前言
在皓哥的鼓励下,磕磕绊绊断断续续终于做完了BombLab,这个实验确实很有趣而且对我帮助很大,做完也非常的有成就感(HGNB)👏,因此决定写一篇博客记录一下学习的过程
首先作几点说明
1、由于每个学生的Bomb是随机的,而我是从网上其他人的github下载的lab,所以有可能你的Bomb与我并不一样,导致每个阶段的答案可能是不一样的,但是方法应该还是可以参考的
2、这个实验对提升汇编语言的理解能力以及自己调试代码的能力真的有很大帮助,所以强烈建议你自己独立思考并完成这个实验,即使多花些时间我觉得也是值得的
常用gdb命令
常用的命令可以在CSAPP书上的3.10.2节查阅,也可以在课程的pdf上找到,下面是我在拆弹过程中用的较多的命令:(首先在终端输入gdb bomb启动gdb)
- run: 运行程序。较为有用的方式是带参数启动,例如
run solutions.txt
,其中solutions.txt
存有你已经完成的阶段的答案,这样可以避免在攻略后阶段时每次都要输入前面阶段的答案。另外如果程序已经启动,gdb会提示你是否要从头开始运行,可以用这个方法避免我们被炸死(虽然我们不会因此扣分,但紧张感还是要有的 😃) - b: 设置断点。常用形式是
b functionName
和b *0xffffffff
,分别用来在函数入口处设置断点和在某个地址设置断点。这条命令执行后会提示breakpoint x at xxxxxxx
,然后可以用delete x
来删除该断点,disable/enable x
来禁用和启用断点。直接输入delete
可以一次性清除所有断点 - continue: (在程序停下时)继续程序
- disas:
disas functionName
查看某个函数的汇编代码 - stepi/stepi n: 单步运行1步/n步(会进入函数)
- nexti/nexti n: 单步运行1步/n步(不会进入函数)
- info registers: 显示所有寄存器的值
- print: 打印信息。
print $rdx
打印出rdx寄存器的值,print *(int*)0xffffffff
打印出0xffffffff
处的整数值 - x: 检查信息。
x /s 0xffffffff
检查0xffffffff
处的字节,x /20d 0xffffffff
检查0xffffffff
开始的20个4字节并用十进制输出
在开始拆弹前,我们可以先查看函数的源代码bomb.c
可以看到这个程序一共有六个阶段,每一阶段会读取我们的输入并作为参数传递给当前阶段的函数,因此我们可以分别查看phase_1~phase_6的汇编代码来推测每一阶段的答案
Phase 1
函数phase_1
的汇编代码如下:
可以看出,它将%esi
置为0x402400
然后调用了strings_not_equal
函数,并比较结果,如果为0则返回,否则引爆。那么很自然的推测我们只需要输入这个炸弹相同的字符串即可,这里使用x /s
命令有奇效:
所以第一阶段直接输入这个句子即可
Phase 2
函数phase_2
的汇编代码如下:
观察这个函数,我们会发现第九行调用了一个函数read_six_numbers
,那么可以推测这一阶段需要输入6个数字,我们可以先随便输入6个数字试试(我输入了1 2 3 4 5 6&