
CSAPP bomb Lab(Lab2)
CSAPP bomb Lab
参考资料:
【深入理解计算机系统】CSAPP Bomb Lab实验 - 雾里尘埃 - 博客园 (cnblogs.com)
CSAPP 第三章 汇编指令 – 传送指令和算术指令 – 柚子小站 (conyli.cc)
(汇编指令速查,有详细描述)
CSAPP第三章常用汇编指令总结_cwmzpls_boomerang_Na的博客-CSDN博客
(汇编指令速查)
一、lab2前置基础
1. gdb工具
info stack
检查当前栈的情况info r
查看所有寄存器的值的情况disas
查看函数的情况d <断点号>
删除指定断点info b
查看所有断点信息continue
从断点处继续执行b <*0x某某某>
在某个地址设置断点,具体哪里,可以看反汇编的代码,可以根据那个直接复制粘贴设断点的display <$寄存器>
跟踪寄存器,碰到断点停下时会显示出所有跟踪的寄存器的当前值,非常好用的一个命令,注意的是gdb中表示寄存器的话前面用的不是百分符号%,而是美元符号$x/参数 <地址>
访问地址的内存,其实就是间接访问,也是很好用的指令,关于参数,s是输出为字符串,d为输出为十进制,x为输出为十六进制,b、w、l、q控制输出字节,默认是w,四字节,s字符串不受这个控制除外。r
运行程序layout asm
显示汇编代码执行到那一步stepi
一步步执行p
经常用于打印调试过程中碰到的各种变量run
执行代码,本文常用run ans.txt
将ans.txt的数据当作输入
2. 汇编基础
二、Lab2
这是在炸弹的初始化
1. phase_1
第一个炸弹的汇编代码不长,就是一个"Hello World"。
我们一行行看汇编指令,%esi应该是传入string_not_equal
的一个参数,test判断%eax返回值是否相等,等于则je到+23,那么就可以跳过+18的炸弹,ok这题的突破点就是+9的函数,我们查看$0x402400
的值
得到一串字符串,测试一下,ok便通过了。
2. phase_2
粗读代码,我们需要避开其中的两个炸弹。
+9为read_six_numbers
,可以猜测是需要读入6个数,在ans.txt中先填入6个随机数看看,在+14处是一个比较(%rsp)是否等于1,那么这个数应该就是我们输入的第一个参数,测试看看:
可以确定(%rsp)就是第一个参数,且应为1,接下来跳到+52
执行两行:%rbx = (%rsp) + 0x4;%rbp = (%rsp) + 0x18(这里操作的是内存地址)
跳到+27
向下看可以得出+27到+48是一个循环
在第二个炸弹前设置断点,查看%rbx的值,可以看到这就是第二个数
通过分析第一个循环,其中%rbx就是%rsp + 0x4 - 0x4,那么第一个(%rbx)就是2,以此类推可得答案
3. phase_3
通过看该代码,在+24行可知需要两个参数,+44行可得(%rsp)要小于等于7,通过+50这个跳转指令跳到指定的mov,jmp对,这类似于switch;
我们只需找到跳到那里了即可,将断点设置在+50,读入4 438
经过分析,%rsp + 0xc存的就是第二个参数,这个数应该和%eax相等,在+71处%eax = 0x185,就是389,ok测试一下通过。
4. phase_4
先看本体需要什么输入,由+24可看到应该是两个整型数
+29的返回值%eax应该等于2更印证这一点
+39可知 第一个参数应该小于14(0xe),之后初始化寄存器后进入func4,我们需要找到该函数的出口,并且返回值应为0(+67),阅读代码,可知第一个参数为7,+74行可知第二个参数为0
5. phase_5
本题在注释中写得比较清楚了,比较卡的点就是取出输入字符串的字符取出其后四位二进制数当作字符串的索引。确实很巧妙!
6. phase_6
初始化
该部分可知,输入的数需要小于6,而且是输入6个数
看中间的循环,该部分实现的是判断当前的数应该不等于前一个数,否则bomb,+68表示对栈元素的遍历,一个int占4个字节
结果前面大循环后,我们得到了两个信息,接下来跳出循环,根据我的注释可以看到rax开始指向栈底,rsi在栈顶,很明显这是对6个数的遍历,接下来看看做了些什么操作,+110说明【7-当前元素】,+112说明【把+110计算值放入栈区】,即num[i] = 7-num[i]
分析这段代码,可知把值存进了链表,在位置rsp + 0x20存了6个节点,分别为node[7 - num[i]]
这段代码比较抽象,但如果把它看作是链表就好理解了,这就是在重构链表,将断点打在+222,再查看0x6032d0
可以发现next域发生了变化
从+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}
这样就拆掉了所有的炸弹
更多推荐
所有评论(0)