Bomb Lab实验报告.docx

上传人:b****5 文档编号:6429985 上传时间:2023-01-06 格式:DOCX 页数:22 大小:136.75KB
下载 相关 举报
Bomb Lab实验报告.docx_第1页
第1页 / 共22页
Bomb Lab实验报告.docx_第2页
第2页 / 共22页
Bomb Lab实验报告.docx_第3页
第3页 / 共22页
Bomb Lab实验报告.docx_第4页
第4页 / 共22页
Bomb Lab实验报告.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

Bomb Lab实验报告.docx

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

Bomb Lab实验报告.docx

BombLab实验报告

 

课程实验报告

 

课程名称:

计算机系统原理实验

实验名称:

BombLab

专业班级:

姓名:

学号:

完成时间:

2017.4.19

 

1、实验目的

熟悉汇编程序,学习gdb调试工具,熟悉并掌握函数调用过程中的栈帧结构的变化。

2、实验环境

个人PC,Linux发行版本,终端,gdb调试工具。

3、实验要求

1.本次实验为熟悉汇编程序及其调试方法的实验。

2.实验内容包含2个文件bomb(可执行文件)和bomb.c(c源文件)。

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

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

5.本实验一共有7个关卡,包括6个普通关卡和1个隐藏关卡。

要求至少通过6个普通关卡。

4、实验内容及操作步骤

(1)准备过程

1.解压文件夹得到“bomb”,“bomb.c”,“README-bomblab.txt”以及“实验基本内容与要求.txt”等文档。

查看“实验基本内容与要求.txt”了解实验内容与要求后打开bomb.c文件,编译发现不能通过,代码不完整,所以bomb.c文件只能用来作为参考。

查看bomb.c文件发现控制密码正确的6个函数分别为phase_1,phase_2,phase_3,phase_4,phase_5,phase_6,因此可以对bomb文件反汇编得到汇编文本,结合汇编文本与bomb.c文本进一步分析。

2.进入Ubuntu,将bom和bomb.c文档复制到主文件目录下,ctrl+alt+t打开终端,通过“objdump-dbomb>bomb.s”命令将可执行文件反汇编成bomb.s文件,并且可以通过“gdb-qbomb”进行调试。

3.将bomb.c复制成文本后打开bomb.c查看汇编代码并进一步分析。

(2)关卡分析

1.phase_1

phase_1汇编代码及注释如下:

08048f61:

8048f61:

55push%ebp

8048f62:

89e5mov%esp,%ebp

8048f64:

83ec18sub$0x18,%esp#开辟一个24位的栈空间

8048f67:

c74424045ca104movl$0x804a15c,0x4(%esp)#将0x804a15c存到%eap+4的位置,x/s0x804a15c得到"WehavetostandwithourNorthKoreanallies."

8048f6e:

08

8048f6f:

8b4508mov0x8(%ebp),%eax

8048f72:

890424mov%eax,(%esp)#将%ebp+8处的值存到%esp

8048f75:

e831000000call8048fab

8048f7a:

85c0test%eax,%eax

8048f7c:

7405je8048f83#%eax=0则跳出函数,否则跳到爆炸函数,可以看出,调用函数后如果两个字符串相等的话最后%eax会等于0

8048f7e:

e84e010000call80490d1

8048f83:

c9leave

8048f84:

c3ret

8048f85:

90nop

8048f86:

90nop

8048f87:

90nop

8048f88:

90nop

8048f89:

90nop

8048f8a:

90nop

8048f8b:

90nop

8048f8c:

90nop

8048f8d:

90nop

8048f8e:

90nop

8048f8f:

90nop

思路与分析:

通过call8048fab我们可以推断要求输入的是一串字符串,movl$0x804a15c,0x4(%esp)将地址0x804a15c存到%esp+4的位置,mov0x8(%ebp),%eax和mov%eax,(%esp)将输入的字符串存到%esp中,call8048fab调用字符串比较函数,通过比较上面位置参数%esp+4与%esp对应的字符串是否相等,将返回值存到%eax中,test%eax,%eax,je8048f83,call80490d1,判断如果两个字符串不相等则爆炸。

由上面分析可知地址0x804a15c中存着正确的字符串,我们只要输入相同的字符串就可以通过关卡。

进入gdb,通过命令x/s0x804a15c查看该字符串为:

"WehavetostandwithourNorthKoreanallies."

所以phase_1的通关密码为:

"WehavetostandwithourNorthKoreanallies."通过r命令运行程序,输入该字符串则通过第一关:

结论与心得:

通过分析汇编代码,通过字符串比较函数可以推测输入的是一串字符串,通过x/s以字符串的形式查看地址0x804a15c所对应的值,运行程序后输入该字符串即可通过关卡。

字符串比较函数主要是通过将两个字符串进行比较,将结果存到%eax中,最后判断%eax的值。

第一关相对比较简单,也比较好理解。

2.phase_2

phase_2汇编代码及注释如下:

08048d6a:

8048d6a:

55push%ebp

8048d6b:

89e5mov%esp,%ebp

8048d6d:

56push%esi

8048d6e:

53push%ebx

8048d6f:

83ec30sub$0x30,%esp

8048d72:

8d45e0lea-0x20(%ebp),%eax

8048d75:

89442404mov%eax,0x4(%esp)#将第一个数字的地址放到%esp+4的位置

8048d79:

8b4508mov0x8(%ebp),%eax

8048d7c:

890424mov%eax,(%esp)

8048d7f:

e887030000call804910b#读取六个数字

8048d84:

837de000cmpl$0x0,-0x20(%ebp)

8048d88:

7506jne8048d90#0和-0x20(%ebp)比较,不相等就爆炸

8048d8a:

837de401cmpl$0x1,-0x1c(%ebp)

8048d8e:

7405je8048d95#1和-0x1c(%ebp)比较,相等就跳过爆炸

8048d90:

e83c030000call80490d1

8048d95:

8d5de8lea-0x18(%ebp),%ebx#将第三个数字的地址传到%ebx中,即现在%ebx中存着第三个数字的地址

8048d98:

8d75f8lea-0x8(%ebp),%esi#将%ebx的地址传到%esi,%esi用于待会的判断结束条件,%ebx存的地址一直循环加4,循环直到%ebx的下一个地址是%esi就结束】

8048d9b:

8b43fcmov-0x4(%ebx),%eax#将第二个数放到%eax寄存器中

8048d9e:

0343f8add-0x8(%ebx),%eax#计算第二个数和第一个数的和

8048da1:

3903cmp%eax,(%ebx)

8048da3:

7405je8048daa#前两个数的和与第三个数相比较,相等则跳过炸弹

8048da5:

e827030000call80490d1

8048daa:

83c304add$0x4,%ebx#将%ebx的地址加4,现在%ebx中存着第四个数字的地址

8048dad:

39f3cmp%esi,%ebx

8048daf:

75eajne8048d9b#比较现在%esi和%ebx里面的值是否相等,不相等则循环,否则结束。

其实两个寄存器中存的都是地址,为的是保证只输入6个数,因为当输入第7个数时,%ebx=%esi

8048db1:

83c430add$0x30,%esp

8048db4:

5bpop%ebx

8048db5:

5epop%esi

8048db6:

5dpop%ebp#释放栈帧

8048db7:

c3ret

思路与分析:

通过call804910b我们可以推断出应该是要输入6个数字。

通过对汇编代码进行分析知道-0x20(%ebp)存着第一个数字,-0x1c(%ebp)存着第二个数字,依次类推。

通过cmpl$0x0,-0x20(%ebp),jne8048d90和cmpl$0x1,-0x1c(%ebp),je8048d95知道第一个数字必须是0,第二个数字必须是1,否则就爆炸。

命令lea-0x18(%ebp),%ebx初始化寄存器%ebx的值,将第三个数字的地址传到%ebx中.lea-0x8(%ebp),%esi将%ebx的地址传到%esi,%esi用于待会的判断结束条件,%ebx存的地址一直循环加4,循环直到%ebx的下一个地址是%esi就结束,mov-0x4(%ebx),%eax将第二个数放到%eax寄存器中,add-0x8(%ebx),%eax计算第二个数和第一个数的和,cmp%eax,(%ebx),je8048daa前两个数的和与第三个数相比较,相等则跳过炸弹。

add$0x4,%ebx将%ebx的地址加4,现在%ebx中存着第四个数字的地址,之后%ebx一直加4,知道循环完6个数字。

通过上面的分析知道,输入的前两个数字为0和1,后面的数字等于前面两个数字的和。

所以,这六个数字为Fibonacci数列的前六项。

为011235。

输入这6个数字可通过phase_2.

结论与心得:

第二关需要弄懂栈帧结构的变化,通过add$0x4,%ebx将%ebx的地址加4,然后判断前两个数字的和与当前位置的数是否相等。

结合第一个和第二个数字是0和1知道结果为011235。

3.phase_3

phase_3汇编代码及注释如下:

08048ea1:

8048ea1:

55push%ebp

8048ea2:

89e5mov%esp,%ebp

8048ea4:

83ec28sub$0x28,%esp

8048ea7:

8d45f0lea-0x10(%ebp),%eax#第二个数的位置

8048eaa:

8944240cmov%eax,0xc(%esp)

8048eae:

8d45f4lea-0xc(%ebp),%eax#第一个数的位置

8048eb1:

89442408mov%eax,0x8(%esp)

8048eb5:

c74424043ea204movl$0x804a23e,0x4(%esp)#通过查看0x804a23e的内容,即x/s0x804a23e,显示为"%d%d",提示输入两个整型数

8048ebc:

08

8048ebd:

8b4508mov0x8(%ebp),%eax

8048ec0:

890424mov%eax,(%esp)

8048ec3:

e878f9ffffcall8048840<__isoc99_sscanf@plt>#isoc99标准输入变量,应该是把输入的数字个数存在%eax里

8048ec8:

83f801cmp$0x1,%eax

8048ecb:

7f05jg8048ed2#至少输入2个数,否则爆炸

8048ecd:

e8ff010000call80490d1

8048ed2:

837df407cmpl$0x7,-0xc(%ebp)

8048ed6:

776bja8048f43#第1个数大于7爆炸,所以,第一个数需要小于等于7

8048ed8:

8b45f4mov-0xc(%ebp),%eax将第一个数存到%eax中

8048edb:

ff2485a0a10408jmp*0x804a1a0(,%eax,4)#跳转至0x804a1a0+4*%eax(存放第一个数)中的内容所指的行数p/x*0x804a1a0+4*%eax

8048ee2:

b800000000mov$0x0,%eax

8048ee7:

eb53jmp8048f3c

8048ee9:

b800000000mov$0x0,%eax

8048eee:

6690xchg%ax,%ax

8048ef0:

eb45jmp8048f37

8048ef2:

b800000000mov$0x0,%eax#第一个数等于5的时候跳到这里

8048ef7:

eb39jmp8048f32

8048ef9:

b800000000mov$0x0,%eax#第一个数等于4的时候跳到这里

8048efe:

6690xchg%ax,%ax

8048f00:

eb2bjmp8048f2d

8048f02:

b800000000mov$0x0,%eax#第一个数等于4的时候跳到这里

8048f07:

eb1fjmp8048f28

8048f09:

b800000000mov$0x0,%eax#第一个数等于2的时候跳到这里

8048f0e:

6690xchg%ax,%ax

8048f10:

eb11jmp8048f23

8048f12:

b814030000mov$0x314,%eax#第一个数为0的时候跳到这里(p/x*0x804a1a0)首先x=778,最后第二个数等于147

8048f17:

eb05jmp8048f1e#跳转到8048f1e这一行

8048f19:

b800000000mov$0x0,%eax#第一个数等于1的时候跳到这里

8048f1e:

2d5a030000sub$0x35a,%eax#x=x-858

8048f23:

05ef020000add$0x2ef,%eax#x=x+751

8048f28:

2d16020000sub$0x216,%eax#x=x-534

8048f2d:

0516020000add$0x216,%eax#x=x+534

8048f32:

2d16020000sub$0x216,%eax#x=x-534

8048f37:

0516020000add$0x216,%eax#x=x+534

8048f3c:

2d16020000sub$0x216,%eax#x=x-534

8048f41:

eb0ajmp8048f4d#跳转到8048f4d这一行

8048f43:

e889010000call80490d1

8048f48:

b800000000mov$0x0,%eax

8048f4d:

837df405cmpl$0x5,-0xc(%ebp)

8048f51:

7f05jg8048f58#第一个数字需要小于等于5,否则爆炸

8048f53:

3b45f0cmp-0x10(%ebp),%eax

8048f56:

7405je8048f5d#0,147;1-641;2,217;3,-534;4,0;5,-534

8048f58:

e874010000call80490d1

8048f5d:

c9leave

8048f5e:

6690xchg%ax,%ax

8048f60:

c3ret

思路与分析:

观察到指令movl$0x804a23e,0x4(%esp),通过查看0x804a23e的内容,即x/s0x804a23e,显示为"%d%d",提示输入两个整型数。

call8048840<__isoc99_sscanf@plt>,调用isoc99标准输入变量,是把输入的数字个数存在%eax里返回。

通过cmp$0x1,%eax和jg8048ed2知道至少输入2个数,否则爆炸。

通过cmpl$0x7,-0xc(%ebp)和ja8048f43知道第一个数字小于等于7,由cmpl$0x5,-0xc(%ebp)和jg8048f58知道输入的数字要小于等于5,所以输入的数字范围为0-5。

jmp*0x804a1a0(,%eax,4)为switch分支结构,%eax存着输入的数字的值,当输入的数组是0的时候,,查看*0x804a1a0的值,得到$1=0x8048f12,即跳转到0x8048f12处。

当输入的数字为1-5时依次类推。

得到的地址分别为:

cmp-0x10(%ebp),%eax和je8048f5d即为判断经过一系列运算后求的值是否与正确的值相等。

通过分析汇编代码,我们可以知道当输入不同的x值,等到的y值如下:

当x=0时,y=788-858+751-534+534-534+534-534=147

当x=1时,y=-858+751-534+534-534+534-534=-641

当x=2时,y=751-534+534-534+534-534=217

当x=3时,x=-534+534-534+534-534=-534

当x=4时,x=534-534+534-534=0

当x=5时,x=-534+534-534=-534

所以可以输入六组数据:

0147;1-641;2217;3-534;40;5-534。

随便输入一组都能通过炸弹。

结论与心得:

第三关主要用到了switch分支结构,根据输如的不同数字跳转到不同位置进行不同的运算,最后得到结果。

首先分析输入数字的范围,然后通过判断跳转的位置来准确计算。

4.phase_4

phase_4汇编代码及注释如下:

08048e2e:

8048e2e:

55push%ebp

8048e2f:

89e5mov%esp,%ebp

8048e31:

83ec28sub$0x28,%esp#开辟栈空间

8048e34:

8d45f0lea-0x10(%ebp),%eax#第二个数字

8048e37:

8944240cmov%eax,0xc(%esp)

8048e3b:

8d45f4lea-0xc(%ebp),%eax#第一个数字

8048e3e:

89442408mov%eax,0x8(%esp)

8048e42:

c74424043ea204movl$0x804a23e,0x4(%esp)#输入x/s0x804a23e显示为"%d%d",提示输入两个整型数字

8048e49:

08

8048e4a:

8b4508mov0x8(%ebp),%eax

8048e4d:

890424mov%eax,(%esp)

8048e50:

e8ebf9ffffcall8048840<__isoc99_sscanf@plt>#标准输入变量,将输入的数字个数存在%eax中

8048e55:

83f802cmp$0x2,%eax

8048e58:

750cjne8048e66#要求输入2个数字,即输入的数字个数不等于2则爆炸

8048e5a:

8b45f4mov-0xc(%ebp),%eax#将第一个数放到%eax中

8048e5d:

85c0test%eax,%eax

8048e5f:

7805js8048e66#判断第一个数,如果是负数就爆炸,所以需要%eax>=0

8048e61:

83f80ecmp$0xe,%eax

8048e64:

7e05jle8048e6b#比较第一个数和14(0xe)的大小,如果%eax<=14,则继续执行,否则爆炸

8048e66:

e866020000call80490d1

8048e6b:

c74424080e0000movl$0xe,0x8(%esp)#将0xe存到%esp+8

8048e72:

00

8048e73:

c7442404000000movl$0x0,0x4(%esp)#将0x0存到%esp+4

8048e7a:

00

8048e7b:

8b45f4mov-0xc(%ebp),%eax

8048e7e:

89042

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

当前位置:首页 > 考试认证 > 其它考试

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

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