实验介绍
- 使用所学知识拆除Binary Bombs来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。
- Binary Bombs(二进制炸弹)是一个可执行程序,是C语言编译链接成的,包含phase1~phase6共6个阶段(还有隐藏阶段)。
- 各阶段要求输入一个答案,若正确,该阶段炸弹被拆除,否则爆炸。
- 你需要拆除尽可能多的炸弹
- 实验提供一个bomb.c和bomb可执行文件,但是,bomb.c中只有主函数,和一些彩蛋。
- bomb有一个命令行参数,为读入的文件。所以你可以将答案写入到一个txt文件,每个答案一行。
实验技巧
gdb调试
(gdb)info reg
查看所有寄存器的信息(gdb)info frame
查看栈的信息(gdb)b * 0x405040
在0x405040处设置断点(gdb)b phase_1
在函数phase_1处设置断点(gdb)x/2s 0x405010
输出0x405010开始的两个字符串(gdb)stepi
执行一条指令(gdb)nexti
类似于stepi,但以函数调用为单位(gdb)c
继续(遇到断点后)(gdb)run ans.txt
命令行参数运行(gdb)q
退出(gdb)finish
运行到当前函数返回(gdb)delete
删除所有断点(gdb)delete 5
删除断点 5(gdb)layout asm
展示当前的汇编语言(非常的好用,ctrl + L 刷新)(gdb)p *(int *) 0x405012
输出位于地址0x405012的整数(gdb)p $rax
输出%rax的值(gdb)p /x $rax
以十六进制输出%rax的值(gdb)p *(int *)($rbp + 0x8)
输出地址%rbp + 0x8的整数(gdb)disas phase_1
反汇编phase_1函数
我的实验经验
- 先反汇编
objdump -d bomb > asm.txt
。然后把asm.txt的内容复制粘贴到word。用word来看汇编语言,方便涂色标注 - 一边分析汇编语言,一边利用gdb调试。
- 先熟读CSAPP第三章,最好把习题做完
phase_1
密码如下:I am not part of the problem. I am a Republican.
破解过程:
-
在phase_1函数处设置断点。
-
随便输出一个答案,如 abcdef。
-
观察断点信息,input_strings可知,答案确实是一个字符串。
-
反汇编观察到 strings_not_equal,推测是在判断字符串是否相等。然后,test命令测试返回值,如果非0,则爆炸。
-
0为真,1为假,那么非0对于strings_not_equal,应该是字符串不等,所以现在要找到那个与输出的字符串匹配的字符串。
-
观察到,传递给寄存器%esi的值0x403150
-
打印此处的字符串:
x/2s 0x403150
-
得到答案
汇编代码:
点击查看代码
00000000004013f9 <phase_1>:
4013f9: 55 push %rbp
4013fa: 48 89 e5 mov %rsp,%rbp
4013fd: be 50 31 40 00 mov $0x403150,%esi
401402: e8 3d 04 00 00 callq 401844 <strings_not_equal>
401407: 85 c0 test %eax,%eax
401409: 75 02 jne 40140d <phase_1+0x14>
40140b: 5d pop %rbp
40140c: c3 retq
40140d: e8 2e 05 00 00 callq 401940 <explode_bomb>
401412: eb f7 jmp 40140b <phase_1+0x12>****
phase_2
密码如下:0 1 3 6 10 15
破解过程:
-
在phase_2设置断点。
-
运行,参数为ans.txt,其中写有刚刚得到的第一个的答案。
-
先随便输入,这里输入一个数 5。
-
反汇编观察,一开始调用了<read_six_numbers>函数,那么可以先把输入改为6个数
-
继续观察下面的汇编语言,发现 -30(%rbp)不就是存放第一个数的位置吗?这里判断第一个数必须为0,否则炸弹爆炸
-
在后面,%ebx先赋值为1,然后判断是否大于5,是一个循环,然后根据输入的6个数,每轮打印发现规律。
-
得出代码:
for(int i = 1; i <= 5; i ++) a[i] = a[i - 1] + i;
。 -
则得出答案。
汇编代码:
点击查看代码
0000000000401414 <phase_2>:
401414: 55 push %rbp
401415: 48 89 e5 mov %rsp,%rbp
401418: 53 push %rbx
401419: 48 83 ec 28 sub $0x28,%rsp
40141d: 48 8d 75 d0 lea -0x30(%rbp),%rsi
401421: e8 3c 05 00 00 callq 401962 <read_six_numbers>
401426: 83 7d d0 00 cmpl $0x0,-0x30(%rbp)
40142a: 78 07 js 401433 <phase_2+0x1f>
40142c: bb 01 00 00 00 mov $0x1,%ebx
401431: eb 0f jmp 401442 <phase_2+0x2e>
401433: e8 08 05 00 00 callq 401940 <explode_bomb>
401438: eb f2 jmp 40142c <phase_2+0x18>
40143a: e8 01 05 00 00 callq 401940 <explode_bomb>
40143f: 83 c3 01 add $0x1,%ebx
401442: 83 fb 05 cmp $0x5,%ebx
401445: 7f 17 jg 40145e <phase_2+0x4a>
401447: 48 63 c3 movslq %ebx,%rax
40144a: 8d 53 ff lea -0x1(%rbx),%edx
40144d: 48 63 d2 movslq %edx,%rdx
401450: 89 d9 mov %ebx,%ecx
401452: 03 4c 95 d0 add -0x30(%rbp,%rdx,4),%ecx
401456: 39 4c 85 d0 cmp %ecx,-0x30(%rbp,%rax,4)
40145a: 74 e3 je 40143f <phase_2+0x2b>
40145c: eb dc jmp 40143a <phase_2+0x26>
40145e: 48 83 c4 28 add $0x28,%rsp
401462: 5b pop %rbx
401463: 5d pop %rbp
401464: c3 retq
phase_3
密码如下:1 -1199
破解过程:
-
设置断点,运行,反汇编。
-
发现线索:
401475:be 1f 33 40 00 mov $0x40331f,%esi
。 -
打印0x40331f处的字