bomblab实验的C语言,计算机系统原理实验之BombLab二进制炸弹3、4关

计算机系统原理实验之BombLab二进制炸弹3、4关

发布时间:2018-05-23 14:41,

浏览次数:1127

, 标签:

BombLab

实验目的:

通过二进制炸弹实验,熟悉汇编语言,反汇编工具objdump以及gdb调试工具。

实验内容:

1、eflags标志位的查看。

2、backtrace指令学习。

3、炸弹实验第3、4关。

实验过程:

1、进入gdb调试命令,设置断点运行之前课上得到的hello文件,然后输入i r指令即可查看寄存器的内容,当然也包括eflags标志位寄存器的值。

32位CPU的标志位寄存器的主要标志位分布如下:

17

16

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

VM

RF

NT

IOPL

OF

DF

IF

TF

SF

ZF

AF

PF

CF

0

0

1

0

1

0

0

0

0

1

1

0

在上面我查出的标志位寄存器eflags的值为0x286转化为二进制形式即为001010000110,对应到相应位即可知道哪些标志位值为1,我们也可以通过例如

set eflags=0x206语句来设置标志位的值,至于你想要什么标志位值为1,则可以通过把上表中对应位的值置为1,再转化为16进制数来改变标志位的值。

2、backtrace指令可以查看程序所有函数的栈帧,简写为bt,以下显示的即为main函数和sum函数栈帧的返回地址。

也可以通过以下指令查看帧的详细信息:

3、

第三关:

1)、有了前面两关的经验,在过第三关的时候,一开始我就直接进入bomb文件的gdb调试界面,反汇编得到phase_3

函数的汇编代码,代码很长一次性显示不完全,回车即可接着显示余下的代码直到显示完(这里没有截完所有的图)。

观察整个phase_3函数的汇编代码,我发现它跟前面两关有一个相似之处,调用了两个函数,其中一个仍是爆炸函数,另一个是__isoc99_sscanf@plt

函数,现在猜不出这个函数要干嘛了,所以,我索性直接开始分析phase_3函数汇编代码,希望能发现一些线索。

2)、开始分析phase_3函数的反汇编代码:

首先是为函数准备堆栈,这里开辟了40个字节的内存。

然后加载%ebp-0x10的有效地址通过中间寄存器%eax传给%esp+0xc,同时也加载%ebp-0xc的有效地址通过中间寄存器%eax传给%esp+0x8

接着把地址0x804a23e中存储的值传给%esp+0x4处,再把%esp+0x8存储的值间接传给%esp,然后调用__isoc99_sscanf@plt

函数,到这里大概就可以猜测地址0x804a23e中存储的值和%esp+0x8存储的值即为函数__isoc99_sscanf@plt

的参数,此处即为准备参数阶段,根据前两关的经验,地址0x804a23e中存储的值即为第三关想要的通关密码。

3)、到目前为止,我自认为汇编代码分析到此处就可以顺利通关了,于是,我就打印出地址0x804a23e

处存储的值,然后验证是否为正确的密码,结果显示我失败了,想了一会,并没有想出个所以然,所以我接着分析汇编代码。

4)、接着把%eax存储的值和1作比较,改变标志位进行跳转,若%eax存储的值小于等于1,就会跳转到爆炸函数,引爆,反之,若大于1,则跳转到

处。

这里我在phase_3函数执行前(通过设置断点)查看了标志位,然后在执行完cmp $0x1,%eax语句后又查看了标志位,发现标志位有所改变以证实上述说法。

然后接着把%ebp-0xc处存储的值和7作比较,如果大于7就引爆(处为爆炸函数),如果小于等于7,就将地址为%ebp-0xc

处的值存到寄存器%eax中去。

接着无条件跳转到地址(0x804a1a0+4*%eax)存储的地址处,这其实是以0x804a1a0为基地址,4*%eax为步长进行跳转,典型的switch

语句,由于%eax的值未知但要小于7,姑且先假设为0,所以直接打印0x804a1a0处存储的地址值,以16进制显示。

现在来分析余下的代码,首先传 了个立即数给%eax,而后跳转到处执行如下操作:

%eax=0x314-0x35a+0x2ef-0x216+0x216-0x216+0x216-0x216=0x93=147,并把%eax赋值为0

,为之后的操作作准备,接着跳转到处,在这里参数1和5作了比较,限定了参数1必须要小于等于5。

5)、基于以上的分析,大概就可以找到规律了,%ebp-0xc处存储的值即为参数一,然后根据参数1的值改变(0x804a1a0+4*%eax

)处存储的值,跳转到不同的地址处以求解出参数2的值,这里参数1的范围为0~5。

在这里我验证了输入的参数为两个整数:

接着当参数1为1时,求得跳转地址为0x8048f19,分析跳转后的代码得:

%eax=0x0-0x35a+0x2ef-0x216+0x216+0x216+0x216-0x216=-641

之后依次更换参数1的值为2、3、4、5按照以上规律即可求得参数2的值,这里就不一一截图了。

根据上述跳转地址求得参数2的值:

参数1

2

3

4

5

参数2

217

-534

0

-534

依次验证这些参数组合的正确性:

全部通过,当然想要通关只需要6选1即可。

附phase_3函数的栈帧图:

以上,第三关即成功通过。

第四关:

1、查看phase_4函数的汇编代码,纵观全部的phase_4函数的汇编代码,发现此函数在phase_3函数的基础上多调用了一个func4函数。

2、分析整个函数的汇编代码,前半段仍是准备堆栈过程,然后是__isoc99_sscanf@plt函数的参数准备,有了第三关的经验,地址0x804a23e

里面存储的应该不会是本关的通关密码,按照老规矩查看里面存储的数据类型,发现仍旧是两个整型数据。

3、接下来通过比较%eax和2是否相等来判断输入的参数个数是否为两个,如果不是,则函数爆炸。

4、在输入的参数个数为2时,进行test指令,而后进行当符号位为1时的跳转,为了不跳转,则%eax要大于0。

5、接着把%eax和14进行比较,为了让程序跳转到处,而不是调用爆炸函数,则%eax要小于等于14,所以这里可以推出其中一个参数的范围是(0,14]

6、接下来为func4函数准备参数,参数1未知,参数2为0,参数3为14。

7、到这里,就得开始分析func4函数了,查看其汇编代码。

8、前部分堆栈准备,而后对传进来的三个参数做了一些操作。

下面是对应的计算过程,func4函数的初始化参数为n、0、14:

而后求得%ecx=7,把其与参数1作比较跳转到不同的代码段,以下是我的分析过程:

9、现在我们回到phase_4函数的剩余那部分代码,在调用完func4函数后,可以清晰的看到返回值为1,否则函数将跳转到处进而引发爆炸,紧接着,把

%ebp-0x10处的值与1比较,若相等,则结束,否则爆炸,由此可见此处存储的值为1,且由phase_4的栈帧图可以得到此处为输入的第二个参数。

Phase_4的栈帧图:

10、以上得到func4函数的返回值为1,根据第8步的分析可知,func4函数要想返回1,需通过参数1大于7的那段函数体求得,它的返回值为2*%eax+1

,由于这个func4是一个递归函数,所以,要想2*%eax+1=1,最快的方式就是底层调用的返回值为0且调用一次。

所以,倒推即可求得参数1为11:

11、接下来验证11和1的正确性:

结果显示,成功通关。

小结:

第三关主要考察的是switch语句,第四关主要考察的是递归调用,在第四关的炸弹拆除过程中,其实有一种简单快捷的方式,在未进入func4函数前已经把参数1

的取值范围分析出来了,参数2也分析出来,所以,可以组合它们逐个检验直到得到正确答案,这一关的答案也不只一个。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值