CSAPP——Bomb Lab Report
Bomb Lab
姓名:张**
学号:S********7
实验介绍
本报告为中科大研究生课程计算机系统Lab2——Bomb Lab(参考CMU CSAPP Lab1 )的实验报告,主要记录实验 2 二进制炸弹拆解过程以及主要思考。Bomb Lab 对应课本第三章,根据 Randal 所说,这一章也是整本书最重要的章节,我们需要学习代码的机器表示并在这个层次进行问题思考与代码分析。有很多 High Level 觉得很复杂的事情(比如递归)在底层看并无复杂。学习本章的过程也更好的熟悉并理解机器代码以及和 C 语言的关系。
实验环境
Lenovo Laptop
- CPU: AMD Ryzen 5 2.10GHz
- RAM: 16GB
- OS: Ubuntu 20.04
实验详解
Phase 1
1 |
|
阅读反汇编代码,我们发现0x08048b94 <phase_1+20>
call 了 strings_not_equal
,我们只需要找到比对的字符串。在栈中我们发现程序分配了空间给一个地址,合理猜测有可能是比对字符串的起始地址。我们使用 gdb 打印,x/s 0x8049928
字符串内容。
答案
1 |
|
Phase 2
1 |
|
阅读反汇编代码,phase_2 前面阶段是输入六个整数。由0x08048bc3 <phase_2+31>
的无条件 jump 到结尾和0x08048be7 <phase_2+67>
的条件跳转 jle,为 while 循环的跳转至中间翻译。阅读中间的反汇编代码,观察判断是比较相邻输入的差是否为 5。所以只要满足+5 的等差数列就是符合条件的正确答案。
答案组合(多种)
1 |
|
Phase 3
1 |
|
输入两个数,输入第一个参数应小于 7,default 情况为引爆炸弹。
整体表达式,case 从不同地方起始运算
1 |
|
答案组合(有多种),但注意尾部还有一个判断参数 1 是否大于 5 的限制:
1 |
|
Phase 4
输入一个参数(参数过多会引爆炸弹)。
1 |
|
根据反汇编0x8048d0b <phase_4+59>
行和0x8048d13 <phase_4+67>
行可知 phase 4 调用了一个递归函数fun4
,将最后的返回结果与 0x157(十进制为 343)进行比较。
1 |
|
阅读fun4
反汇编结果发现该函数判断输入参数小于等于 0 时,返回 1,否则递归调用fun4(x-1)
,得到的结果乘 7 后返回,相当于以下 c 代码:
1 |
|
易知0x157 = 343 = 7^3
,所以答案:
1 |
|
Phase 5
1 |
|
阅读汇编代码,读取一个字符串,如果长度不为 6 会直接引爆炸弹。后面紧跟一个循环。阅读循环体内容我们可以发现,每次将输入的字符串转化为一个偏移量。
1 |
|
and $0xf,%eax
,对字母对应的 ASCII 值只取最低字节作为偏移,然后从起始地址 0x804a5c0 加偏移取出新字符。调用 gdb 指令x/s 0x804a5c0
查看,同时查看我们最终要比对的字符串。
1 |
|
可以确定我们要加的偏移量为1
,5
,0
,11
,13
,1
。
根据前面计算偏移的规则(注意低字节为 0 的字母为p
),我们的答案是
1 |
|
Phase 6
1 |
|
其中0x08048e5f <phase_6+56>
到0x08048e65 <phase_6+62>
很像列表的访问。p = p->next
,寄存器保存指针值,指向位置偏移的值赋给指针自身。最后终止时指向值与 atoi 转换的结果是否一致。while 循环变量知循环了四轮。
fun6 的反汇编结果:
1 |
|
发现其中并没有根据参数调整的地方,GDB 运行至0x8048e74 <phase_6+77>
,发现与地址0x804a5d0
储存的值进行比较,打印为 530,所以我们最终答案为
1 |
|
实验结果
按照阶段依次输入上面分析的答案,运行结果截图如下:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!