当前位置:Gxlcms > mysql > CSAPP六个重要实验lab2

CSAPP六个重要实验lab2

时间:2021-07-01 10:21:17 帮助过:49人阅读

CSAPP lab2 哈哈~ 不愧是“美国进口的六级*”!爽歪歪的“升级打怪” 我把实验材料都上传到下面这个link了,0分下载(良心啊~) http://download.csdn.net/detail/u011368821/7892649 再一个实验指导说明供大家下载: http://download.csdn.net/detail/u011

CSAPP && lab2



哈哈~ 不愧是“美国进口的六级*”!爽歪歪的“升级打怪”


我把实验材料都上传到下面这个link了,0分下载(良心啊~)

http://download.csdn.net/detail/u011368821/7892649


再一个实验指导说明供大家下载:

http://download.csdn.net/detail/u011368821/7892677



对于Phase_1的分析:



  1. 0000000000400ef0 <phase_1>:
  2. 400ef0:
  3. 48 83 ec 08
  4. sub $0x8,%rsp
  5. 400ef4:
  6. be 18 1b 40 00
  7. mov $0x401b18,%esi
  8. 400ef9:
  9. e8 10 04 00 00
  10. callq 40130e <strings_not_equal>
  11. 400efe:
  12. 85 c0
  13. test %eax,%eax
  14. 400f00:
  15. 74 05
  16. je 400f07 <phase_1+0x17>
  17. 400f02:
  18. e8 dc 07 00 00
  19. callq 4016e3 <explode_bomb>
  20. 400f07:
  21. 48 83 c4 08
  22. add $0x8,%rsp
  23. 400f0b:
  24. c3
  25. retq </explode_bomb></phase_1+0x17></strings_not_equal></phase_1>


注意到这句指令.

400ef4:be 18 1b 40 00 mov $0x401b18,%esi


ESI/EDI 分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中

就是要培养的对寄存器很敏感的能力.上面mov $0x401b18,%esi之后立马callq string_not_equal.这是在bomb爆炸之前.我们看看string_not_equal 里面能找到什么线索


  1. 000000000040130e <strings_not_equal>:
  2. 40130e:
  3. 41 54
  4. push %r12
  5. 401310:
  6. 55
  7. push %rbp
  8. 401311:
  9. 53
  10. push %rbx
  11. 401312:
  12. 48 89 fb
  13. mov %rdi,%rbx
  14. 401315:
  15. 48 89 f5
  16. mov %rsi,%rbp
  17. 401318:
  18. e8 d4 ff ff ff
  19. callq 4012f1 <string_length>
  20. 40131d:
  21. 41 89 c4
  22. mov %eax,%r12d
  23. 401320:
  24. 48 89 ef
  25. mov %rbp,%rdi
  26. 401323:
  27. e8 c9 ff ff ff
  28. callq 4012f1 <string_length>
  29. 401328:
  30. ba 01 00 00 00
  31. mov $0x1,%edx
  32. 40132d:
  33. 41 39 c4
  34. cmp %eax,%r12d
  35. 401330:
  36. 75 3e
  37. jne 401370 <strings_not_equal+0x62>
  38. ... ...
  39. 401369:
  40. eb 05
  41. jmp 401370 <strings_not_equal+0x62>
  42. 40136b:
  43. ba 01 00 00 00
  44. mov $0x1,%edx
  45. 401370:
  46. 89 d0
  47. mov %edx,%eax
  48. 401372:
  49. 5b
  50. pop %rbx
  51. 401373:
  52. 5d
  53. pop %rbp
  54. 401374:
  55. 41 5c
  56. pop %r12
  57. 401376:
  58. c3
  59. retq </strings_not_equal+0x62></strings_not_equal+0x62></string_length></string_length></strings_not_equal>


我们可以看到这里有连个string_length. 注意到之前的%rdi 和%rsi 分别被mov到%rbx和%rbp中

%rdi记录的是第一个参数的地址,于是当第一次调用直接第一个参数(指针)指向的字符串,

经过

mov %rsi %rbp

mov %rbp %rdi

这样第二次传入string_length的参数就变成了string_not_equal的第二个参数(指针),

string_length 对这两个不同指针指向的字符串进行计算,返回它们的长度值,如果不一致,返回1,如果一致返回0(关于返回值的情况这里的汇编不足以解释,还要分析所有的string_not_equal反汇编才会知道)

phase_1中

callq 40130e
test %eax,%eax

string_not_equal结束后立即test %eax %eax(text 指令的作用是对寄存器& bit and)

je 如果上一个test指令的结果是0就跳转,否者不跳转

这里如果返回值是0就跳转到了

add $0x8,%rsp
retq

正确返回弹栈了。

上面唧唧歪歪说了这么一对铺垫就一个目的,推理出

400ef4:be 18 1b 40 00 mov $0x401b18,%esi

涉及的这个0x401b18是不寻常的,它指向一个字符串,而我们输入的字符串必须和这个指针指向的字符串完全相同才能不触发bomb否者触发BOMB

那就看看0x401b18这里究竟都藏了什么!

gdb debug去


Science isn't about why, it's about why not?

输入0x401b18 指向的字符串即可过了phase 1 : -)





对于Phase_2的分析:



main函数部分截选

  1. 400e30:
  2. e8 bb 00 00 00
  3. callq 400ef0 <phase_1>
  4. 400e35:
  5. e8 f2 09 00 00
  6. callq 40182c <phase_defused>
  7. 400e3a:
  8. bf 08 1a 40 00
  9. mov $0x401a08,%edi
  10. 400e3f:
  11. e8 ac fc ff ff
  12. callq 400af0 <puts@plt>
  13. 400e44:
  14. e8 fe 08 00 00
  15. callq 401747 <read_line>
  16. 400e49:
  17. 48 89 c7
  18. mov %rax,%rdi
  19. 400e4c:
  20. e8 bb 00 00 00
  21. callq 400f0c <phase_2></phase_2></read_line></puts@plt></phase_defused></phase_1>
我们可以看到搞定了phase_1这里又要进入pahse_2鸟~
这里又有个指令

mov $0x401a08,%edi

0x401a08这个地址装着是一个普通的提示字符串不必在意(测试过了)



看看pahse_2

  1. 0000000000400f0c <phase_2>:
  2. 400f0c:
  3. 55
  4. push %rbp
  5. 400f0d:
  6. 53
  7. push %rbx
  8. 400f0e:
  9. 48 83 ec 28
  10. sub $0x28,%rsp
  11. 400f12:
  12. 48 89 e6
  13. mov %rsp,%rsi
  14. 400f15:
  15. e8 eb 07 00 00
  16. callq 401705 <read_six_numbers>
  17. 400f1a:
  18. 83 3c 24 01
  19. cmpl $0x1,(%rsp)
  20. 400f1e:
  21. 74 25
  22. je 400f45 <phase_2+0x39>
  23. 400f20:
  24. e8 be 07 00 00
  25. callq 4016e3 <explode_bomb>
  26. 400f25:
  27. eb 1e
  28. jmp 400f45 <phase_2+0x39>
  29. 400f27:
  30. 83 c3 01
  31. add $0x1,%ebx
  32. 400f2a:
  33. 89 d8
  34. mov %ebx,%eax
  35. 400f2c:
  36. 0f af 45 fc
  37. imul -0x4(%rbp),%eax
  38. 400f30:
  39. 39 45 00
  40. cmp %eax,0x0(%rbp)
  41. 400f33:
  42. 74 05
  43. je 400f3a <phase_2+0x2e>
  44. 400f35:
  45. e8 a9 07 00 00
  46. callq 4016e3 <explode_bomb>
  47. 400f3a:
  48. 48 83 c5 04
  49. add $0x4,%rbp
  50. 400f3e:
  51. 83 fb 06
  52. cmp $0x6,%ebx
  53. 400f41:
  54. 75 e4
  55. jne 400f27 <phase_2+0x1b>
  56. 400f43:
  57. eb 0c
  58. jmp 400f51 <phase_2+0x45>
  59. 400f45:
  60. 48 8d 6c 24 04
  61. lea 0x4(%rsp),%rbp
  62. 400f4a:
  63. bb 01 00 00 00
  64. mov $0x1,%ebx
  65. 400f4f:
  66. eb d6
  67. jmp 400f27 <phase_2+0x1b>
  68. 400f51:
  69. 48 83 c4 28
  70. add $0x28,%rsp
  71. 400f55:
  72. 5b
  73. pop %rbx
  74. 400f56:
  75. 5d
  76. pop %rbp
  77. 400f57:
  78. c3
  79. retq </phase_2+0x1b></phase_2+0x45></phase_2+0x1b></explode_bomb></phase_2+0x2e></phase_2+0x39></explode_bomb></phase_2+0x39></read_six_numbers></phase_2>


核心语句

imul -0x4(%rbp),%eax
cmp %eax,0x0(%rbp) //如果比较结果是0,就跳转,否则BOMB
je 400f3a
callq 4016e3

既然如此,那就看看前面什么东东影响%eax 和%rbp的取值


callq 401705

cmpl $0x1,(%rsp)

je 400f45
callq 4016e3

这里很明显,读入的6个数字被存放在从rsp指向的地址开始向上的位置。

先比较第一个输入的数(%rsp)和1是否相等,如果是则跳转到400f45标记的位置,否者callq explode_bomb,爆炸

那么可以确定,第一个输入的数字必须是1,接着我们跳转到 400f45 的位置看看会发生什么


  1. 400f45:
  2. 48 8d 6c 24 04
  3. lea 0x4(%rsp),%rbp
  4. 400f4a:
  5. bb 01 00 00 00
  6. mov $0x1,%ebx
  7. 400f4f:
  8. eb d6
  9. jmp 400f27 <phase_2+0x1b></phase_2+0x1b>
这里lea把rsp寄存器指向的指针+4,然后赋值给rbp,并把%edx寄存器初始化为1

最后跳转到400f27的位置


  1. 400f27:
  2. 83 c3 01
  3. add $0x1,%ebx
  4. 400f2a:
  5. 89 d8
  6. mov %ebx,%eax
  7. 400f2c:
  8. 0f af 45 fc
  9. imul -0x4(%rbp),%eax
  10. 400f30:
  11. 39 45 00
  12. cmp %eax,0x0(%rbp)
  13. 400f33:
  14. 74 05
  15. je 400f3a <phase_2+0x2e>
  16. 400f35:
  17. e8 a9 07 00 00
  18. callq 4016e3 <explode_bomb>
  19. 400f3a:
  20. 48 83 c5 04
  21. add $0x4,%rbp
  22. 400f3e:
  23. 83 fb 06
  24. cmp $0x6,%ebx
  25. 400f41:
  26. 75 e4
  27. jne 400f27 <phase_2+0x1b></phase_2+0x1b></explode_bomb></phase_2+0x2e>
此时add 把ebx 增 1,然后赋值给%eax,即数值2.

把-0x4(%rbp)即第一个输入的数字,imul 乘以%eax的值,然后赋值给%eax,即 %eax = 1*2

cmp把此时的%eax 和当前输入0x0(%rbp),此时为第二个输入数字,比较。如果相同就跳转到400f3a的位置,否者callq explode_bomb爆炸. 由此我们可以知道,第二个输入的数字必须是2.


如果第二个数字输入的是2,接着add 把%rbp +4, 接着cmp 比较%ebx(此时为2)和0x6比较,不相等就跳转到400f27,

于是我们又回到了400f27的位置,有点汇编经验的人一看就可以发现,这里其实是一个循环. %ebx每次+1, 循环6次。

  1. 400f2c:
  2. 0f af 45 fc
  3. imul -0x4(%rbp),%eax
  4. 400f30:
  5. 39 45 00
  6. cmp %eax,0x0(%rbp)
每次都把%eax和前一个输入数字相乘,赋值给%eax,并和当前数字0x0(%rbp)比较。


这样一步步按照汇编语句构造的循环,执行下去,可以发现要想不bomb,输入应该是

1 2 6 24 120 720



OK~ 搞定,phase_2。






对于Phase_3的分析:

当我们搞定phase_2之后,phase_3来了~

  1. 400e4c:
  2. e8 bb 00 00 00
  3. callq 400f0c <phase_2>
  4. 400e51:
  5. e8 d6 09 00 00
  6. callq 40182c <phase_defused>
  7. 400e56:
  8. bf 67 19 40 00
  9. mov $0x401967,%edi
  10. 400e5b:
  11. e8 90 fc ff ff
  12. callq 400af0 <puts@plt>
  13. 400e60:
  14. e8 e2 08 00 00
  15. callq 401747 <read_line>
  16. 400e65:
  17. 48 89 c7
  18. mov %rax,%rdi
  19. 400e68:
  20. e8 eb 00 00 00
  21. callq 400f58 <phase_3>
  22. 400e6d:
  23. e8 ba 09 00 00
  24. callq 40182c <phase_defused></phase_defused></phase_3></read_line></puts@plt></phase_defused></phase_2>



phase_3:

  1. 0000000000400f58 <phase_3>:
  2. 400f58:
  3. 48 83 ec 18
  4. sub $0x18,%rsp
  5. 400f5c:
  6. 4c 8d 44 24 08
  7. lea 0x8(%rsp),%r8 //把%rsp指向的地址+0x8 赋值给%rcx ,以下的lea操作同理
  8. 400f61:
  9. 48 8d 4c 24 07
  10. lea 0x7(%rsp),%rcx
  11. 400f66:
  12. 48 8d 54 24 0c
  13. lea 0xc(%rsp),%rdx
  14. 400f6b:
  15. be 6e 1b 40 00
  16. mov $0x401b6e,%esi //把0x401b6赋值给%esi ,注意esi是字符串相关寄存器,我们看看这个地址里面是什么
  17. 400f70:
  18. b8 00 00 00 00
  19. mov $0x0,%eax
  20. 400f75:
  21. e8 86 fc ff ff
  22. callq 400c00 <__isoc99_sscanf@plt>
  23. 400f7a:
  24. 83 f8 02
  25. cmp $0x2,%eax
  26. 400f7d:
  27. 7f 05
  28. jg 400f84 <phase_3+0x2c>
  29. 400f7f:
  30. e8 5f 07 00 00
  31. callq 4016e3 <explode_bomb>
  32. 400f84:
  33. 83 7c 24 0c 07
  34. cmpl $0x7,0xc(%rsp) //比较0xc(%rsp)处的值和7比较,如果大于7,ja跳转,接着bomb,于是我们知道0xc(%rsp)处的值要在(0~7)
  35. 400f89:
  36. 0f 87 fc 00 00 00
  37. ja 40108b <phase_3+0x133>
  38. 400f8f:
  39. 8b 44 24 0c
  40. mov 0xc(%rsp),%eax
  41. 400f93:
  42. ff 24 c5 80 1b 40 00
  43. jmpq *0x401b80(,%rax,8)
  44. 400f9a:
  45. b8 6a 00 00 00
  46. mov $0x6a,%eax //把0x6a赋值给%eax,这里很重要,每一个witch分支的这里都不一样,而且第二个输入参数和这个有关系
  47. 400f9f:
  48. 81 7c 24 08 40 02 00
  49. cmpl $0x240,0x8(%rsp) //把0x8(%rsp)的值和0x240比较,如果不相等,bomb,相等就正常跳转到 401095
  50. 400fa6:
  51. 00
  52. 400fa7:
  53. 0f 84 e8 00 00 00
  54. je 401095 <phase_3+0x13d>
  55. 400fad:
  56. e8 31 07 00 00
  57. callq 4016e3 <explode_bomb>
  58. 400fb2:
  59. b8 6a 00 00 00
  60. mov $0x6a,%eax
  61. 400fb7:
  62. e9 d9 00 00 00
  63. jmpq 401095 <phase_3+0x13d>
  64. 400fbc:
  65. b8 66 00 00 00
  66. mov $0x66,%eax
  67. 400fc1:
  68. 81 7c 24 08 bc 03 00
  69. cmpl $0x3bc,0x8(%rsp)
  70. 400fc8:
  71. 00
  72. 400fc9:
  73. 0f 84 c6 00 00 00
  74. je 401095 <phase_3+0x13d>
  75. 400fcf:
  76. e8 0f 07 00 00
  77. callq 4016e3 <explode_bomb>
  78. 400fd4:
  79. b8 66 00 00 00
  80. mov $0x66,%eax
  81. 400fd9:
  82. e9 b7 00 00 00
  83. jmpq 401095 <phase_3+0x13d>
  84. 400fde:
  85. b8 6a 00 00 00
  86. mov $0x6a,%eax
  87. 400fe3:
  88. 81 7c 24 08 2a 02 00
  89. cmpl $0x22a,0x8(%rsp)
  90. 400fea:
  91. 00
  92. 400feb:
  93. 0f 84 a4 00 00 00
  94. je 401095 <phase_3+0x13d>
  95. 400ff1:
  96. e8 ed 06 00 00
  97. callq 4016e3 <explode_bomb>
  98. 400ff6:
  99. b8 6a 00 00 00
  100. mov $0x6a,%eax
  101. 400ffb:
  102. e9 95 00 00 00
  103. jmpq 401095 <phase_3+0x13d>
  104. 401000:
  105. b8 76 00 00 00
  106. mov $0x76,%eax
  107. 401005:
  108. 81 7c 24 08 c9 00 00
  109. cmpl $0xc9,0x8(%rsp)
  110. 40100c:
  111. 00
  112. 40100d:
  113. 0f 84 82 00 00 00
  114. je 401095 <phase_3+0x13d>
  115. 401013:
  116. e8 cb 06 00 00
  117. callq 4016e3 <explode_bomb>
  118. 401018:
  119. b8 76 00 00 00
  120. mov $0x76,%eax
  121. 40101d:
  122. eb 76
  123. jmp 401095 <phase_3+0x13d>
  124. 40101f:
  125. b8 62 00 00 00
  126. mov $0x62,%eax
  127. 401024:
  128. 81 7c 24 08 07 01 00
  129. cmpl $0x107,0x8(%rsp)
  130. 40102b:
  131. 00
  132. 40102c:
  133. 74 67
  134. je 401095 <phase_3+0x13d>
  135. 40102e:
  136. e8 b0 06 00 00
  137. callq 4016e3 <explode_bomb>
  138. 401033:
  139. b8 62 00 00 00
  140. mov $0x62,%eax
  141. 401038:
  142. eb 5b
  143. jmp 401095 <phase_3+0x13d>
  144. 40103a:
  145. b8 69 00 00 00
  146. mov $0x69,%eax
  147. 40103f:
  148. 81 7c 24 08 3b 03 00
  149. cmpl $0x33b,0x8(%rsp)
  150. 401046:
  151. 00
  152. 401047:
  153. 74 4c
  154. je 401095 <phase_3+0x13d>
  155. 401049:
  156. e8 95 06 00 00
  157. callq 4016e3 <explode_bomb>
  158. 40104e:
  159. b8 69 00 00 00
  160. mov $0x69,%eax
  161. 401053:
  162. eb 40
  163. jmp 401095 <phase_3+0x13d>
  164. 401055:
  165. b8 71 00 00 00
  166. mov $0x71,%eax
  167. 40105a:
  168. 81 7c 24 08 c6 00 00
  169. cmpl $0xc6,0x8(%rsp)
  170. 401061:
  171. 00
  172. 401062:
  173. 74 31
  174. je 401095 <phase_3+0x13d>
  175. 401064:
  176. e8 7a 06 00 00
  177. callq 4016e3 <explode_bomb>
  178. 401069:
  179. b8 71 00 00 00
  180. mov $0x71,%eax
  181. 40106e:
  182. eb 25
  183. jmp 401095 <phase_3+0x13d>
  184. 401070:
  185. b8 77 00 00 00
  186. mov $0x77,%eax
  187. 401075:
  188. 81 7c 24 08 74 01 00
  189. cmpl $0x174,0x8(%rsp)
  190. 40107c:
  191. 00
  192. 40107d:
  193. 74 16
  194. je 401095 <phase_3+0x13d>
  195. 40107f:
  196. e8 5f 06 00 00
  197. callq 4016e3 <explode_bomb>
  198. 401084:
  199. b8 77 00 00 00
  200. mov $0x77,%eax
  201. 401089:
  202. eb 0a
  203. jmp 401095 <phase_3+0x13d>
  204. 40108b:
  205. e8 53 06 00 00
  206. callq 4016e3 <explode_bomb>
  207. 401090:
  208. b8 68 00 00 00
  209. mov $0x68,%eax
  210. 401095:
  211. 3a 44 24 07
  212. cmp 0x7(%rsp),%al //把0x7(%rsp)和 %al(%eax低字节)比较,相等就跳转,否者,bomb
  213. 401099:
  214. 74 05
  215. je 4010a0 <phase_3+0x148>
  216. 40109b:
  217. e8 43 06 00 00
  218. callq 4016e3 <explode_bomb>
  219. 4010a0:
  220. 48 83 c4 18
  221. add $0x18,%rsp
  222. 4010a4:
  223. c3
  224. retq
  225. </explode_bomb></phase_3+0x148></explode_bomb></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x13d></explode_bomb></phase_3+0x13d></phase_3+0x133></explode_bomb></phase_3+0x2c></phase_3>


注意到开头这里

mov $0x401b6e,%esi

把0x401b6赋值给%esi ,注意esi是字符串相关寄存器,我们看看这个地址里面是什么


我们发现是一个格式化输入说明字符串

于是我们就知道我们应该输入什么类型的数据了

400f75: callq 400c00 <__isoc99_sscanf@plt>
400f7a: cmp $0x2,%eax
400f7d: jg 400f84
400f7f: callq 4016e3
400f84: cmpl $0x7,0xc(%rsp)

可以发现,sscanf的返回值放在%eax里,如果输入的数据大于2个(即最少是3个),就跳转到400f84,否则explode_bomb

根据前面的格式化字符串我们可以注意到

输入三个数据即正常跳转


这里又有个跳转语句

  1. 400f93:
  2. ff 24 c5 80 1b 40 00
  3. jmpq *0x401b80(,%rax,8)
  4. 400f9a:
  5. b8 6a 00 00 00
  6. mov $0x6a,%eax
我们看看 *0x401b80处是什么东东


是一个数,0x400f9a,这个是指令mov $0x6a,%eax 的代码段标记地址

如果%rax是0,就直接跳转到0x400f9a 否则0x400f9a + %rax * 8

这里是典型的witch 语句的汇编形式...如果不明白就去看CSAPP第三章


上面给出的phase_3汇编部分注释我已经写的很清楚了~

  1. 400f5c:
  2. 4c 8d 44 24 08
  3. lea 0x8(%rsp),%r8 //把%rsp指向的地址+0x8 赋值给%rcx ,以下的lea操作同理
  4. 400f61:
  5. 48 8d 4c 24 07
  6. lea 0x7(%rsp),%rcx
  7. 400f66:
  8. 48 8d 54 24 0c
  9. lea 0xc(%rsp),%rdx
这里可以推知phase_3一开始就保存了0x8(%rsp),0x7(%rsp),0xc(%rsp)三处的值,这三处肯定要被接下来的程序重写利用.

而分析偏移量0x8 0x7 0xc,以及格式化字符串参数入栈顺序可知,0xc(%rsp)储存第一个参数,0x7(%rsp)储存第二个参数,0x8(%rsp)储存第三个参数.

提示: printf("%d %d",a,b); 参数是b先入栈,然后是a

综合以上分析,输入

0 j 576

即可过关

这里我偷一下懒第一个选择了0

实际上第一个数据可以是0~7内的任意数字,这也会导致跳转至不同的分支,而影响第二个第三个参数的输入情况。

以0 作为第一个输入参数的例子,

  1. 400f9a:
  2. b8 6a 00 00 00
  3. mov $0x6a,%eax

  1. 401095:
  2. 3a 44 24 07
  3. cmp 0x7(%rsp),%al
以上两个指令将被执行,我们可以知道0x7(%rsp)第二个输入的参数应当为0x6a对应的ascii码字符,于是这里应当输入 j

第三个参数的确定是在

  1. 400f9f:
  2. 81 7c 24 08 40 02 00
  3. cmpl $0x240,0x8(%rsp) //把0x8(%rsp)的值和0x240比较,如果不相等,bomb,相等就正常跳转到 401095
  4. 400fa6:
  5. 00
  6. 400fa7:
  7. 0f 84 e8 00 00 00
  8. je 401095 <phase_3+0x13d></phase_3+0x13d>
于是第三个参数必须为0x240,否则bomb,这里是%d的读入,于是转化为相应的十进制数为576.



OK, Phase_3 搞定 halfway there!


对于Phase_4的分析:


注意到phase_4会调用到func4

  1. 00000000004010a5 <func4>:
  2. 4010a5:
  3. 53
  4. push %rbx
  5. 4010a6:
  6. 89 fb
  7. mov %edi,%ebx
  8. 4010a8:
  9. b8 01 00 00 00
  10. mov $0x1,%eax
  11. 4010ad:
  12. 83 ff 01
  13. cmp $0x1,%edi
  14. 4010b0:
  15. 7e 0b
  16. jle 4010bd <func4+0x18>
  17. 4010b2:
  18. 8d 7f ff
  19. lea -0x1(%rdi),%edi
  20. 4010b5:
  21. e8 eb ff ff ff
  22. callq 4010a5 <func4>
  23. 4010ba:
  24. 0f af c3
  25. imul %ebx,%eax
  26. 4010bd:
  27. 5b
  28. pop %rbx
  29. 4010be:
  30. c3
  31. retq
  32. 00000000004010bf <phase_4>:
  33. 4010bf:
  34. 48 83 ec 18
  35. sub $0x18,%rsp
  36. 4010c3:
  37. 48 8d 54 24 0c
  38. lea 0xc(%rsp),%rdx
  39. 4010c8:
  40. be 74 1b 40 00
  41. mov $0x401b74,%esi
  42. 4010cd:
  43. b8 00 00 00 00
  44. mov $0x0,%eax
  45. 4010d2:
  46. e8 29 fb ff ff
  47. callq 400c00 <__isoc99_sscanf@plt>
  48. 4010d7:
  49. 83 f8 01
  50. cmp $0x1,%eax
  51. 4010da:
  52. 75 07
  53. jne 4010e3 <phase_4+0x24>
  54. 4010dc:
  55. 83 7c 24 0c 00
  56. cmpl $0x0,0xc(%rsp)
  57. 4010e1:
  58. 7f 05
  59. jg 4010e8 <phase_4+0x29>
  60. 4010e3:
  61. e8 fb 05 00 00
  62. callq 4016e3 <explode_bomb>
  63. 4010e8:
  64. 8b 7c 24 0c
  65. mov 0xc(%rsp),%edi
  66. 4010ec:
  67. e8 b4 ff ff ff
  68. callq 4010a5 <func4>
  69. 4010f1:
  70. 3d 00 5f 37 00
  71. cmp $0x375f00,%eax
  72. 4010f6:
  73. 74 05
  74. je 4010fd <phase_4+0x3e>
  75. 4010f8:
  76. e8 e6 05 00 00
  77. callq 4016e3 <explode_bomb>
  78. 4010fd:
  79. 48 83 c4 18
  80. add $0x18,%rsp
  81. 401101:
  82. c3
  83. retq </explode_bomb></phase_4+0x3e></func4></explode_bomb></phase_4+0x29></phase_4+0x24></phase_4></func4></func4+0x18></func4>

进过前面三个*的“轰炸”,这里我不想在过细致的分析,就是一步步跟着汇编看就是了

主题就是phase_4要求根据格式化字符串“%d”输入一个数字,这个数字传入func做递归乘法,相当于传入参数的阶乘.

最后

  1. 4010f1:
  2. 3d 00 5f 37 00
  3. cmp $0x375f00,%eax
返回值和0x375f00比较,如果不相等就bomb,于是我们必须找到阶乘等于0x375f00的数字.

的方法嘛.写个阶乘的C 函数去测试,什么输入参数的阶乘是0x375f00


  1. #include <stdio.h>
  2. int main()
  3. {
  4. int ans = 1;
  5. int tmp = 1;
  6. for(tmp = 1;ans != 0x375f00;tmp++)
  7. {
  8. ans *= tmp;
  9. }
  10. printf("%d \n",tmp-1);
  11. return 0;
  12. }</stdio.h>

呵呵,原来是10.






对于Phase_5的分析:



  1. 0000000000401102 <phase_5>:
  2. 401102:
  3. 53
  4. push %rbx
  5. 401103:
  6. 48 89 fb
  7. mov %rdi,%rbx
  8. 401106:
  9. e8 e6 01 00 00
  10. callq 4012f1 <string_length>
  11. 40110b:
  12. 83 f8 06
  13. cmp $0x6,%eax //输入字符串的长度必须是6,否则bomb
  14. 40110e:
  15. 74 05
  16. je 401115 <phase_5+0x13>
  17. 401110:
  18. e8 ce 05 00 00
  19. callq 4016e3 <explode_bomb>
  20. 401115:
  21. b8 00 00 00 00
  22. mov $0x0,%eax // 把%eax %edx 寄存器赋值为0
  23. 40111a:
  24. ba 00 00 00 00
  25. mov $0x0,%edx
  26. 40111f:
  27. 0f b6 0c 03
  28. movzbl (%rbx,%rax,1),%ecx //%rbx + %rax*1 赋值给%ecx
  29. 401123:
  30. 83 e1 0f
  31. and $0xf,%ecx //取%ecx低4位赋值给%ecx
  32. 401126:
  33. 03 14 8d c0 1b 40 00
  34. add 0x401bc0(,%rcx,4),%edx
  35. 40112d:
  36. 48 83 c0 01
  37. add $0x1,%rax
  38. 401131:
  39. 48 83 f8 06
  40. cmp $0x6,%rax
  41. 401135:
  42. 75 e8
  43. jne 40111f <phase_5+0x1d>
  44. 401137:
  45. 83 fa 3e
  46. cmp $0x3e,%edx
  47. 40113a:
  48. 74 05
  49. je 401141 <phase_5+0x3f>
  50. 40113c:
  51. e8 a2 05 00 00
  52. callq 4016e3 <explode_bomb>
  53. 401141:
  54. 5b
  55. pop %rbx
  56. 401142:
  57. c3
  58. retq </explode_bomb></phase_5+0x3f></phase_5+0x1d></explode_bomb></phase_5+0x13></string_length></phase_5>


值得注意的是

  1. 401126:
  2. 03 14 8d c0 1b 40 00
  3. add 0x401bc0(,%rcx,4),%edx
这里又有个很特殊的地址0x401bc0

我尝试打印这里的数据,怀疑这里很可能是个数组


对于phase_5,概括性的说,就是输入6个ascii字符,然后这6个字符的低4位对应这个数组的index,然后对应数字累加要等于0x3e,即62

这里我的想法是62 = 2+2+10+16+16+16

对应的偏移量是001555

我们查看ascii码表可以发现,恰巧数字字符00155符合要求,于是输入00155







对于Phase_6的分析:


最后一关了!

  1. 0000000000401143 <fun6>:
  2. 401143:
  3. 48 89 f8
  4. mov %rdi,%rax
  5. 401146:
  6. 4c 8b 47 08
  7. mov 0x8(%rdi),%r8
  8. 40114a:
  9. 48 c7 47 08 00 00 00
  10. movq $0x0,0x8(%rdi)
  11. 401151:
  12. 00
  13. 401152:
  14. 4d 85 c0
  15. test %r8,%r8
  16. 401155:
  17. 75 48
  18. jne 40119f <fun6+0x5c>
  19. 401157:
  20. f3 c3
  21. repz retq
  22. 401159:
  23. 48 89 d1
  24. mov %rdx,%rcx
  25. 40115c:
  26. 48 8b 51 08
  27. mov 0x8(%rcx),%rdx
  28. 401160:
  29. 48 85 d2
  30. test %rdx,%rdx
  31. 401163:
  32. 74 09
  33. je 40116e <fun6+0x2b>
  34. 401165:
  35. 39 32
  36. cmp %esi,(%rdx)
  37. 401167:
  38. 7f f0
  39. jg 401159 <fun6+0x16>
  40. 401169:
  41. 48 89 d6
  42. mov %rdx,%rsi
  43. 40116c:
  44. eb 03
  45. jmp 401171 <fun6+0x2e>
  46. 40116e:
  47. 48 89 d6
  48. mov %rdx,%rsi
  49. 401171:
  50. 48 39 ce
  51. cmp %rcx,%rsi
  52. 401174:
  53. 74 06
  54. je 40117c <fun6+0x39>
  55. 401176:
  56. 4c 89 41 08
  57. mov %r8,0x8(%rcx)
  58. 40117a:
  59. eb 13
  60. jmp 40118f <fun6+0x4c>
  61. 40117c:
  62. 4c 89 c0
  63. mov %r8,%rax
  64. 40117f:
  65. eb 0e
  66. jmp 40118f <fun6+0x4c>
  67. 401181:
  68. 48 89 c2
  69. mov %rax,%rdx
  70. 401184:
  71. 4c 89 c0
  72. mov %r8,%rax
  73. 401187:
  74. eb 06
  75. jmp 40118f <fun6+0x4c>
  76. 401189:
  77. 48 89 c2
  78. mov %rax,%rdx
  79. 40118c:
  80. 4c 89 c0
  81. mov %r8,%rax
  82. 40118f:
  83. 49 8b 48 08
  84. mov 0x8(%r8),%rcx
  85. 401193:
  86. 49 89 50 08
  87. mov %rdx,0x8(%r8)
  88. 401197:
  89. 48 85 c9
  90. test %rcx,%rcx
  91. 40119a:
  92. 74 14
  93. je 4011b0 <fun6+0x6d>
  94. 40119c:
  95. 49 89 c8
  96. mov %rcx,%r8
  97. 40119f:
  98. 48 85 c0
  99. test %rax,%rax
  100. 4011a2:
  101. 74 dd
  102. je 401181 <fun6+0x3e>
  103. 4011a4:
  104. 41 8b 30
  105. mov (%r8),%esi
  106. 4011a7:
  107. 39 30
  108. cmp %esi,(%rax)
  109. 4011a9:
  110. 7e de
  111. jle 401189 <fun6+0x46>
  112. 4011ab:
  113. 48 89 c1
  114. mov %rax,%rcx
  115. 4011ae:
  116. eb ac
  117. jmp 40115c <fun6+0x19>
  118. 4011b0:
  119. f3 c3
  120. repz retq
  121. 00000000004011b2 <phase_6>:
  122. 4011b2:
  123. 48 83 ec 08
  124. sub $0x8,%rsp
  125. 4011b6:
  126. ba 0a 00 00 00
  127. mov $0xa,%edx
  128. 4011bb:
  129. be 00 00 00 00
  130. mov $0x0,%esi
  131. 4011c0:
  132. e8 1b fa ff ff
  133. callq 400be0 <strtol@plt>
  134. 4011c5:
  135. 89 05 55 21 20 00
  136. mov %eax,0x202155(%rip) # 603320 <node0>
  137. 4011cb:
  138. bf 20 33 60 00
  139. mov $0x603320,%edi
  140. 4011d0:
  141. e8 6e ff ff ff
  142. callq 401143 <fun6>
  143. 4011d5:
  144. 48 8b 40 08
  145. mov 0x8(%rax),%rax
  146. 4011d9:
  147. 8b 0d 41 21 20 00
  148. mov 0x202141(%rip),%ecx # 603320 <node0>
  149. 4011df:
  150. 39 08
  151. cmp %ecx,(%rax)
  152. 4011e1:
  153. 74 05
  154. je 4011e8 <phase_6+0x36>
  155. 4011e3:
  156. e8 fb 04 00 00
  157. callq 4016e3 <explode_bomb>
  158. 4011e8:
  159. 48 83 c4 08
  160. add $0x8,%rsp
  161. 4011ec:
  162. c3
  163. retq
  164. </explode_bomb></phase_6+0x36></node0></fun6></node0></strtol@plt></phase_6></fun6+0x19></fun6+0x46></fun6+0x3e></fun6+0x6d></fun6+0x4c></fun6+0x4c></fun6+0x4c></fun6+0x39></fun6+0x2e></fun6+0x16></fun6+0x2b></fun6+0x5c></fun6>

这步不要陷入到func6了,逐步的去gdb stepi nexti 调试就是了. 具体的调试方法不讲了

值得一提的就是这里

  1. 4011c5:
  2. 89 05 55 21 20 00
  3. mov %eax,0x202155(%rip) # 603320 <node0>
  4. 4011d9:
  5. 8b 0d 41 21 20 00
  6. mov 0x202141(%rip),%ecx # 603320 <node0></node0></node0>
这里0x202155(%rip) 0x202141(%rip)都是指向同一个地址,这个地址储存着输入数据

  1. cmp %ecx,(%rax)
最后这里比较的时候,直接gdb查看%rax指向的地址存的什么东东,

打印出来


826!于是我们就应该输入826





其实应该还有个彩蛋——secrete phase

我目前~没心思看了,过两天继续更新

*****************************************************************************************************************************

参考资料——向所有前辈致敬, sharing,step together! open source!


逆向工程——二进制*(CSAPP Project)

http://www.cnblogs.com/remlostime/archive/2011/05/21/2052708.html


bomb lab (《深入理解计算机系统》lab2)Stone

http://blog.csdn.net/u013648407/article/details/24845129


CSAPP:二进制*实验 lycos的六度空间

http://blog.csdn.net/caoxu1987728/article/details/6056947


最后感谢

  • UNIVERSITY OF WASHINGTON


呵呵,国内的某些大学学着点别人的风度.

***************************************************************************************************************************




人气教程排行