前言:一个不会汇编的菜鸟强行做一个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