csapp:bomblab炸弹实验

phase_1:判断字符串是否相等

(一)反汇编代码

在这里插入图片描述

(二)汇编代码说明

在这里插入图片描述

(三)分析

首先我们看到调用的函数为<strings_not_equal>,即比较两个字符串是否相等。可以想到该函数需要的两个参数为个两个字符串的首地址。按照这个思路我们先查看一下地址0x804a15c:
在这里插入图片描述
另外一个参数放在0x20(%esp)中,我们需要查看寄存器%esp中的值。这里设置断点b phase_1,然后随便输入一个字符串,再执行该函数内部的几条汇编代码,再查看esp中的值即可(一定要用si执行几步汇编代码,esp中的值会发生变化):
在这里插入图片描述在这里插入图片描述
(%esp)中的值为0xbffff2c0,那么地址0xbffff2e0(0x20(%esp))中的值即为另一个字符串首地址:
在这里插入图片描述
果然地址0x804c3e0这个地址开始存放的就是刚刚输入的字符串hello world。验证了刚刚的猜想。<string_not_equal>函数只有在字符串相等的时候返回值0,跳转,不会bomb。
故输入The moon unit will be divided into two divisions.:
在这里插入图片描述

phase_2:斐波那契数列

(一)汇编代码分析

在这里插入图片描述

(二)具体分析

函数<read_six_numbers>即读入6个数字。再看其上面的几个传参指令:一个是把地址0x18(%esp)传了进去; 另一个是传入了地址0x40(%esp)储存的值。按照第一关的思路,我们可以想到0x40(%esp)储存的值为我们输入字符串的首地址。
验证0x40(%esp)为输入字符串首地址:
在这里插入图片描述
根据后面的分析,0x18(%esp)这个地址值也是保存了a[0]首地址,因为在执行完函数
<read_six_numbers>函数后还要进行一系列判断,验证0x18(%esp)这个地址值:
在这里插入图片描述
(输出前两个数 此时输入为0 1 1 2 3 5)
中间有几行代码可以直接看出a[0]=0,a[1]=1.
%ebx初始值为a[2]的地址,%eax= -0x8(%ebx)的值加-0x4(%ebx)。如果%eax和(%ebx)不相等会bomb;否则%ebx中的地址值+4,继续这样循环。很显然这就是一个斐波那契数列。
在这里插入图片描述

phase_3:switch选择分支

(一)汇编代码分析

在这里插入图片描述
在这里插入图片描述

(二)具体分析

执行0x8048870 __isoc99_sscanf@plt之前传入了4个参数。其中0x1c(%esp),0x18(%esp)为输入的两个整数的地址;0x30(%esp)应该和前面几题一样,存的就是我们输入字符串的首地址,先验证一下(输入4 0)(注意一定要在执行完函数以后才有输入的值):
在这里插入图片描述
0x804a3e3这个地址是干什么的呢:在这里插入图片描述
也应证了确实要输入两个整数
0x30(%esp)是字符串的首地址:
在这里插入图片描述
第一个参数不能大于5,否则bomb:
在这里插入图片描述在这里插入图片描述
一个关键的语句:
0x08048c00 <+60>: jmp *0x804a220(,%eax,4) //switch选择分支
这里%eax存的是第一个参数的值,为4,可以调试一下看看跳转到了哪里:
在这里插入图片描述
故最后进行一些列计算后,计算结果%eax=0,只有结果和第二个参数相等时不爆照故第一个参数推出为0。当然这题会有多个答案。
在这里插入图片描述

phase_4:递归函数

(一)汇编代码分析

在这里插入图片描述
在这里插入图片描述
假设我们输入的是2和3。这部分主要是对函数的参数进行处理。0xc(%esp)和0x8(%esp)中是输入的参数。打印地址0x804a3e3中的内容,输出“%d %d”,说明是要输入两个整数。
最后一个参数是字符串首地址,可以验证:(当时输入的是ff)
在这里插入图片描述
在这里插入图片描述
由中间一部分汇编代码可以得知第一个参数:0<=x1<=14。由最后的汇编代码得知第二个参数要为7。满足条件就会调用函数func4.
func4的汇编代码如下,是一个递归调用的函数:
在这里插入图片描述
转化成c++:
在这里插入图片描述
最后当输入的第一个数为14时,输出为7(phase_4汇编中最后函数输出要为7)

phase_5

(一)汇编代码分析

在这里插入图片描述

(二)具体分析

这函数需要输入一个长度为6的字符串。实现了一个循环。依次处理这六个字符,只取每个字符ascii码的最后4位放入ecx,作为偏移量。将0x804a240+%ecx*4放入edx。最终edx的值要为0x2d.
其中地址0x804a240是一个字符串的首地址,可得到当选中如下数据最后和为0x2e。则偏移量ecx应该分别为(0x):3 4 5 6 7 8.即选取字符串的6个字符ascii码的二进制编码后4位需要满足上面的关系。所以,取c(0x63),d(0x64),e(0x65),f(0x66),g(0x67),h(0x68)
在这里插入图片描述

(三)结果(不唯一)

在这里插入图片描述

phase_6:链表

(一)汇编代码分析

很显然是要输入六个整数
在这里插入图片描述
接下来这一部分的代码对输入进行了限制。首先输入数据不能大于6。然后是一个双重的for循环,要求每个数组元素不能相同。
在这里插入图片描述
在这里插入图片描述
再接下来对每个数组元素的值进行了处理,a[i]=7-a[i].
在这里插入图片描述
然后有一长串不好分析的汇编代码,这其中有一个重要的地址需要发现:0x804c13c.
打印其中内容,发现是个链表。三个数一组,第一个数是一个权值,第二个数按照123456排序下来,第三个数是下一个节点的首地址。
在这里插入图片描述
我们将中间那段不好分析的汇编语言跳过,直接看最后一部分。发现节点的权值要递减排列。所以猜测中间部分的汇编代码是对节点按照权重递减排列。
在这里插入图片描述
自行按照权值递减排列结果:
246 3
18a 6
17d 4
176 1
115 2
E2 5
但是由于前面有部分代码实现了a[i]=7-a[i],所以应该输入4,1,3,6,5,2

(二)结果

在这里插入图片描述

secret_phase

(一)隐藏关卡如何进去

由于phase_defused函数一直没有用到过,所以可能与这个有关,查看其汇编代码:
<+18>:只有地址0x804c3cc这个地址里的值=6时才会触发隐藏关卡,猜想每通过一关这个地址中的值就会自动加一。在三个phase函数设置断点验证:
(自动加一的功能应该是在readline中实现的)
在这里插入图片描述
<+27>~<+66>:传参+调用输入的函数
参数0x804a3e9说明了参数要有两个整数,一个字符串
在这里插入图片描述
第二个参数0x804c4d0按照前面几个炸弹的经验,应该是输入字符串的首地址,但是之前的格式都是xx(%esp),可能这个地址里面存的是之前某个炸弹输入的字符串的首地址。之前的首地址都存在30(%esp)。经验证0x804c4d0是phase_4的字符串首地址
在这里插入图片描述
回顾一下第四次的输入:当时是输入两个整数,而这里要是要输入两个整数以及一个字符串,说明我们需要在第四次输入时,输入完两个整数后还需要输入一个字符串。可能这里会有疑问,这里再输入一个字符串不会导致bomb 吗?其实是不会的,因为当时传的参数为“%d %d”,所以在读入两个整数以后便不会再读入。

<+91>有一个判读那判断字符串相等的函数,查看地址内容可知第四个炸弹后面要输入DrEvil才可开始隐藏炸弹:
在这里插入图片描述
再后面有两个输出的函数,输出相应的字符串后就会进入secret_phase了:
在这里插入图片描述

(二)secret_phase汇编分析

在这里插入图片描述
可以看到调用了fun7函数,fun7的返回值要为0,查看fun7汇编代码:在这里插入图片描述
对应的c++代码:
在这里插入图片描述
这个函数会用来对一颗二叉树进行查询操作,最初传入函数的那个地址就是根节点的地址,具体的返回值来说就像代码中写的那样:当当前节点的值等于你查询的值时候,返回0,否则根据值的大小的判断进行不同的递归查询。当查询值大于当前节点的值的时候,递归查询右子树,否则递归查询左子树。
Fun7返回值要为0,那么输入根节点的值即可,根节点值为十进制36:
在这里插入图片描述

(三)结果

在这里插入图片描述

  • 17
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值