升入理解计算机系统BombLAB实验报告资料.docx

上传人:b****5 文档编号:6473901 上传时间:2023-01-06 格式:DOCX 页数:15 大小:149.30KB
下载 相关 举报
升入理解计算机系统BombLAB实验报告资料.docx_第1页
第1页 / 共15页
升入理解计算机系统BombLAB实验报告资料.docx_第2页
第2页 / 共15页
升入理解计算机系统BombLAB实验报告资料.docx_第3页
第3页 / 共15页
升入理解计算机系统BombLAB实验报告资料.docx_第4页
第4页 / 共15页
升入理解计算机系统BombLAB实验报告资料.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

升入理解计算机系统BombLAB实验报告资料.docx

《升入理解计算机系统BombLAB实验报告资料.docx》由会员分享,可在线阅读,更多相关《升入理解计算机系统BombLAB实验报告资料.docx(15页珍藏版)》请在冰豆网上搜索。

升入理解计算机系统BombLAB实验报告资料.docx

升入理解计算机系统BombLAB实验报告资料

 

湖南大学课程实验报告

 

课程名称:

计算机组成与结构

实验项目名称:

二进制炸弹

专业班级:

姓名:

学号:

指导教师:

完成时间:

 

计算机科学与工程系

实验题目:

APPBombLab

实验目的:

实验环境:

linux,终端,gdb工具

实验内容及操作步骤:

查看给出的bomb.c中的代码,得知控制检测密码正误的6个函数分别为:

phase_1,phase_2,phase_3,phase_4,phase_5,phase_6。

使用gbd工具对可执行文件bomb进行反汇编:

得到六段汇编代码,将其复制成文本后,对其进行分析,

phase_1代码:

0x08048f61<+0>:

push%ebp

0x08048f62<+1>:

mov%esp,%ebp

0x08048f64<+3>:

sub$0x18,%esp

0x08048f67<+6>:

movl$0x804a15c,0x4(%esp)将esp寄存器地址指向$0x804a15c

0x08048f6f<+14>:

mov0x8(%ebp),%eax将$0x804a15c中的数据移给eax寄存器

0x08048f72<+17>:

mov%eax,(%esp)

0x08048f75<+20>:

call0x8048fab

0x08048f7a<+25>:

test%eax,%eax上一行与这一行比较用户输入和$0x804a15c中的值

0x08048f7c<+27>:

je0x8048f83

0x08048f7e<+29>:

call0x80490d1

0x08048f83<+34>:

leave

0x08048f84<+35>:

ret

可以看出,phase_1的密码是固定储存在$0x804a15c中的。

令$0x804a15c中的数据与用户输入的数据比较,若相同则跳过explode_bomb,避开炸弹。

用命令x/s0x804a15c查看其中的数据如下

因此知道第一个密码为:

WehavetostandwithourNorthKoreanallies.

phase_2代码:

0x08048d6a<+0>:

push%ebp

0x08048d6b<+1>:

mov%esp,%ebp

0x08048d6d<+3>:

push%esi

0x08048d6e<+4>:

push%ebx

0x08048d6f<+5>:

sub$0x30,%esp

0x08048d72<+8>:

lea-0x20(%ebp),%eax

0x08048d75<+11>:

mov%eax,0x4(%esp)

0x08048d79<+15>:

mov0x8(%ebp),%eax

0x08048d7c<+18>:

mov%eax,(%esp)

0x08048d7f<+21>:

call0x804910b读取六个数字

0x08048d84<+26>:

cmpl$0x0,-0x20(%ebp)0和第一个数字比较,不相等则爆炸。

0x08048d88<+30>:

jne0x8048d90

0x08048d8a<+32>:

cmpl$0x1,-0x1c(%ebp)1和第二个数字比较,相等则跳过爆炸。

0x08048d8e<+36>:

je0x8048d95

0x08048d90<+38>:

call0x80490d1

0x08048d95<+43>:

lea-0x18(%ebp),%ebxebx指向第三个数字。

0x08048d98<+46>:

lea-0x8(%ebp),%esiesi指向第六个数字再向后移一位的地址。

0x08048d9b<+49>:

mov-0x4(%ebx),%eaxebx向前第一位的数字赋给eax。

0x08048d9e<+52>:

add-0x8(%ebx),%eaxeax再加上ebx向前第二位的数字。

0x08048da1<+55>:

cmp%eax,(%ebx)比较ebx前两位的和与ebx指向的数字。

0x08048da3<+57>:

je0x8048daa相等则跳过爆炸(explode_bomb)

0x08048da5<+59>:

call0x80490d1

0x08048daa<+64>:

add$0x4,%ebxebx地址向后移动一位(四个字节)。

0x08048dad<+67>:

cmp%esi,%ebx如果还未超过第六位数字,则跳转到0x8048d9b行。

0x08048daf<+69>:

jne0x8048d9b

0x08048db1<+71>:

add$0x30,%esp

0x08048db4<+74>:

pop%ebx

0x08048db5<+75>:

pop%esi

0x08048db6<+76>:

pop%ebp

0x08048db7<+77>:

ret

从上面的代码分析中可以知道,phase_2的密码有六个数字,第一个是0,第二个是1,然后之后的每位都是前两位的和,即斐波拉契数列的前6位。

所以密码是:

011235。

phase_3代码:

0x08048ea1<+0>:

push%ebp

0x08048ea2<+1>:

mov%esp,%ebp

0x08048ea4<+3>:

sub$0x28,%esp

0x08048ea7<+6>:

lea-0x10(%ebp),%eax

0x08048eaa<+9>:

mov%eax,0xc(%esp)此处为第二个数字。

0x08048eae<+13>:

lea-0xc(%ebp),%eax

0x08048eb1<+16>:

mov%eax,0x8(%esp)此处为第一个数字。

0x08048eb5<+20>:

movl$0x804a23e,0x4(%esp)用x/s0x804a23e命令查看$0x804a23e为

0x08048ebd<+28>:

mov0x8(%ebp),%eax%d%d,即要输入两个整数,上面已经指出。

0x08048ec0<+31>:

mov%eax,(%esp)

0x08048ec3<+34>:

call0x8048840<__isoc99_sscanf@plt>

0x08048ec8<+39>:

cmp$0x1,%eax以上两行即要求输入至少两组数据,否则引爆。

0x08048ecb<+42>:

jg0x8048ed2

0x08048ecd<+44>:

call0x80490d1

0x08048ed2<+49>:

cmpl$0x7,-0xc(%ebp)第一个数大于7引爆,即第一个数小于等于7。

0x08048ed6<+53>:

ja0x8048f43

0x08048ed8<+55>:

mov-0xc(%ebp),%eax

0x08048edb<+58>:

jmp*0x804a1a0(,%eax,4)跳转至0x804a1a0+eax*4(第一个数)内数据所

0x08048ee2<+65>:

mov$0x0,%eax指的行数。

0x08048ee7<+70>:

jmp0x8048f3c

0x08048ee9<+72>:

mov$0x0,%eax

0x08048eee<+77>:

xchg%ax,%ax

0x08048ef0<+79>:

jmp0x8048f37

0x08048ef2<+81>:

mov$0x0,%eax

0x08048ef7<+86>:

jmp0x8048f32

0x08048ef9<+88>:

mov$0x0,%eax

0x08048efe<+93>:

xchg%ax,%ax

0x08048f00<+95>:

jmp0x8048f2d

0x08048f02<+97>:

mov$0x0,%eax

0x08048f07<+102>:

jmp0x8048f28

0x08048f09<+104>:

mov$0x0,%eax

0x08048f0e<+109>:

xchg%ax,%ax

0x08048f10<+111>:

jmp0x8048f23

0x08048f12<+113>:

mov$0x314,%eax当第一个数为0时跳转到此处,第二个数x=788。

0x08048f17<+118>:

jmp0x8048f1e跳转到0x8048f1e。

0x08048f19<+120>:

mov$0x0,%eax

0x08048f1e<+125>:

sub$0x35a,%eaxx=x-858

0x08048f23<+130>:

add$0x2ef,%eaxx=x+751

0x08048f28<+135>:

sub$0x216,%eaxx=x-534

0x08048f2d<+140>:

add$0x216,%eaxx=x+534

0x08048f32<+145>:

sub$0x216,%eaxx=x-534

0x08048f37<+150>:

add$0x216,%eaxx=x+534

0x08048f3c<+155>:

sub$0x216,%eaxx=x-534

0x08048f41<+160>:

jmp0x8048f4d跳转到0x8048f4d行。

0x08048f43<+162>:

call0x80490d1

0x08048f48<+167>:

mov$0x0,%eax

0x08048f4d<+172>:

cmpl$0x5,-0xc(%ebp)第一个数大于5引爆,即第一个数小于等于5。

0x08048f51<+176>:

jg0x8048f58

0x08048f53<+178>:

cmp-0x10(%ebp),%eax第一个数是0时,算得x=147,即第二个数

0x08048f56<+181>:

je0x8048f5d为147。

0x08048f58<+183>:

call0x80490d1

0x08048f5d<+188>:

leave

0x08048f5e<+189>:

xchg%ax,%ax

0x08048f60<+191>:

ret

由以上分析可以得到,我们需要输入两个数,储存在%ebx-16和%edx-12中,%edx为输入的第一个数据,由0x08048f4d<+172>:

cmpl$0x5,-0xc(%ebp)可以判断第一个数输入不能大于5,即可以输入6组数据0,1,2,3,4,5,他们应该分别对应一个%edx-16的值!

假设第二个一个输入的数为x:

当输入第一个数为0时,x=788-858+751-534+534-534+534-534=147

当输入第一个数为1时,x=-858+751-534+534-534+534-534=-641

当输入第一个数为2时,x=751-534+534-534+534-534=217

当输入第一个数为3时,x=-534+534-534+534-534=-534

当输入第一个数为4时,x=534-534+534-534=0

当输入第一个数为5时,x=-534+534-534=-534

所以,可以输入的六组数据分别为:

0,1471,-6412,2173,-5344,05,-534

phase_4代码:

0x08048e2e<+0>:

push%ebp

0x08048e2f<+1>:

mov%esp,%ebp

0x08048e31<+3>:

sub$0x28,%esp

0x08048e34<+6>:

lea-0x10(%ebp),%eax

0x08048e37<+9>:

mov%eax,0xc(%esp)此处第二段数字。

0x08048e3b<+13>:

lea-0xc(%ebp),%eax

0x08048e3e<+16>:

mov%eax,0x8(%esp)此处第一段数字。

0x08048e42<+20>:

movl$0x804a23e,0x4(%esp)$0x804a23e内为%d%d,即输入两个整数。

0x08048e4a<+28>:

mov0x8(%ebp),%eax

0x08048e4d<+31>:

mov%eax,(%esp)

0x08048e50<+34>:

call0x8048840<__isoc99_sscanf@plt>

0x08048e55<+39>:

cmp$0x2,%eax以上两行要求之前输入的为两个数据,否则引爆。

0x08048e58<+42>:

jne0x8048e66

0x08048e5a<+44>:

mov-0xc(%ebp),%eax

0x08048e5d<+47>:

test%eax,%eax第一段数据大于等于0,否则引爆。

0x08048e5f<+49>:

js0x8048e66

0x08048e61<+51>:

cmp$0xe,%eax第一段数据小于等于14时跳过引爆。

0x08048e64<+54>:

jle0x8048e6b

0x08048e66<+56>:

call0x80490d1

0x08048e6b<+61>:

movl$0xe,0x8(%esp)

0x08048e73<+69>:

movl$0x0,0x4(%esp)

0x08048e7b<+77>:

mov-0xc(%ebp),%eax

0x08048e7e<+80>:

mov%eax,(%esp)

0x08048e81<+83>:

call0x8048b60这几行为运行一个递归函数func4来确定第一

0x08048e86<+88>:

cmp$0x1,%eax段数据的值。

0x08048e89<+91>:

jne0x8048e91

0x08048e8b<+93>:

cmpl$0x1,-0x10(%ebp)第二个数据等于1则跳过爆炸。

0x08048e8f<+97>:

je0x8048e9d

0x08048e91<+99>:

lea0x0(%esi,%eiz,1),%esi

0x08048e98<+106>:

call0x80490d1

0x08048e9d<+111>:

leave

0x08048e9e<+112>:

xchg%ax,%ax

0x08048ea0<+114>:

ret

由以上对代码的分析可以看出,第二个数据确定为1。

第一个数据范围为大于等于0,小于14,并且由一个递归函数func4又一次缩小了范围。

但因为这个递归函数太过繁杂,而第一个数据范围又不大,所以我没有细看,直接将第一个数据从0尝试到13,得到了三个数字8、9、11符合要求。

因此密码有三组:

81,91,111。

phase_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)$0x804a23e内为%d%d,即输入两个整数。

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按位与,即保留第一个数的后四位。

0x08048df1<+57>:

mov%eax,-0xc(%ebp)

0x08048df4<+60>:

cmp$0xf,%eax第一个数二进制后四位不能为(1111)2,否则引爆。

0x08048df7<+63>:

je0x8048e22

0x08048df9<+65>:

mov$0x0,%ecx

0x08048dfe<+70>:

mov$0x0,%edx

0x08048e03<+75>:

mov$0x804a1c0,%ebx$0x804a1c0指向的是一个数组,下面分析。

0x08048e08<+80>:

add$0x1,%edx

0x08048e0b<+83>:

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

0x08048e0e<+86>:

add%eax,%ecx

0x08048e10<+88>:

cmp$0xf,%eax

0x08048e13<+91>:

jne0x8048e08以上五行为一个for循环语句,下面分析。

0x08048e15<+93>:

mov%eax,-0xc(%ebp)

0x08048e18<+96>:

cmp$0xf,%edx上述的for循环要循环15次。

0x08048e1b<+99>:

jne0x8048e22

0x08048e1d<+101>:

cmp%ecx,-0x10(%ebp)确定第二个数的值,下面分析。

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

根据上述的代码分析可以知道,第一个数二进制后四位不能为(1111)2。

密码主要由上述的一个for循环确定。

首先$0x804a1c0指向了一个数组,在for循环中每循环一次调用一次,因为必须循环15次,且最开始还要调用一次,因此需要16个元素,使用p*0x804a1c0@16命令来查看这个数组为:

将这个for循环写出:

设i在%edx中,数组a[16]在%ebx中,n在%eax中,sum在%ecx中。

sum=0;

for(i=1;n=15;i++)

{

n=a[n];

sum+=n;

}

n会取16次值,其中第一次n取的值应为用户输入的第一个数二进制下的后四位。

之后每次都等于a[n],sum为除去第一次之外所有n取值的和。

因此我采用逆推的方法来求出n第一次取的值。

序号

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

数组

10

2

14

7

8

12

15

11

0

4

1

13

3

9

6

5

for循环当n为15时终止,因此最后一个n为15,对应序号为上一个n,即6。

同理,可以得到,n从第一个到最后一个为:

5123711139480101214615。

sum=15*16/2-5=115。

即用户输入的第二个数为115。

用户输入第一个数二进制下的后四位为0101(即第一个n=5),而之前位可以随意取值。

因此有无数多的密码,如:

5115,21115。

phase_6代码:

0x08048c89<+0>:

push%ebp

0x08048c8a<+1>:

mov%esp,%ebp

0x08048c8c<+3>:

push%edi

0x08048c8d<+4>:

push%esi

0x08048c8e<+5>:

push%ebx

0x08048c8f<+6>:

sub$0x5c,%esp

0x08048c92<+9>:

lea-0x30(%ebp),%eax

0x08048c95<+12>:

mov%eax,0x4(%esp)

0x08048c99<+16>:

mov0x8(%ebp),%eax

0x08048c9c<+19>:

mov%eax,(%esp)

0x08048c9f<+22>:

call0x804910b

0x08048ca4<+27>:

mov$0x0,%esi

0x08048ca9<+32>:

lea-0x30(%ebp),%edi

0x08048cac<+3

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

当前位置:首页 > 工程科技 > 能源化工

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

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