参考资料:

【深入理解计算机系统】CSAPP Bomb Lab实验 - 雾里尘埃 - 博客园 (cnblogs.com)

CSAPP 第三章 汇编指令 – 传送指令和算术指令 – 柚子小站 (conyli.cc)
(汇编指令速查,有详细描述)

CSAPP第三章常用汇编指令总结_cwmzpls_boomerang_Na的博客-CSDN博客
(汇编指令速查)

bomblab 哔哩哔哩_bilibili

一、lab2前置基础

1. gdb工具
  1. info stack 检查当前栈的情况
  2. info r 查看所有寄存器的值的情况
  3. disas 查看函数的情况
  4. d <断点号>    删除指定断点
  5. info b    查看所有断点信息
  6. continue 从断点处继续执行
  7. b <*0x某某某>    在某个地址设置断点,具体哪里,可以看反汇编的代码,可以根据那个直接复制粘贴设断点的
  8. display <$寄存器>    跟踪寄存器,碰到断点停下时会显示出所有跟踪的寄存器的当前值,非常好用的一个命令,注意的是gdb中表示寄存器的话前面用的不是百分符号%,而是美元符号$
  9. x/参数 <地址>    访问地址的内存,其实就是间接访问,也是很好用的指令,关于参数,s是输出为字符串,d为输出为十进制,x为输出为十六进制,b、w、l、q控制输出字节,默认是w,四字节,s字符串不受这个控制除外。
  10. r    运行程序
  11. layout asm 显示汇编代码执行到那一步
  12. stepi 一步步执行
  13. p 经常用于打印调试过程中碰到的各种变量
  14. run 执行代码,本文常用run ans.txt 将ans.txt的数据当作输入
2. 汇编基础

image.png

二、Lab2

image.png
这是在炸弹的初始化

1. phase_1

image.png

第一个炸弹的汇编代码不长,就是一个"Hello World"。
我们一行行看汇编指令,%esi应该是传入string_not_equal的一个参数,test判断%eax返回值是否相等,等于则je到+23,那么就可以跳过+18的炸弹,ok这题的突破点就是+9的函数,我们查看$0x402400的值

image.png

得到一串字符串,测试一下,ok便通过了。

2. phase_2

image.png

粗读代码,我们需要避开其中的两个炸弹。
+9为read_six_numbers,可以猜测是需要读入6个数,在ans.txt中先填入6个随机数看看,在+14处是一个比较(%rsp)是否等于1,那么这个数应该就是我们输入的第一个参数,测试看看:
image.png

image.png
image.png

可以确定(%rsp)就是第一个参数,且应为1,接下来跳到+52
执行两行:%rbx = (%rsp) + 0x4;%rbp = (%rsp) + 0x18(这里操作的是内存地址)
跳到+27
向下看可以得出+27到+48是一个循环

在第二个炸弹前设置断点,查看%rbx的值,可以看到这就是第二个数
image.png

通过分析第一个循环,其中%rbx就是%rsp + 0x4 - 0x4,那么第一个(%rbx)就是2,以此类推可得答案
image.png

3. phase_3

image.png

通过看该代码,在+24行可知需要两个参数,+44行可得(%rsp)要小于等于7,通过+50这个跳转指令跳到指定的mov,jmp对,这类似于switch;
我们只需找到跳到那里了即可,将断点设置在+50,读入4 438
image.png
经过分析,%rsp + 0xc存的就是第二个参数,这个数应该和%eax相等,在+71处%eax = 0x185,就是389,ok测试一下通过。

4. phase_4

image.png

image.png

先看本体需要什么输入,由+24可看到应该是两个整型数
image.png

+29的返回值%eax应该等于2更印证这一点
+39可知 第一个参数应该小于14(0xe),之后初始化寄存器后进入func4,我们需要找到该函数的出口,并且返回值应为0(+67),阅读代码,可知第一个参数为7,+74行可知第二个参数为0

5. phase_5

image.png

本题在注释中写得比较清楚了,比较卡的点就是取出输入字符串的字符取出其后四位二进制数当作字符串的索引。确实很巧妙!

6. phase_6

image.png

初始化

image.png

该部分可知,输入的数需要小于6,而且是输入6个数

image.png

看中间的循环,该部分实现的是判断当前的数应该不等于前一个数,否则bomb,+68表示对栈元素的遍历,一个int占4个字节

image.png

结果前面大循环后,我们得到了两个信息,接下来跳出循环,根据我的注释可以看到rax开始指向栈底,rsi在栈顶,很明显这是对6个数的遍历,接下来看看做了些什么操作,+110说明【7-当前元素】,+112说明【把+110计算值放入栈区】,即num[i] = 7-num[i]

image.png

image.png

分析这段代码,可知把值存进了链表,在位置rsp + 0x20存了6个节点,分别为node[7 - num[i]]

image.png

这段代码比较抽象,但如果把它看作是链表就好理解了,这就是在重构链表,将断点打在+222,再查看0x6032d0

image.png
可以发现next域发生了变化

image.png

从+235,+239,+241可以看到需要满足node[7-num[i]]->data >= node[7-num[i+1]]->data
从node的结构来看,data域应该就是332,168…
对他进行一个排序,那么num = {4 3 2 1 6 5}
这样就拆掉了所有的炸弹

image.png

image.png

Logo

中德AI开发者社区由X.Lab发起,旨在促进中德AI技术交流与合作,汇聚开发者及学者,共同探索前沿AI应用与创新。加入我们,共享资源,共创未来!🚀

更多推荐