前言:一个不会汇编的菜鸟强行做一个bomb_lab作业。
拖了两周才做好的bomb_lab,期间因为心情郁闷拖了一周?
现在来写一下“拆后感”。(这个博客早就想写,因为期中考试和懒又拖了两周,有点可惜一些细节记得不是特别清楚了)话不多说上代码(之前一大段编译准备栈什么的删了)
开始前的一些指令:
cd 路径 ->进入文件存放的目录下
./bomb_XXX 运行那个炸弹程序
objdump -d bomb_xxx > bomb_xxx.s 把反汇编代码放到文本框里好看一点。
gdb bomb_104 进入该程序的gdb调试
第一关热身,x/s 0x804a0a4
出来一句话:And they have no disregard for human life.
输入要和这句话相等,否则爆炸,这就是第一句。
08048b33 <phase_1>:
8048b33: 83 ec 14 sub $0x14,%esp
8048b36: 68 a4 a0 04 08 push $0x804a0a4 //突然一个奇怪的地址入栈,很可疑啊
8048b3b: ff 74 24 1c pushl 0x1c(%esp)
8048b3f: e8 3b 05 00 00 call 804907f <strings_not_equal> 函数名说明了问题
8048b44: 83 c4 10 add $0x10,%esp
8048b47: 85 c0 test %eax,%eax
8048b49: 74 05 je 8048b50 <phase_1+0x1d>
8048b4b: e8 26 06 00 00 call 8049176 <explode_bomb> //不相等就爆炸
8048b50: 83 c4 0c add $0xc,%esp
8048b53: c3 ret
第二关代码不长,也只有一个循环,我是直接读代码的,由ebx++访问了所有参数,分析得出是斐波那契数列,
输入1 2 4 7 11 15过了。
08048b54 <phase_2>:
8048b54: 53 push %ebx
8048b55: 83 ec 30 sub $0x30,%esp
8048b58: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048b5e: 89 44 24 24 mov %eax,0x24(%esp)
8048b62: 31 c0 xor %eax,%eax
8048b64: 8d 44 24 0c lea 0xc(%esp),%eax
8048b68: 50 push %eax
8048b69: ff 74 24 3c pushl 0x3c(%esp)
8048b6d: e8 29 06 00 00 call 804919b <read_six_numbers> 这边才开始输入,前面的代码不用管了(论函数名规范的重要性)
8048b72: 83 c4 10 add $0x10,%esp
8048b75: 83 7c 24 04 00 cmpl $0x0,0x4(%esp) 不懂,好像意思是第一个参数不为0,但试了一下0也是可以的,懵逼...
8048b7a: 79 05 jns 8048b81 <phase_2+0x2d>
8048b7c: e8 f5 05 00 00 call 8049176 <explode_bomb>
8048b81: bb 01 00 00 00 mov $0x1,%ebx
8048b86: 89 d8 mov %ebx,%eax
8048b88: 03 04 9c add (%esp,%ebx,4),%eax eax加上第一个参数的值
8048b8b: 39 44 9c 04 cmp %eax,0x4(%esp,%ebx,4) eax与第二个参数比较
8048b8f: 74 05 je 8048b96 <phase_2+0x42> 不等会爆炸
8048b91: e8 e0 05 00 00 call 8049176 <explode_bomb>
8048b96: 83 c3 01 add $0x1,%ebx ebx++;
8048b99: 83 fb 06 cmp $0x6,%ebx ebx<6的时候回去,原来是个循环
8048b9c: 75 e8 jne 8048b86 <phase_2+0x32>
8048b9e: 8b 44 24 1c mov 0x1c(%esp),%eax
8048ba2: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048ba9: 74 05 je 8048bb0 <phase_2+0x5c>
8048bab: e8 e0 fb ff ff call 8048790 <__stack_chk_fail@plt>
8048bb0: 83 c4 28 add $0x28,%esp
8048bb3: 5b pop %ebx
8048bb4: c3 ret
第三关有个switch因此代码很长,偷了个懒,找到一条可以不爆炸的路径就出去了(有多组解)。
一个答案是:3 l 240 路径,计算地址跳来跳去的有点累,注释也加了好几行。
08048bb5 <phase_3>:
8048bb5: 83 ec 28 sub $0x28,%esp
8048bb8: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048bbe: 89 44 24 18 mov %eax,0x18(%esp)
8048bc2: 31 c0 xor %eax,%eax
8048bc4: 8d 44 24 14 lea 0x14(%esp),%eax
8048bc8: 50 push %eax
8048bc9: 8d 44 24 13 lea 0x13(%esp),%eax
8048bcd: 50 push %eax
8048bce: 8d 44 24 18 lea 0x18(%esp),%eax
8048bd2: 50 push %eax
8048bd3: 68 f6 a0 04 08 push $0x804a0f6 这个地址肯定有些门道, x/s 它得到 %d %c %d,这是输入的格式
8048bd8: ff 74 24 3c pushl 0x3c(%esp)
8048bdc: e8 3f fc ff ff call 8048820 <__isoc99_sscanf@plt> 这边调用输入函数
8048be1: 83 c4 20 add $0x20,%esp
8048be4: 83 f8 02 cmp $0x2,%eax 不是很懂sscanf的返回值,这边大概是输入了太多的东西就爆炸
8048be7: 7f 05 jg 8048bee <phase_3+0x39>
8048be9: e8 88 05 00 00 call 8049176 <explode_bomb>
8048bee: 83 7c 24 04 07 cmpl $0x7,0x4(%esp) 第一个参数来比较啦,比7大就爆炸
8048bf3: 0f 87 fc 00 00 00 ja 8048cf5 <phase_3+0x140>//bomb!
8048bf9: 8b 44 24 04 mov 0x4(%esp),%eax
8048bfd: ff 24 85 00 a1 04 08 jmp *0x804a100(,%eax,4)//switch!!跳转表来了,根据eax(第一个输入的数)判断调到哪一行,看了一下哪个简单点,当时输入了个3继续往下走
8048c04: b8 6a 00 00 00 mov $0x6a,%eax
8048c09: 81 7c 24 08 4e 03 00 cmpl $0x34e,0x8(%esp)
8048c10: 00
8048c11: 0f 84 e8 00 00 00 je 8048cff <phase_3+0x14a>
8048c17: e8 5a 05 00 00 call 8049176 <explode_bomb>
8048c1c: b8 6a 00 00 00 mov $0x6a,%eax
8048c21: e9 d9 00 00 00 jmp 8048cff <phase_3+0x14a>
8048c26: b8 67 00 00 00 mov $0x67,%eax//from switch eax=1
8048c2b: 81 7c 24 08 c9 01 00 cmpl $0x1c9,0x8(%esp)
8048c32: 00
8048c33: 0f 84 c6 00 00 00 je 8048cff <phase_3+0x14a>
8048c39: e8 38 05 00 00 call 8049176 <explode_bomb>
8048c3e: b8 67 00 00 00 mov $0x67,%eax
8048c43: e9 b7 00 00 00 jmp 8048cff <phase_3+0x14a>
8048c48: b8 65 00 00 00 mov $0x65,%eax
8048c4d: 81 7c 24 08 62 02 00 cmpl $0x262,0x8(%esp)
8048c54: 00
8048c55: 0f 84 a4 00 00 00 je 8048cff <phase_3+0x14a>
8048c5b: e8 16 05 00 00 call 8049176 <explode_bomb>
8048c60: b8 65 00 00 00 mov $0x65,%eax
8048c65: e9 95 00 00 00 jmp 8048cff <phase_3+0x14a>
8048c6a: b8 6c 00 00 00 mov $0x6c,%eax// from eax=3 输入3到这儿了
8048c6f: 81 7c 24 08 f0 00 00 cmpl $0xf0,0x8(%esp)//240,get 原来3 对应的第二个数要等于240
8048c76: 00
8048c77: 0f 84 82 00 00 00 je 8048cff <phase_3+0x14a>
8048c7d: e8 f4 04 00 00 call 8049176 <explode_bomb>
8048c82: b8 6c 00 00 00 mov $0x6c,%eax
8048c87: eb 76 jmp 8048cff <phase_3+0x14a>
8048c89: b8 78 00 00 00 mov $0x78,%eax
8048c8e: 81 7c 24 08 8e 00 00 cmpl $0x8e,0x8(%esp)
8048c95: 00
8048c96: 74 67 je 8048cff <phase_3+0x14a>
8048c98: e8 d9 04 00 00 call 8049176 <explode_bomb>
8048c9d: b8 78 00 00 00 mov $0x78,%eax
8048ca2: eb 5b jmp 8048cff <phase_3+0x14a>
8048ca4: b8 61 00 00 00 mov $0x61,%eax
8048ca9: 81 7c 24 08 b1 02 00 cmpl $0x2b1,0x8(%esp)
8048cb0: 00
8048cb1: 74 4c je 8048cff <phase_3+0x14a>
8048cb3: e8 be 04 00 00 call 8049176 <explode_bomb>
8048cb8: b8 61 00 00 00 mov $0x61,%eax
8048cbd: eb 40 jmp 8048cff <phase_3+0x14a>
8048cbf: b8 79 00 00 00 mov $0x79,%eax
8048cc4: 81 7c 24 08 3f 02 00 cmpl $0x23f,0x8(%esp)
8048ccb: 00
8048ccc: 74 31 je 8048cff <phase_3+0x14a>
8048cce: e8 a3 04 00 00 call 8049176 <explode_bomb>
8048cd3: b8 79 00 00 00 mov $0x79,%eax
8048cd8: eb 25 jmp 8048cff <phase_3+0x14a>
8048cda: b8 6f 00 00 00 mov $0x6f,%eax
8048cdf: 81 7c 24 08 4c 02 00 cmpl $0x24c,0x8(%esp)
8048ce6: 00
8048ce7: 74 16 je 8048cff <phase_3+0x14a>
8048ce9: e8 88 04 00 00 call 8049176 <explode_bomb>
8048cee: b8 6f 00 00 00 mov $0x6f,%eax
8048cf3: eb 0a jmp 8048cff <phase_3+0x14a>
8048cf5: e8 7c 04 00 00 call 8049176 <explode_bomb>
8048cfa: b8 61 00 00 00 mov $0x61,%eax
8048cff: 3a 44 24 03 cmp 0x3(%esp),%al// %al-->l,get eax = 3 到了这儿,可在此设断点:break *0x8048cff,info registers 查看当前寄存器状态,al中存着l,随便猜一下,%c是l
8048d03: 74 05 je 8048d0a <phase_3+0x155>
8048d05: e8 6c 04 00 00 call 8049176 <explode_bomb>
8048d0a: 8b 44 24 0c mov 0xc(%esp),%eax
8048d0e: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048d15: 74 05 je 8048d1c <phase_3+0x167>
8048d17: e8 74 fa ff ff call 8048790 <__stack_chk_fail@plt>
8048d1c: 83 c4 1c add $0x1c,%esp
8048d1f: c3 ret
第四关代码不长,可是它调用一个递归函数,功力尚浅,看晕了。。。很无耻地看到数据范围不是很大,忍不住穷举得出了结果
6 6。这个答案也是6。有时间要把递归推一推。
08048d20 <func4>:
8048d20: 56 push %esi
8048d21: 53 push %ebx
8048d22: 83 ec 04 sub $0x4,%esp
8048d25: 8b 4c 24 10 mov 0x10(%esp),%ecx
8048d29: 8b 5c 24 14 mov 0x14(%esp),%ebx
8048d2d: 8b 74 24 18 mov 0x18(%esp),%esi
8048d31: 89 f0 mov %esi,%eax
8048d33: 29 d8 sub %ebx,%eax
8048d35: 89 c2 mov %eax,%edx
8048d37: c1 ea 1f shr $0x1f,%edx//>>31
8048d3a: 01 d0 add %edx,%eax
8048d3c: d1 f8 sar %eax
8048d3e: 8d 14 18 lea (%eax,%ebx,1),%edx
8048d41: 39 ca cmp %ecx,%edx
8048d43: 7e 15 jle 8048d5a <func4+0x3a>//over
8048d45: 83 ec 04 sub $0x4,%esp
8048d48: 83 ea 01 sub $0x1,%edx
8048d4b: 52 push %edx
8048d4c: 53 push %ebx
8048d4d: 51 push %ecx
8048d4e: e8 cd ff ff ff call 8048d20 <func4>
8048d53: 83 c4 10 add $0x10,%esp
8048d56: 01 c0 add %eax,%eax
8048d58: eb 1e jmp 8048d78 <func4+0x58>
8048d5a: b8 00 00 00 00 mov $0x0,%eax
8048d5f: 39 ca cmp %ecx,%edx
8048d61: 7d 15 jge 8048d78 <func4+0x58>
8048d63: 83 ec 04 sub $0x4,%esp
8048d66: 56 push %esi
8048d67: 83 c2 01 add $0x1,%edx
8048d6a: 52 push %edx
8048d6b: 51 push %ecx
8048d6c: e8 af ff ff ff call 8048d20 <func4>
8048d71: 83 c4 10 add $0x10,%esp
8048d74: 8d 44 00 01 lea 0x1(%eax,%eax,1),%eax
8048d78: 83 c4 04 add $0x4,%esp
8048d7b: 5b pop %ebx
8048d7c: 5e pop %esi
8048d7d: c3 ret
08048d7e <phase_4>:
8048d7e: 83 ec 1c sub $0x1c,%esp
8048d81: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048d87: 89 44 24 0c mov %eax,0xc(%esp)
8048d8b: 31 c0 xor %eax,%eax
8048d8d: 8d 44 24 08 lea 0x8(%esp),%eax
8048d91: 50 push %eax
8048d92: 8d 44 24 08 lea 0x8(%esp),%eax
8048d96: 50 push %eax
8048d97: 68 6f a2 04 08 push $0x804a26f
8048d9c: ff 74 24 2c pushl 0x2c(%esp)
8048da0: e8 7b fa ff ff call 8048820 <__isoc99_sscanf@plt> 同样的x/s 0x804a26f 得到输入的是%d %d
8048da5: 83 c4 10 add $0x10,%esp
8048da8: 83 f8 02 cmp $0x2,%eax 输入了太多的数直接爆炸
8048dab: 75 07 jne 8048db4 <phase_4+0x36>//bomb
8048dad: 83 7c 24 04 0e cmpl $0xe,0x4(%esp) 第一个数大于14会爆炸
8048db2: 76 05 jbe 8048db9 <phase_4+0x3b>//lowOrequ
8048db4: e8 bd 03 00 00 call 8049176 <explode_bomb>
8048db9: 83 ec 04 sub $0x4,%esp
8048dbc: 6a 0e push $0xe
8048dbe: 6a 00 push $0x0
8048dc0: ff 74 24 10 pushl 0x10(%esp) 第二个数作为参数,要递归了
8048dc4: e8 57 ff ff ff call 8048d20 <func4>
8048dc9: 83 c4 10 add $0x10,%esp
8048dcc: 83 f8 06 cmp $0x6,%eax
8048dcf: 75 07 jne 8048dd8 <phase_4+0x5a>//!=6,bomb
8048dd1: 83 7c 24 08 06 cmpl $0x6,0x8(%esp) 第一个数必须要等于6
8048dd6: 74 05 je 8048ddd <phase_4+0x5f>
8048dd8: e8 99 03 00 00 call 8049176 <explode_bomb>//!=6,bomb
8048ddd: 8b 44 24 0c mov 0xc(%esp),%eax
8048de1: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048de8: 74 05 je 8048def <phase_4+0x71>
8048dea: e8 a1 f9 ff ff call 8048790 <__stack_chk_fail@plt>
8048def: 83 c4 1c add $0x1c,%esp
8048df2: c3 ret
第五关!代码看起来不是很长但其实不是那么容易的,输入的数对应数组中相应索引下表的元素,它们加起来要等于一个值才不会爆炸,答案应该是不唯一的,我找了个和相等的串,OK了
这边GDB开始显示威力了,看不懂的可以在循环开始和末尾设断点,每次查看寄存器,猜一猜哪个寄存器保存什么变量,做什么事等等。
PS:语句不熟练,一开始不知道这数组有多少个元素,print *0xXXXX,print (*0xXXX+4)一个一个试出来的数组元素,好累。
后来网上看到原来print *0x8048...@16就可以看这个地址开始的数组的连续16个元素,不过那位大神是怎么知道共有16 元素的呢?按道理10 足矣...
找到一个恰好的:444427
08048df3 <phase_5>:
8048df3: 53 push %ebx
8048df4: 83 ec 14 sub $0x14,%esp
8048df7: 8b 5c 24 1c mov 0x1c(%esp),%ebx
8048dfb: 53 push %ebx
8048dfc: e8 5f 02 00 00 call 8049060 <string_length>
8048e01: 83 c4 10 add $0x10,%esp
8048e04: 83 f8 06 cmp $0x6,%eax
8048e07: 74 05 je 8048e0e <phase_5+0x1b> 到这儿可以看出要求输入一个长度为6的string
8048e09: e8 68 03 00 00 call 8049176 <explode_bomb>
8048e0e: 89 d8 mov %ebx,%eax
8048e10: 83 c3 06 add $0x6,%ebx
8048e13: b9 00 00 00 00 mov $0x0,%ecx
8048e18: 0f b6 10 movzbl (%eax),%edx//loop begin一个循环,要求和。。。这里不是很懂edx是怎么更新的,随便输入了一组数,设断点看寄存器发现他就是依次输入的数字...谜
8048e1b: 83 e2 0f and $0xf,%edx
8048e1e: 03 0c 95 20 a1 04 08 add 0x804a120(,%edx,4),%ecx 又是一个特殊地址,这是数组寻址的套路,ecx保存和,数组中对应下标的数加到ecx里面了
8048e25: 83 c0 01 add $0x1,%eax//p *0x804a120@16 show array {2, 10, 6, 1, 12, 16, 9, 3, 4, 7, 14, 5, 11, 8, 15, 13}我喜欢这个语句
8048e28: 39 d8 cmp %ebx,%eax//eax存着6,可以看寄存器得到,也可以理解为它是那个函数的返回值,string 的长度是6嘛
8048e2a: 75 ec jne 8048e18 <phase_5+0x25>//loop
8048e2c: 83 f9 39 cmp $0x39,%ecx//let --0x39看来和要求等于57,ok
8048e2f: 74 05 je 8048e36 <phase_5+0x43>
8048e31: e8 40 03 00 00 call 8049176 <explode_bomb>
8048e36: 83 c4 08 add $0x8,%esp
8048e39: 5b pop %ebx
8048e3a: c3 ret
这算是BOSS关了,从上午做到快晚饭的时候。难点在于输入的东西变换了多次,中间没有call bomb,调试就比较难搞(或许是我技巧不够).输入的数与7做差再对应链表,形成一个递减序列才行(渣渣递增还是递减也看不出,又看了寄存器),答案是唯一的:1 6 3 2 4 5
08048e3b <phase_6>:
8048e3b: 56 push %esi
8048e3c: 53 push %ebx
8048e3d: 83 ec 4c sub $0x4c,%esp
8048e40: 65 a1 14 00 00 00 mov %gs:0x14,%eax
8048e46: 89 44 24 44 mov %eax,0x44(%esp)
8048e4a: 31 c0 xor %eax,%eax
8048e4c: 8d 44 24 14 lea 0x14(%esp),%eax
8048e50: 50 push %eax
8048e51: ff 74 24 5c pushl 0x5c(%esp)
8048e55: e8 41 03 00 00 call 804919b <read_six_numbers>//ha这是输入了
8048e5a: 83 c4 10 add $0x10,%esp
8048e5d: be 00 00 00 00 mov $0x0,%esi//initial
8048e62: 8b 44 b4 0c mov 0xc(%esp,%esi,4),%eax//guess,n
8048e66: 83 e8 01 sub $0x1,%eax
8048e69: 83 f8 05 cmp $0x5,%eax//every<=6 为什么要减一再和5比较而不直接和6比较?我也不知道
8048e6c: 76 05 <= jbe 8048e73 <phase_6+0x38>//b1
8048e6e: e8 03 03 00 00 call 8049176 <explode_bomb> //bomb
8048e73: 83 c6 01 add $0x1,%esi
8048e76: 83 fe 06 cmp $0x6,%esi//for countloop
8048e79: 74 1b je 8048e96 <phase_6+0x5b>//out!这样就可以出去了,意思大概是6个数都要<=6,不禁想到了穷举,但这是六个数还是算了。。。
8048e7b: 89 f3 mov %esi,%ebx
8048e7d: 8b 44 9c 0c mov 0xc(%esp,%ebx,4),%eax
8048e81: 39 44 b4 08 cmp %eax,0x8(%esp,%esi,4)
8048e85: 75 05 jne 8048e8c <phase_6+0x51>//b3
8048e87: e8 ea 02 00 00 call 8049176 <explode_bomb> //bomb
8048e8c: 83 c3 01 add $0x1,%ebx
8048e8f: 83 fb 05 cmp $0x5,%ebx
8048e92: 7e e9 jle 8048e7d <phase_6+0x42>//back
8048e94: eb cc jmp 8048e62 <phase_6+0x27>//back 这边的循环看不是很懂,不过试了几个数据也没在这儿爆了,可能是检测输入的是不是6个数吧
8048e96: 8d 44 24 0c lea 0xc(%esp),%eax //newBegin 输入之后从这里开始玩了
8048e9a: 8d 5c 24 24 lea 0x24(%esp),%ebx //notknow 80
8048e9e: b9 07 00 00 00 mov $0x7,%ecx//b2
8048ea3: 89 ca mov %ecx,%edx
8048ea5: 2b 10 sub (%eax),%edx
8048ea7: 89 10 mov %edx,(%eax) 这边把7减去你每个输入的数,再存到原来位置,寄存器看了半天才想到,这边全是寄存器有点难,具体怎么实现也感觉很玄
8048ea9: 83 c0 04 add $0x4,%eax//examine
8048eac: 39 c3 cmp %eax,%ebx
8048eae: 75 f3 traver jne 8048ea3 <phase_6+0x68>
8048eb0: bb 00 00 00 00 mov $0x0,%ebx
8048eb5: eb 16 jmp 8048ecd <phase_6+0x92>//forward
8048eb7: 8b 52 08 mov 0x8(%edx),%edx//next node 刚开始不知道node的存储发现直接print node2 也可以看node2的数值哈哈哈{846,354,422,537,501,963}这是六个node的值
8048eba: 83 c0 01 add $0x1,%eax
8048ebd: 39 c8 cmp %ecx,%eax 这是在->next找到对应node啊,当时看不懂不过调试也猜出来了
8048ebf: 75 f6 jne 8048eb7 <phase_6+0x7c>//loop/b
8048ec1: 89 54 b4 24 mov %edx,0x24(%esp,%esi,4)//find
8048ec5: 83 c3 01 add $0x1,%ebx
8048ec8: 83 fb 06 cmp $0x6,%ebx
8048ecb: 74 17 je 8048ee4 <phase_6+0xa9>//forward
8048ecd: 89 de mov %ebx,%esi 0,0 //newStart
8048ecf: 8b 4c 9c 0c mov 0xc(%esp,%ebx,4),%ecx
8048ed3: b8 01 00 00 00 mov $0x1,%eax
8048ed8: ba 3c c1 04 08 mov $0x804c13c,%edx//?? 好奇地x/x了一下,显示node1: 0x4e看来别有洞天了
8048edd: 83 f9 01 cmp $0x1,%ecx
8048ee0: 7f d5 jg 8048eb7 <phase_6+0x7c> //findNode!
8048ee2: eb dd jmp 8048ec1 <phase_6+0x86>
8048ee4: 8b 5c 24 24 mov 0x24(%esp),%ebx //firstNode
8048ee8: 8d 44 24 24 lea 0x24(%esp),%eax
8048eec: 8d 74 24 38 lea 0x38(%esp),%esi
8048ef0: 89 d9 mov %ebx,%ecx
8048ef2: 8b 50 04 mov 0x4(%eax),%edx //break
8048ef5: 89 51 08 mov %edx,0x8(%ecx)
8048ef8: 83 c0 04 add $0x4,%eax
8048efb: 89 d1 mov %edx,%ecx
8048efd: 39 c6 cmp %eax,%esi
8048eff: 75 f1 jne 8048ef2 <phase_6+0xb7> //loop
8048f01: c7 42 08 00 00 00 00 movl $0x0,0x8(%edx)
8048f08: be 05 00 00 00 mov $0x5,%esi
8048f0d: 8b 43 08 mov 0x8(%ebx),%eax //last
8048f10: 8b 00 mov (%eax),%eax
8048f12: 39 03 cmp %eax,(%ebx) 好长,有点忘了,好像是看寄存器,发现对应的node值被保存到了一些寄存器,然后循环比较,一言不合就爆炸!
8048f14: 7d 05 jge 8048f1b <phase_6+0xe0>//要>=下一个才不会爆炸,是递减序列
8048f16: e8 5b 02 00 00 call 8049176 <explode_bomb> //bomb
8048f1b: 8b 5b 08 mov 0x8(%ebx),%ebx//next Node?
8048f1e: 83 ee 01 sub $0x1,%esi
8048f21: 75 ea !=0 jne 8048f0d <phase_6+0xd2> //countloop
8048f23: 8b 44 24 3c mov 0x3c(%esp),%eax
8048f27: 65 33 05 14 00 00 00 xor %gs:0x14,%eax
8048f2e: 74 05 je 8048f35 <phase_6+0xfa>
8048f30: e8 5b f8 ff ff call 8048790 <__stack_chk_fail@plt>
8048f35: 83 c4 44 add $0x44,%esp
8048f38: 5b pop %ebx
8048f39: 5e pop %esi
8048f3a: c3 ret
做到这儿心力憔悴,隐藏关卡没有再尝试了,于是我可耻地删了相关代码,下面是一些被调用的函数的代码,GDB中disas 函数名也可以看到
08049060 <string_length>:
8049060: 8b 54 24 04 mov 0x4(%esp),%edx
8049064: 80 3a 00 cmpb $0x0,(%edx)
8049067: 74 10 je 8049079 <string_length+0x19>
8049069: b8 00 00 00 00 mov $0x0,%eax
804906e: 83 c0 01 add $0x1,%eax
8049071: 80 3c 02 00 cmpb $0x0,(%edx,%eax,1)
8049075: 75 f7 jne 804906e <string_length+0xe>
8049077: f3 c3 repz ret
8049079: b8 00 00 00 00 mov $0x0,%eax
804907e: c3 ret
0804907f <strings_not_equal>:
804907f: 57 push %edi
8049080: 56 push %esi
8049081: 53 push %ebx
8049082: 8b 5c 24 10 mov 0x10(%esp),%ebx
8049086: 8b 74 24 14 mov 0x14(%esp),%esi
804908a: 53 push %ebx
804908b: e8 d0 ff ff ff call 8049060 <string_length>
8049090: 89 c7 mov %eax,%edi
8049092: 89 34 24 mov %esi,(%esp)
8049095: e8 c6 ff ff ff call 8049060 <string_length>
804909a: 83 c4 04 add $0x4,%esp
804909d: ba 01 00 00 00 mov $0x1,%edx
80490a2: 39 c7 cmp %eax,%edi
80490a4: 75 38 jne 80490de <strings_not_equal+0x5f>
80490a6: 0f b6 03 movzbl (%ebx),%eax
80490a9: 84 c0 test %al,%al
80490ab: 74 1e je 80490cb <strings_not_equal+0x4c>
80490ad: 3a 06 cmp (%esi),%al
80490af: 74 06 je 80490b7 <strings_not_equal+0x38>
80490b1: eb 1f jmp 80490d2 <strings_not_equal+0x53>
80490b3: 3a 06 cmp (%esi),%al
80490b5: 75 22 jne 80490d9 <strings_not_equal+0x5a>
80490b7: 83 c3 01 add $0x1,%ebx
80490ba: 83 c6 01 add $0x1,%esi
80490bd: 0f b6 03 movzbl (%ebx),%eax
80490c0: 84 c0 test %al,%al
80490c2: 75 ef jne 80490b3 <strings_not_equal+0x34>
80490c4: ba 00 00 00 00 mov $0x0,%edx
80490c9: eb 13 jmp 80490de <strings_not_equal+0x5f>
80490cb: ba 00 00 00 00 mov $0x0,%edx
80490d0: eb 0c jmp 80490de <strings_not_equal+0x5f>
80490d2: ba 01 00 00 00 mov $0x1,%edx
80490d7: eb 05 jmp 80490de <strings_not_equal+0x5f>
80490d9: ba 01 00 00 00 mov $0x1,%edx
80490de: 89 d0 mov %edx,%eax
80490e0: 5b pop %ebx
80490e1: 5e pop %esi
80490e2: 5f pop %edi
80490e3: c3 ret
08049176 <explode_bomb>:
8049176: 83 ec 18 sub $0x18,%esp
8049179: 68 43 a2 04 08 push $0x804a243
804917e: e8 3d f6 ff ff call 80487c0 <puts@plt>
8049183: c7 04 24 4c a2 04 08 movl $0x804a24c,(%esp)
804918a: e8 31 f6 ff ff call 80487c0 <puts@plt>
804918f: c7 04 24 08 00 00 00 movl $0x8,(%esp)
8049196: e8 55 f6 ff ff call 80487f0 <exit@plt>
0804919b <read_six_numbers>:
804919b: 83 ec 0c sub $0xc,%esp
804919e: 8b 44 24 14 mov 0x14(%esp),%eax
80491a2: 8d 50 14 lea 0x14(%eax),%edx
80491a5: 52 push %edx
80491a6: 8d 50 10 lea 0x10(%eax),%edx
80491a9: 52 push %edx
80491aa: 8d 50 0c lea 0xc(%eax),%edx
80491ad: 52 push %edx
80491ae: 8d 50 08 lea 0x8(%eax),%edx
80491b1: 52 push %edx
80491b2: 8d 50 04 lea 0x4(%eax),%edx
80491b5: 52 push %edx
80491b6: 50 push %eax
80491b7: 68 63 a2 04 08 push $0x804a263
80491bc: ff 74 24 2c pushl 0x2c(%esp)
80491c0: e8 5b f6 ff ff call 8048820 <__isoc99_sscanf@plt>
80491c5: 83 c4 20 add $0x20,%esp
80491c8: 83 f8 05 cmp $0x5,%eax
80491cb: 7f 05 jg 80491d2 <read_six_numbers+0x37>
80491cd: e8 a4 ff ff ff call 8049176 <explode_bomb>
80491d2: 83 c4 0c add $0xc,%esp
80491d5: c3 ret
终于做完了,感谢网上实验报告的作者!(可耻地看了一点你们的套路),感谢LJL告知的语句,感谢自己的努力!
./bomb_xxx solution 重定向输入,不用自己一行一行敲密码啦。
不足之处欢迎指正!