LAB boom实验报告.docx

上传人:b****4 文档编号:4069147 上传时间:2022-11-27 格式:DOCX 页数:16 大小:1.03MB
下载 相关 举报
LAB boom实验报告.docx_第1页
第1页 / 共16页
LAB boom实验报告.docx_第2页
第2页 / 共16页
LAB boom实验报告.docx_第3页
第3页 / 共16页
LAB boom实验报告.docx_第4页
第4页 / 共16页
LAB boom实验报告.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

LAB boom实验报告.docx

《LAB boom实验报告.docx》由会员分享,可在线阅读,更多相关《LAB boom实验报告.docx(16页珍藏版)》请在冰豆网上搜索。

LAB boom实验报告.docx

LABboom实验报告

实验题目:

bomblab

实验目的:

熟悉汇编程序及其调试方法,熟悉BGD工具

实验环境:

个人电脑,Linux系统(虚拟机)

实验内容及操作步骤:

实验内容:

程序运行在linux环境中,程序运行中有6个关卡,每个phase需要用户在终端上输入特定的字符或者数字才能通关,否则会引爆炸弹。

需要使用gdb工具反汇编出汇编代码,结合c语言文件找到每个关卡的入口函数。

然后分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。

实验需要用到gdb工具,可到网上查找gdb使用方法和参数。

操作步骤:

1、打开终端进入bomb文件夹开始进行实验,反汇编出代码,这里有两种方式可以反汇编,第一种用命令行objdump-dbomb>1.txt,如下图:

第二种反汇编方式就是用gdb工具,首先gdbbomb进入gdb工具的调试状态然后输入命令“disas所要返回的函数名”即可得到函数的汇编代码。

2、拆除炸弹

Phase1:

汇编代码

当判断%eax的结果如果不为0的话就会调用call0x80490d1也就是说会爆炸,所以函数strings_not_equal的返回值为0由这个函数名可联想到函数的功能是比较字符串,“字符串不相同”返回值为0证明字符串相同,再往上movl$0x804a15c,0x4(%esp)这里有立即数,按照刚才的分析这应该是一个字符串所以我们在gdb状态下用x/s0x804a15c查看出现字符串"WehavetostandwithourNorthKoreanallies."这就应该是我们所要输入的字符串了。

我们可以先调试一下,在explode_bomb入口0x80490d1设断点,再进行run操作。

Phase2:

汇编代码

首先看到了call0x804910b所以可以猜测这道关可能是要输入6个数字,所以先把汇编代码弄出来。

事实上经过过程的分析我们确实需要输入6个数字并且存储在-0x20(%ebp)到-0xc(%ebp)的位置上,由上述的代码所给出的注释可以得到第一个数为0第二个为1,然后代码进入一个循环,这个循环所表达的意思就是第3个数字等于前两个数字的和也就是1,第四个数字等于第2个和第3个数字的和,以此类推,我们得到这6个数字分别为011235.验证结果如下:

Phase3:

汇编代码

调用sscanf函数

看到0x08048eb5<+20>:

movl$0x804a23e,0x4(%esp)这行代码,又是一个立即数。

同样我们查看地址中的值再结合后面语句中有调用__isoc99_sscanf@plt函数,说明这是要我们输入两个整型值。

注:

sscanf的功能是sscanf(),从一个字符串中读进与指定格式相符的数据。

它的返回值为被成功赋值的指针变量的个数,如果该函数发生错误,则返回EOF(-1)

根据sscanf的返回值判断可知所输入的值得个数大于1,也就验证上面所说的输入两个整型数值,后面的语句有判断了输入的第一个数值小于7。

接下来的语句0x08048edb<+58>:

jmp*0x804a1a0(,%eax,4)典型的switch跳转语句,跳转到以0x804a1a0为基址的跳转表中输入p/x*0x804a1a0得到地址0x8048f12,也就是输入0的时候程序会跳转到0x8048f12<+113>的地方执行。

在代码中找到这个地址,从这个地址继续执行将0x314赋给%eax然后跳转到0x08048f1e<+125>

以下的操作就是0x314-0x35a+0x2ef-0x216+0x216-0x216+0x216-0x216结果为147

cmp-0x10(%ebp),%eax这个语句说明147就是我们所要输入的第二个参数。

验证结果如下:

Phase4:

汇编代码

根据0x08048e42<+20>:

movl$0x804a23e,0x4(%esp),我们查看0x804a23e的值结果为:

再根据语句0x08048e50<+34>:

call0x8048840<__isoc99_sscanf@plt>

0x08048e55<+39>:

cmp$0x2,%eax

说明我们要输入两个整型数,下面的工作就是判断这两个整型数分别是什么。

由代码

0x08048e6b<+61>:

movl$0xe,0x8(%esp)

0x08048e73<+69>:

movl$0x0,0x4(%esp)

0x08048e7b<+77>:

mov-0xc(%ebp),%eax

0x08048e7e<+80>:

mov%eax,(%esp)

可以看出我们以第一个参数,0,14为参数传入递归函数中而且返回值为1,所以我们这时做的事情就是分析func4函数,看第一个参数为多少时返回值能为1,而第二个参数有代码

0x08048e8b<+93>:

cmpl$0x1,-0x10(%ebp)

0x08048e8f<+97>:

je0x8048e9d

可知第二个参数就为1。

下面分析func4

根据判断条件jle0x8048ba0和jge0x8048bc0可知这个函数就是参数2和参数3经过一系列的操作最终等于参数1。

参数1在这个过程中是不变的。

我们第一次传入func4的参数为参数1,0,14,结果返回值要求为1,也就是%eax的值为1,我用的是反向推理的方法。

首先如果使返回值为1,根据

0x08048bbc<+92>:

lea0x1(%eax,%eax,1),%eax

这条语句我们可以使这条语句为最后返回的值也就是说我们第一次调用func4是在

0x08048bb7<+87>:

call0x8048b60

那么就是说参数1大于7,在此条件下我们将(9,8,14)传入再次调用func4,调用func4后我们希望它的返回值为0这样根据0x1(%eax,%eax,1),%eax返回值就是1了,最简单的一种情况就是14和8经过运算后结果为11而参数1恰好等于11的情况,更复杂一些的情况就是它又调用了0x08048b97<+55>:

call0x8048b60,再由它的返回值再继续推理,所以此题有多种答案,最简单的就是11,1。

Phase5:

汇编代码

Dumpofassemblercodeforfunctionphase_5:

0x08048db8<+0>:

push%ebp

0x08048db9<+1>:

mov%esp,%ebp

0x08048dbb<+3>:

push%esi

0x08048dbc<+4>:

push%ebx

0x08048dbd<+5>:

sub$0x20,%esp

0x08048dc0<+8>:

lea-0x10(%ebp),%eax

0x08048dc3<+11>:

mov%eax,0xc(%esp)

0x08048dc7<+15>:

lea-0xc(%ebp),%eax

0x08048dca<+18>:

mov%eax,0x8(%esp)

0x08048dce<+22>:

movl$0x804a23e,0x4(%esp)

0x08048dd6<+30>:

mov0x8(%ebp),%eax

0x08048dd9<+33>:

mov%eax,(%esp)

0x08048ddc<+36>:

call0x8048840<__isoc99_sscanf@plt>

0x08048de1<+41>:

cmp$0x1,%eax//所输入的值的个数应该大于1

0x08048de4<+44>:

jg0x8048deb

0x08048de6<+46>:

call0x80490d1

0x08048deb<+51>:

mov-0xc(%ebp),%eax

0x08048dee<+54>:

and$0xf,%eax//将%eax中的值与0xf做逻辑与运算

0x08048df1<+57>:

mov%eax,-0xc(%ebp)//将相与后的结果传入地址-0xc(%ebp)

0x08048df4<+60>:

cmp$0xf,%eax//比较%eax中的值,结果不能等于15

0x08048df7<+63>:

je0x8048e22

0x08048df9<+65>:

mov$0x0,%ecx

0x08048dfe<+70>:

mov$0x0,%edx

0x08048e03<+75>:

mov$0x804a1c0,%ebx//将数组的首地址中的值传入%edx

0x08048e08<+80>:

add$0x1,%edx//进入循环

0x08048e0b<+83>:

mov(%ebx,%eax,4),%eax//将数组中第%eax位置的值传

给%eax

0x08048e0e<+86>:

add%eax,%ecx//将每次%eax的值累加起来

0x08048e10<+88>:

cmp$0xf,%eax//比较%eax和15若等于则跳出循环

0x08048e13<+91>:

jne0x8048e08

0x08048e15<+93>:

mov%eax,-0xc(%ebp)//将得到的%eax的值传入-0xc(%ebp)

0x08048e18<+96>:

cmp$0xf,%edx//比较%edx和15,如不等于会bomb!

所以

循环以后%edx必定等于15

0x08048e1b<+99>:

jne0x8048e22

0x08048e1d<+101>:

cmp%ecx,-0x10(%ebp)//我们所输入的第二个参数的值

等于循环之后%ecx的结果,也就是数组中15个值累加的结果

0x08048e20<+104>:

je0x8048e27

0x08048e22<+106>:

call0x80490d1

0x08048e27<+111>:

add$0x20,%esp

0x08048e2a<+114>:

pop%ebx

0x08048e2b<+115>:

pop%esi

0x08048e2c<+116>:

pop%ebp

0x08048e2d<+117>:

ret

与phase3相同0x08048dce<+22>:

movl$0x804a23e,0x4(%esp)我们查看这个语句中地址的值得到“%d,%d”结合语句

0x08048ddc<+36>:

call0x8048840<__isoc99_sscanf@plt>

0x08048de1<+41>:

cmp$0x1,%eax

说明和phase3一样我们需要输入两个整型数,下面的工作就是确定整型数的值,首先取我们所要输入的第一个参数的后四位,如果它的后四位全为1那么就会爆炸,所以后四位不可能全为1.接着就是一个循环的过程了,这个循环我们可以尝试写成c代码来解决c代码如下:

intc=0;

intd=0;

intb=a[0];

While(a[n]!

=15)

{

d++;

n=a[n];

c=c+n;

}

根据0x08048e18<+96>:

cmp$0xf,%edx我们知道c代码中的d在最后循环结束时的值为15,也就是循环要进行15次,根据

0x08048e1d<+101>:

cmp%ecx,-0x10(%ebp)

最后c的值就是第二个参数。

而第一个参数在取后四位之后循环之后的结果是15。

看到循环中的0x08048dce<+22>:

movl$0x804a23e,0x4(%esp)语句我最开始想到的是又是一个立即数所以我查看了它的值发现如下图所示,,加上

0x08048e0b<+83>:

mov(%ebx,%eax,4),%eax

我联想到这是一个数组,0x804a1c0是数组的首地址,我们用p/x*(0x804a1c0)@16来查看这个数组。

如下图所示:

根据最后的%eax的值15来推出最开始的值,我们可以根据n=a[n]来:

n=a[n]=15n=a[n]=6n=a[n]=14n=a[n]=2n=a[n]=1n=a[n]=10n=a[n]=0n=a[n]=8n=a[n]=4n=a[n]=9n=a[n]=13n=a[n]=11n=a[n]=7n=a[n]=3n=a[n]=12****

n=a[n]=5实际上循环执行了15次也就是第一次迭代n所得到的值是12,那么此时传进的n是5也就是第一个参数的后4位就是0101也就是5,而第二个参数等于这15个过程的累加也就是115,。

第一个参数后四位为5的之都可以,最后我选择的参数是5,115,验证过程如图所示:

再试一个53115

Phase6:

汇编代码

%eax值小于6

两参数值不同

<+27>到<+91>判断6个参数每个都小于等于6并且互不相同。

%edx的值必须大于%eax中的值

<+147>到<+177>将-0x48(%ebp)到-0x34(%ebp)的值按照距离为0x8的地址排列起来。

<+180>到<+224>排列的六个值是递减的也就是说-0x48(%ebp),中的值大于-0x44(%ebp)的值大于-0x40(%ebp)以此类推。

实验结果:

 

收获与体会:

我觉得此次试验主要考察的是对汇编代码的理解以及gdb工具的使用。

开始的时候面对汇编代码很惧怕特别是像3和6这长代码,对一些语句也不是很理解,绕来绕去的循环递归也很让人头疼,不过参考了老师给的资料以及网上一些大神的报告,对照着看过几个函数后就上手一些了,也不至于无从下手了。

我觉得这是一个很有意思的实验,拆炸弹的过程中虽然有些代码很长很无聊,但是拆好了后感觉很棒,也能从中找出规律来,比如说看到这一个函数该从哪里入手,像是还有立即数的传入都可能是我们入手的切点还有对于有些代码从后向前推更容易解出,还有很多时候你不知道这一条语句是什么意思,这时候不必纠结于这一条,也许结合后面就能明白它的意思。

经过此次试验感觉自己对汇编代码更为熟悉了也了解和使用了gdb工具。

当然,少不了同学的帮助。

验成绩

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1