本实验在32位Linux虚拟机中完成(点击查看安装教程)
实验内容
二进制炸弹实际是由C语言源程序生成的可执行目标代码,主程序可参考bomb.c。运行时,会按次序提示用户输入3个不同的字符串。如果输入的字符串有误,炸弹就会“爆炸”,输出一条错误信息。必须通过对可执行程序反汇编和逆向工程判断应该是哪3个数据串,从而拆除“炸弹”。
通过分析对C语言源代码生成的可执行程序进行反汇编得到的汇编代码,在实践中加深对C语言和汇编语言关联的认识。
实验过程和结果
本实验一共有30个bomb文件夹,根据学号计算我要拆26号--bomb26
打开虚拟机开始拆炸弹,设置中开启拖放和复制粘贴
选中要拆的炸弹bomb26文件夹,复制,在虚拟机桌面上右键粘贴进来
在左上角点击,搜索终端(Terminal)打开,进入文件夹
里面有三个文件,查看要拆的炸弹为2、3、6
使用objdump -d bomb > 1.txt将反汇编的内容输出到1.txt文本文档中方便查看
打开1.txt向下找到phase_2开始分析
0804906e <phase_2>:
804906e: 53 push %ebx
804906f: 83 ec 30 sub $0x30,%esp
8049072: 8d 44 24 10 lea 0x10(%esp),%eax
8049076: 50 push %eax
8049077: ff 74 24 3c pushl 0x3c(%esp)
804907b: e8 f2 08 00 00 call 8049972 <read_six_numbers>
8049080: 83 c4 10 add $0x10,%esp
8049083: 83 7c 24 08 01 cmpl $0x1,0x8(%esp)
8049088: 74 0d je 8049097 <phase_2+0x29>
804908a: 83 ec 0c sub $0xc,%esp
804908d: 6a 02 push $0x2
804908f: e8 b9 08 00 00 call 804994d <explode_bomb>
8049094: 83 c4 10 add $0x10,%esp
8049097: bb 01 00 00 00 mov $0x1,%ebx
804909c: 89 d8 mov %ebx,%eax
804909e: 83 c3 01 add $0x1,%ebx
80490a1: 89 da mov %ebx,%edx
80490a3: 0f af 54 84 04 imul 0x4(%esp,%eax,4),%edx
80490a8: 39 54 84 08 cmp %edx,0x8(%esp,%eax,4)
80490ac: 74 0d je 80490bb <phase_2+0x4d>
80490ae: 83 ec 0c sub $0xc,%esp
80490b1: 6a 02 push $0x2
80490b3: e8 95 08 00 00 call 804994d <explode_bomb>
80490b8: 83 c4 10 add $0x10,%esp
80490bb: 83 fb 06 cmp $0x6,%ebx
80490be: 75 dc jne 804909c <phase_2+0x2e>
80490c0: 83 c4 28 add $0x28,%esp
80490c3: 5b pop %ebx
80490c4: c3 ret
通过汇编程序可知<read_six_numbers>要输入六个数字,由下方cmpl $0x1,0x8(%esp)可知第一个数是1,不等于1则爆炸。然后进入循环,由imul 0x4(%esp,%eax,4),%edx和cmp %edx,0x8(%esp,%eax,4) 分析可知要输入的数字为上一个数乘以循环次数,(汇编指令imul 0x4(%esp,%eax,4),%edx与%esp+%eax*4+0x4形式相同,此指令和cmp %edx,0x8(%esp,%eax,4)表示要输入的数为前一个数字*循环次数,相等则继续,否则爆炸,共循环6次)即a[n]=a[n-1]*循环次数(2≤n≤6,a[1]=1),循环次数为%ebx,然后赋值给%edx,循环结束后可得六个数字为1 2 6 24 120 720
输入进行验证,炸弹2拆除成功
继续在1.txt中找到phase_3
080490c5 <phase_3>:
80490c5: 83 ec 28 sub $0x28,%esp
80490c8: 8d 44 24 14 lea 0x14(%esp),%eax
80490cc: 50 push %eax
80490cd: 8d 44 24 17 lea 0x17(%esp),%eax
80490d1: 50 push %eax
80490d2: 8d 44 24 20 lea 0x20(%esp),%eax
80490d6: 50 push %eax
80490d7: 68 d6 9e 04 08 push $0x8049ed6
80490dc: ff 74 24 3c pushl 0x3c(%esp)
80490e0: e8 6b f8 ff ff call 8048950 <__isoc99_sscanf@plt>
80490e5: 83 c4 20 add $0x20,%esp
80490e8: 83 f8 02 cmp $0x2,%eax
80490eb: 7f 0d jg 80490fa <phase_3+0x35>
80490ed: 83 ec 0c sub $0xc,%esp
80490f0: 6a 03 push $0x3
80490f2: e8 56 08 00 00 call 804994d <explode_bomb>
80490f7: 83 c4 10 add $0x10,%esp
80490fa: 83 7c 24 0c 07 cmpl $0x7,0xc(%esp)
80490ff: 0f 87 43 01 00 00 ja 8049248 <phase_3+0x183>
8049105: 8b 44 24 0c mov 0xc(%esp),%eax
8049109: ff 24 85 e0 9e 04 08 jmp *0x8049ee0(,%eax,4)
8049110: b8 77 00 00 00 mov $0x77,%eax
8049115: 81 7c 24 08 51 02 00 cmpl $0x251,0x8(%esp)
804911c: 00
804911d: 0f 84 37 01 00 00 je 804925a <phase_3+0x195>
8049123: 83 ec 0c sub $0xc,%esp
8049126: 6a 03 push $0x3
8049128: e8 20 08 00 00 call 804994d <explode_bomb>
804912d: 83 c4 10 add $0x10,%esp
8049130: b8 77 00 00 00 mov $0x77,%eax
8049135: e9 20 01 00 00 jmp 804925a <phase_3+0x195>
804913a: b8 76 00 00 00 mov $0x76,%eax
804913f: 81 7c 24 08 b6 01 00 cmpl $0x1b6,0x8(%esp)
8049146: 00
8049147: 0f 84 0d 01 00 00 je 804925a <phase_3+0x195>
804914d: 83 ec 0c sub $0xc,%esp
8049150: 6a 03 push $0x3
8049152: e8 f6 07 00 00 call 804994d <explode_bomb>
8049157: 83 c4 10 add $0x10,%esp
804915a: b8 76 00 00 00 mov $0x76,%eax
804915f: e9 f6 00 00 00 jmp 804925a <phase_3+0x195>
8049164: b8 67 00 00 00 mov $0x67,%eax
8049169: 81 7c 24 08 b4 03 00 cmpl $0x3b4,0x8(%esp)
8049170: 00
8049171: 0f 84 e3 00 00 00 je 804925a <phase_3+0x195>
8049177: 83 ec 0c sub $0xc,%esp
804917a: 6a 03 push $0x3
804917c: e8 cc 07 00 00 call 804994d <explode_bomb>
8049181: 83 c4 10 add $0x10,%esp
8049184: b8 67 00 00 00 mov $0x67,%eax
8049189: e9 cc 00 00 00 jmp 804925a <phase_3+0x195>
804918e: b8 63 00 00 00 mov $0x63,%eax
8049193: 81 7c 24 08 87 01 00 cmpl $0x187,0x8(%esp)
804919a: 00
804919b: 0f 84 b9 00 00 00 je 804925a <phase_3+0x195>
80491a1: 83 ec 0c sub $0xc,%esp
80491a4: 6a 03 push $0x3
80491a6: e8 a2 07 00 00 call 804994d <explode_bomb>
80491ab: 83 c4 10 add $0x10,%esp
80491ae: b8 63 00 00 00 mov $0x63,%eax
80491b3: e9 a2 00 00 00 jmp 804925a <phase_3+0x195>
80491b8: b8 64 00 00 00 mov $0x64,%eax
80491bd: 81 7c 24 08 46 02 00 cmpl $0x246,0x8(%esp)
80491c4: 00
80491c5: 0f 84 8f 00 00 00 je 804925a <phase_3+0x195>
80491cb: 83 ec 0c sub $0xc,%esp
80491ce: 6a 03 push $0x3
80491d0: e8 78 07 00 00 call 804994d <explode_bomb>
80491d5: 83 c4 10 add $0x10,%esp
80491d8: b8 64 00 00 00 mov $0x64,%eax
80491dd: eb 7b jmp 804925a <phase_3+0x195>
80491df: b8 6c 00 00 00 mov $0x6c,%eax
80491e4: 81 7c 24 08 3d 01 00 cmpl $0x13d,0x8(%esp)
80491eb: 00
80491ec: 74 6c je 804925a <phase_3+0x195>
80491ee: 83 ec 0c sub $0xc,%esp
80491f1: 6a 03 push $0x3
80491f3: e8 55 07 00 00 call 804994d <explode_bomb>
80491f8: 83 c4 10 add $0x10,%esp
80491fb: b8 6c 00 00 00 mov $0x6c,%eax
8049200: eb 58 jmp 804925a <phase_3+0x195>
8049202: b8 73 00 00 00 mov $0x73,%eax
8049207: 81 7c 24 08 3c 03 00 cmpl $0x33c,0x8(%esp)
804920e: 00
804920f: 74 49 je 804925a <phase_3+0x195>
8049211: 83 ec 0c sub $0xc,%esp
8049214: 6a 03 push $0x3
8049216: e8 32 07 00 00 call 804994d <explode_bomb>
804921b: 83 c4 10 add $0x10,%esp
804921e: b8 73 00 00 00 mov $0x73,%eax
8049223: eb 35 jmp 804925a <phase_3+0x195>
8049225: b8 6b 00 00 00 mov $0x6b,%eax
804922a: 81 7c 24 08 97 02 00 cmpl $0x297,0x8(%esp)
8049231: 00
8049232: 74 26 je 804925a <phase_3+0x195>
8049234: 83 ec 0c sub $0xc,%esp
8049237: 6a 03 push $0x3
8049239: e8 0f 07 00 00 call 804994d <explode_bomb>
804923e: 83 c4 10 add $0x10,%esp
8049241: b8 6b 00 00 00 mov $0x6b,%eax
8049246: eb 12 jmp 804925a <phase_3+0x195>
8049248: 83 ec 0c sub $0xc,%esp
804924b: 6a 03 push $0x3
804924d: e8 fb 06 00 00 call 804994d <explode_bomb>
8049252: 83 c4 10 add $0x10,%esp
8049255: b8 6b 00 00 00 mov $0x6b,%eax
804925a: 3a 44 24 07 cmp 0x7(%esp),%al
804925e: 74 0d je 804926d <phase_3+0x1a8>
8049260: 83 ec 0c sub $0xc,%esp
8049263: 6a 03 push $0x3
8049265: e8 e3 06 00 00 call 804994d <explode_bomb>
804926a: 83 c4 10 add $0x10,%esp
804926d: 83 c4 1c add $0x1c,%esp
8049270: c3 ret
使用x/s查看0x8049ed6中的内容得知要输入三个数据,一个整数,一个字符,一个整数
由cmpl $0x7,0xc(%esp)可知第一个数字小于7这里取0。然后有jmp *0x8049ee0(,%eax,4),此处为switch语句,查看地址为0x8049110
下方mov $0x77,%eax和cmpl $0x251,0x8(%esp)等于则跳转表示%esp+8的值要等于251H,十进制为593。然后跳转到0x804925a进行 cmp 0x7(%esp),%al表示%esp+7的值等于AL的值则跳转,AL中的值为77H,为’w’的ASCII码。所以要输入的两个数字和一个字符为0 w 593
输入进行验证,炸弹3拆除成功
继续向下找到phase_6
080493b0 <phase_6>:
80493b0: 83 ec 10 sub $0x10,%esp
80493b3: 6a 0a push $0xa
80493b5: 6a 00 push $0x0
80493b7: ff 74 24 1c pushl 0x1c(%esp)
80493bb: e8 f0 f5 ff ff call 80489b0 <strtol@plt>
80493c0: a3 74 c1 04 08 mov %eax,0x804c174
80493c5: c7 04 24 74 c1 04 08 movl $0x804c174,(%esp)
80493cc: e8 88 ff ff ff call 8049359 <fun6>
80493d1: 8b 40 08 mov 0x8(%eax),%eax
80493d4: 8b 40 08 mov 0x8(%eax),%eax
80493d7: 8b 40 08 mov 0x8(%eax),%eax
80493da: 8b 40 08 mov 0x8(%eax),%eax
80493dd: 83 c4 10 add $0x10,%esp
80493e0: 8b 15 74 c1 04 08 mov 0x804c174,%edx
80493e6: 39 10 cmp %edx,(%eax)
80493e8: 74 0d je 80493f7 <phase_6+0x47>
80493ea: 83 ec 0c sub $0xc,%esp
80493ed: 6a 06 push $0x6
80493ef: e8 59 05 00 00 call 804994d <explode_bomb>
80493f4: 83 c4 10 add $0x10,%esp
80493f7: 83 c4 0c add $0xc,%esp
80493fa: c3 ret
还有一个fun6
08049359 <fun6>:
8049359: 56 push %esi
804935a: 53 push %ebx
804935b: 8b 44 24 0c mov 0xc(%esp),%eax
804935f: 8b 70 08 mov 0x8(%eax),%esi
8049362: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax)
8049369: 89 c2 mov %eax,%edx
804936b: 85 f6 test %esi,%esi
804936d: 75 2c jne 804939b <fun6+0x42>
804936f: eb 3c jmp 80493ad <fun6+0x54>
8049371: 89 d1 mov %edx,%ecx
8049373: 8b 51 08 mov 0x8(%ecx),%edx
8049376: 85 d2 test %edx,%edx
8049378: 74 08 je 8049382 <fun6+0x29>
804937a: 39 1a cmp %ebx,(%edx)
804937c: 7f f3 jg 8049371 <fun6+0x18>
804937e: eb 02 jmp 8049382 <fun6+0x29>
8049380: 89 c1 mov %eax,%ecx
8049382: 39 d1 cmp %edx,%ecx
8049384: 74 05 je 804938b <fun6+0x32>
8049386: 89 71 08 mov %esi,0x8(%ecx)
8049389: eb 02 jmp 804938d <fun6+0x34>
804938b: 89 f0 mov %esi,%eax
804938d: 8b 4e 08 mov 0x8(%esi),%ecx
8049390: 89 56 08 mov %edx,0x8(%esi)
8049393: 85 c9 test %ecx,%ecx
8049395: 74 16 je 80493ad <fun6+0x54>
8049397: 89 ce mov %ecx,%esi
8049399: 89 c2 mov %eax,%edx
804939b: 85 d2 test %edx,%edx
804939d: 74 e1 je 8049380 <fun6+0x27>
804939f: 8b 1e mov (%esi),%ebx
80493a1: 89 c1 mov %eax,%ecx
80493a3: 39 1a cmp %ebx,(%edx)
80493a5: 7f cc jg 8049373 <fun6+0x1a>
80493a7: 89 c2 mov %eax,%edx
80493a9: 89 f0 mov %esi,%eax
80493ab: eb e0 jmp 804938d <fun6+0x34>
80493ad: 5b pop %ebx
80493ae: 5e pop %esi
80493af: c3 ret
<strtol@plt>输入并读取一行字符,将字符转换为长整型,并规定了长整型的大小。可能是链表结构,头节点为0x804c174,判断输入的数字是否和调用函数fun6返回的值相等,相等则成功拆除,不相等则炸弹爆炸。使用指令查看节点中的内容并继续查看后续节点
由后续4个mov 0x8(%eax),%eax和mov 0x804c174,%edx和cmp %edx,(%eax)可知要输入的值为0x804c1a4中的内容270H,转换成十进制为624
输入进行验证,炸弹6拆除成功
到此为止,2、3、6炸弹全部拆除成功
最后
phase_3中,有多个结果都正确,因为第一个输入的数字不同,跳转到的地址不同,所有的结果如下:
0 w(77H) 593(251H)
1 v(76H) 438(1B6H)
2 g(67H) 948(3B4H)
3 c(63H) 391(187H)
4 d(64H) 582(246H)
5 l(6CH) 317(13DH)
6 s(73H) 828(33CH)
7 k(6BH) 663(297H)
phase_6中,即使没有分析出结果,不知道要输入哪个节点中的内容,还可以一个一个查看,全部试一遍也能找到答案(虽然不建议这样做)