0
点赞
收藏
分享

微信扫一扫

CSAPP--Bomblab 保姆级详解

Lab要求:使用gdb获取程序内部信息,理解由反汇编器生成的汇编代码

Phase_1

在这里插入图片描述
注意到phase_1函数带了一个参数进入,保存在%rdi 中,然后给了%esi 赋了一个值,随后进入了一个叫string_not_equal的函数,合理猜测这函数就是字面意思。
先在函数进入前,阻拦一下,感觉0x402400应该就是要比较的字符串的首地址
在这里插入图片描述
去看一眼:
请添加图片描述
看到结果基本确定正确了,验证一下也确实正确。
在这里插入图片描述

Phase_2

在这里插入图片描述
同样地,phase_2也带了一个参数进入,又使用了一个%rsi 作为参数二,进入了一个 read_six_number的函数,同样怀疑是否就是字面意思。

请添加图片描述
值得注意的是,无论在命令行中输入了什么,都会以字符串的形式先保存,而这也是为什么又调用了read_six_numbers,在read_six_lines 中调用了scanf将字符串转换为int,再往图片的下部看发现调用的格式控制字符串是"%d %d %d %d %d %d"。

再想,读成数字保存在哪里?由于输入了两个参数,参数二是用%rsp 赋值的,sp是stack pointer的简写,显然是一处内存地址。
在这里插入图片描述
先输入一个"1 2 3 4 5 6"作为测试
在这里插入图片描述在这里插入图片描述
在函数的出口设一个断点
在这里插入图片描述
查看进入函数时用于赋值参数二的%rsp,发现我的输入果然是保存在栈中。

请添加图片描述

首先发现,输入的第一个数必须为 1,不然就 call exlplode_bomb.
随后进入了一个以rbx为搜索指针,以rbp为结尾信号的循环,
循环体是,将%rbx的上一个数乘以二,与%rbx指向的数作比较,即:

if(input[i] != input[i-1] * 2)  explode_bomb();

鉴于第一个数为1,每个数是上一个的2倍,且有6个数,
所以答案是"1 2 4 8 16 32"。
在这里插入图片描述

Phase_3

在这里插入图片描述

在这里插入图片描述
和之前的方法类似直接查看scanf的格式控制字符串,又在%rdi中地址所在内存找到了自己的输入。

圈1:scanf的返回值要大于1,不然BOOM!
圈2:input[0]要<=7,不然BOOM!
圈3:这是一个 地址跳转 指令!

到这里应该不难看出,答案不止一个,我们可以不断的修改%rip,在跳转指令执行前修改%rax值,再执行以查看跳转目的地。

  • Input[0] = 1,则:
    input[1]必须等于 0x137 = 311(dec)
    在这里插入图片描述
    在这里插入图片描述
  • Input[0] = 2,则:
    input[1]必须等于 0x2c3 = 707(dec)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    太无聊了,就不继续了,但反正 input[0]=0、1…7 都是可以有答案的。
    以1为例:
    在这里插入图片描述

但值得一提的是,负数不行,编译器使用了一个很聪明的ja指令。

Phase_4

在这里插入图片描述
总之和 Phase_3 很像,也是输入两个数字,就不展开了,仍然是0x8(%rsp)里存input[0],0xc(%rsp)里存input[1]。

圈1:input[0] <= 14,和上一个Phase一样,负数是禁止的,编译器使用了一个jbe对一个signed int作unsigned int比较,这是一种比较隐蔽的技巧以剔除负数。
圈2:进入 func4 时,带了三个参数,参数一:input[0]、参数二:0、参数三:14。
圈3:离开func4之后才检查input[1],说明func4确实只与input[0]有关,正如参数表示的那样。
圈4:func4的返回值必须是0,不然就jump to BOOM!

在这里插入图片描述Phase_4 是肯定有其他答案,但func4的迭代我感觉挺难看出它的用意的,本着详解的原则我尝试把它翻译成了C语言:
在这里插入图片描述
所以只有3个答案,“1 0”、“3 0”、“7 0”
在这里插入图片描述
没有问题!

Phase_5

举报

相关推荐

【CSAPP】Datalab 详解

Docker入门——保姆级

NVM保姆级安装

0 条评论