深入理解计算机系统LAB2.docx
- 文档编号:23401878
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:17
- 大小:99.52KB
深入理解计算机系统LAB2.docx
《深入理解计算机系统LAB2.docx》由会员分享,可在线阅读,更多相关《深入理解计算机系统LAB2.docx(17页珍藏版)》请在冰豆网上搜索。
深入理解计算机系统LAB2
LAB1实验报告
实验目的:
使用课程知识拆除一个“BinaryBombs”来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。
实验简介:
一个“BinaryBombs”(二进制炸弹,简称炸弹)是一个Linux可执行C程序,包含phase1~phase6共6个阶段。
炸弹运行各阶段要求输入一个字符串,若输入符合程序预期,该阶段炸弹被“拆除”,否则“爆炸”。
实验目标是你需要拆除尽可能多的炸弹。
运行结果:
通关密码储存在001431.txt文件中。
成功运行结果截图:
实验中的六组密码:
PHASE1:
字符串比较
本关比较简单,根据课件中的提示用GDB将最先压栈的那个字符串常量打印出来,然后将其作为密码输入,比较成功后即通关。
08048ab2
8048ab2:
83ec14sub$0x14,%esp
8048ab5:
68049f0408push$0x8049f04
8048aba:
ff74241cpushl0x1c(%esp)
8048abe:
e84d040000call8048f10
将地址0x8049f04中的值打印出来:
即“Thefuturewillbebettertomorrow.”
PHASE2:
循环
在查看汇编语言的时候,会看到有调用一个read_six_number函数,猜测此题是让输入六个数字。
08048ad3
8048ad3:
56push%esi
8048ad4:
53push%ebx
8048ad5:
83ec2csub$0x2c,%esp
8048ad8:
8d442410lea0x10(%esp),%eax
8048adc:
50push%eax
8048add:
ff74243cpushl0x3c(%esp)
8048ae1:
e846050000call804902c
8048ae6:
83c410add$0x10,%esp
8048ae9:
837c240801cmpl$0x1,0x8(%esp)------判定是否为1
8048aee:
741eje8048b0e
8048af0:
e812050000call8049007
8048af5:
eb17jmp8048b0e
8048af7:
8b03mov(%ebx),%eax
8048af9:
01c0add%eax,%eax----进行自加,扩大两倍
8048afb:
394304cmp%eax,0x4(%ebx)
8048afe:
7405je8048b05
8048b00:
e802050000call8049007
8048b05:
83c304add$0x4,%ebx
8048b08:
39f3cmp%esi,%ebx
8048b0a:
75ebjne8048af7
8048b0c:
eb0ajmp8048b18
8048b0e:
8d5c2408lea0x8(%esp),%ebx
8048b12:
8d74241clea0x1c(%esp),%esi
8048b16:
ebdfjmp8048af7
8048b18:
83c424add$0x24,%esp
8048b1b:
5bpop%ebx
8048b1c:
5epop%esi
8048b1d:
c3ret
有汇编语言进行分析,不难看出,这道题目要求输入六个数字,并且要求第一个数字为1,之后跳入一个循环,将第一个数字加倍和已有的数字进行比较,所以不难看出所需要的密码是1,2,4,8,16,32这六个数字。
PHASE3:
条件分支语句
这道题的汇编语句明显变长了,但是由于PPT中已经提示这是条件分支语句,以此为切入点,此题也不难分析。
08048b1e
8048b1e:
83ec1csub$0x1c,%esp
8048b21:
8d442408lea0x8(%esp),%eax
8048b25:
50push%eax
8048b26:
8d442410lea0x10(%esp),%eax
8048b2a:
50push%eax
8048b2b:
680fa10408push$0x804a10f打印该值为”%d%d”
8048b30:
ff74242cpushl0x2c(%esp)
8048b34:
e887fcffffcall80487c0<__isoc99_sscanfplt>
上面这一段调用了一个函数sscanf(),查询可知这个函数的原型为:
intsscanf(constchar*buffer,constchar*format,[argument]...);即读取输入的字符串,并以指定的格式赋给参数。
其中一个参数在地址0x804a10f中。
可知需要输入两个整数。
8048b39:
83c410add$0x10,%esp
8048b3c:
83f801cmp$0x1,%eax
8048b3f:
7f05jg8048b46
8048b41:
e8c1040000call8049007
8048b46:
837c240c07cmpl$0x7,0xc(%esp)---------不大于7
8048b4b:
7766ja8048bb3
有这些可以得知第一个参数的信息,可以看出这是一个不大于7的数,因此缩小了选择,不难猜出可能是分支条件。
8048b4d:
8b44240cmov0xc(%esp),%eax
8048b51:
ff2485809f0408jmp*0x8049f80(,%eax,4)
8048b58:
b80c030000mov$0x30c,%eax
8048b5d:
eb05jmp8048b64
8048b5f:
b800000000mov$0x0,%eax
8048b64:
2dd5030000sub$0x3d5,%eax
8048b69:
eb05jmp8048b70
8048b6b:
b800000000mov$0x0,%eax
8048b70:
0535010000add$0x135,%eax
8048b75:
eb05jmp8048b7c
8048b77:
b800000000mov$0x0,%eax
8048b7c:
2de9020000sub$0x2e9,%eax
8048b81:
eb05jmp8048b88
8048b83:
b800000000mov$0x0,%eax
8048b88:
05e9020000add$0x2e9,%eax
8048b8d:
eb05jmp8048b94
8048b8f:
b800000000mov$0x0,%eax
8048b94:
2de9020000sub$0x2e9,%eax
8048b99:
eb05jmp8048ba0
8048b9b:
b800000000mov$0x0,%eax
8048ba0:
05e9020000add$0x2e9,%eax
8048ba5:
eb05jmp8048bac
8048ba7:
b800000000mov$0x0,%eax
8048bac:
2de9020000sub$0x2e9,%eax
8048bb1:
eb0ajmp8048bbd
8048bb3:
e84f040000call8049007
上面是各种分支情况,看起来比较复杂,先放一放
8048bb8:
b800000000mov$0x0,%eax
8048bbd:
837c240c05cmpl$0x5,0xc(%esp)---参数不能大于5
8048bc2:
7f06jg8048bca
8048bc4:
3b442408cmp0x8(%esp),%eax
8048bc8:
7405je8048bcf
8048bca:
e838040000call8049007
8048bcf:
83c41cadd$0x1c,%esp
8048bd2:
c3ret
可以看出参数不能大于五,因此这道题可能有多组解,不过结合分支语句,不难看出当第一个参数比较大的时候,计算量比较小,所以我选择了第一个参数为5,代入进行逐步计算,可以得到此时的值为-745。
PHASE4:
递归调用栈
这一步是递归调用栈,所以有两部分汇编代码,其中一个是被调用的函数,简单地看一下代码,应该是一个递归的函数。
先分析主程序部分的代码,其中也有sscanf函数:
08048c2c
8048c2c:
83ec1csub$0x1c,%esp
8048c2f:
8d442408lea0x8(%esp),%eax
8048c33:
50push%eax
8048c34:
8d442410lea0x10(%esp),%eax
8048c38:
50push%eax
8048c39:
680fa10408push$0x804a10f---输出为”%d%d”
8048c3e:
ff74242cpushl0x2c(%esp)
8048c42:
e879fbffffcall80487c0<__isoc99_sscanfplt>
8048c47:
83c410add$0x10,%esp
8048c4a:
83f802cmp$0x2,%eax----返回值为2
从上面这部分看出我们需要输入两个参数,且两个都是整数型的。
8048c4d:
7507jne8048c56
8048c4f:
837c240c0ecmpl$0xe,0xc(%esp)第一个参数不大于14
8048c54:
7605jbe8048c5b
8048c56:
e8ac030000call8049007
8048c5b:
83ec04sub$0x4,%esp
8048c5e:
6a0epush$0xe
8048c60:
6a00push$0x0
8048c62:
ff742418pushl0x18(%esp)
8048c66:
e868ffffffcall8048bd3
8048c6b:
83c410add$0x10,%esp
8048c6e:
83f825cmp$0x25,%eax
8048c71:
7507jne8048c7a
8048c73:
837c240825cmpl$0x25,0x8(%esp)---第二个参数为37
8048c78:
7405je8048c7f
8048c7a:
e888030000call8049007
8048c7f:
83c41cadd$0x1c,%esp
8048c82:
c3ret
从上面这些可以看出,虽然输入了两个参数,但是只有第一个参数被传递给了func4另外一个没有变化,而且可以知道等于37。
同时,第一个参数还不大于14。
这样可能的情况就少了。
考虑到func4本来就是一个递归函数,即使反汇编出来,也需要一步一步代入,不如直接进行尝试,枚举法得到第一个参数是10。
PHASE5:
指针
这一道题的提示比较模糊,毕竟汇编程序里到处都有指针。
08048c83
8048c83:
83ec1csub$0x1c,%esp
8048c86:
8d442408lea0x8(%esp),%eax
8048c8a:
50push%eax
8048c8b:
8d442410lea0x10(%esp),%eax
8048c8f:
50push%eax
8048c90:
680fa10408push$0x804a10f--地址参数
8048c95:
ff74242cpushl0x2c(%esp)
8048c99:
e822fbffffcall80487c0<__isoc99_sscanfplt>
同样函数sscanf,其中有两个参数,有一个是地址0x804a10f,先记下等会可能会用到。
8048c9e:
83c410add$0x10,%esp
8048ca1:
83f801cmp$0x1,%eax
8048ca4:
7f05jg8048cab
8048ca6:
e85c030000call8049007
8048cab:
8b44240cmov0xc(%esp),%eax
8048caf:
83e00fand$0xf,%eax---------取低四位
8048cb2:
8944240cmov%eax,0xc(%esp)
8048cb6:
83f80fcmp$0xf,%eax---------不能等于15
8048cb9:
742eje8048ce9
8048cbb:
b900000000mov$0x0,%ecx
8048cc0:
ba00000000mov$0x0,%edx
8048cc5:
83c201add$0x1,%edx---------计数用的
8048cc8:
8b0485c09f0408mov0x8049fc0(,%eax,4),%eax寻址
8048ccf:
01c1add%eax,%ecx---------求和用的
8048cd1:
83f80fcmp$0xf,%eax
8048cd4:
75efjne8048cc5
8048cd6:
c744240c0f0000movl$0xf,0xc(%esp)
8048cdd:
00
8048cde:
83fa0fcmp$0xf,%edx---------到15跳出
8048ce1:
7506jne8048ce9
8048ce3:
3b4c2408cmp0x8(%esp),%ecx
8048ce7:
7405je8048cee
8048ce9:
e819030000call8049007
8048cee:
83c41cadd$0x1c,%esp
8048cf1:
c3ret
个别地方不是太清楚,不过已经基本可以猜出来程序的目的,设置一个计数器进行计数,每次按照变量的偏移寻址,找到之后变成新的变量,之后按照新的变量进行寻址,如此循环。
没找到一个变量,求和。
当变量刚好等于15的时候跳出,不过跳出的时候还需要看一下计数器有没有达到15,也就是说要循环15次才可以跳出,这为我们猜测其值提供了方便。
所以我们需要做的是找到初始的变量和以这个变量开始循环所得到的总和。
根据GDB输出的情况,我做了一个表格:
0
1
2
3
4
5
6
7
10
2
14
7
8
12
15
11
8
9
10
11
12
13
14
15
0
4
1
13
3
9
6
5
其中首行是相对于首地址便宜的字节,下面是其对应的常数。
当变量为15的时候跳出,那么我们可以从15向后推:
1561421100849131173125
不难看出15个循环之后是5,因此第一个参数是5。
之后把这十五个参数的值相加。
最开始的时候,我犯了个错误就是直接把这十五个数相加,后来不通过,经过分析发现是15个偏移量对应的地址中的常数,所以为115。
PHASE6:
链表/指针/结构
这一关看提示就觉得很难,首先对这三个词进行联想,“链表+结构”这个比较好联想,应该使用结构体定义了一个链表结构。
至于“指针”,这个我猜测应该是和上一关所说的意思可能有相似之处,应给就是不停地变换地址比较之类的。
这一关的汇编语言比较长,其中有一大部分都是对结构体的定义,所以这里只摘录要点进行解释说明。
08048cf2
8048cf2:
56push%esi
8048cf3:
53push%ebx
8048cf4:
83ec3csub$0x3c,%esp
8048cf7:
8d442420lea0x20(%esp),%eax
8048cfb:
50push%eax
8048cfc:
ff74244cpushl0x4c(%esp)
8048d00:
e827030000call804902c
又是这个参数,这道题还是让你输入六个数
8048d05:
83c410add$0x10,%esp
8048d08:
be00000000mov$0x0,%esi
8048d0d:
8b44b418mov0x18(%esp,%esi,4),%eax
8048d11:
83e801sub$0x1,%eax
8048d14:
83f805cmp$0x5,%eax
8048d17:
7605jbe8048d1e
8048d19:
e8e9020000call8049007
8048d1e:
83c601add$0x1,%esi
8048d21:
83fe06cmp$0x6,%esi
8048d24:
741bje8048d41
8048d26:
89f3mov%esi,%ebx
8048d28:
8b449c18mov0x18(%esp,%ebx,4),%eax
8048d2c:
3944b414cmp%eax,0x14(%esp,%esi,4)
8048d30:
7505jne8048d37
8048d32:
e8d0020000call8049007
8048d37:
83c301add$0x1,%ebx
8048d3a:
83fb05cmp$0x5,%ebx
8048d3d:
7ee9jle8048d28
8048d3f:
ebccjmp8048d0d
8048d41:
8d442418lea0x18(%esp),%eax
到这里为止,是一个循环,是对输入的六个数字进行判定,从这里可以看出,要0到6这几个数字符合要求,是这六个数字的一种组合。
8048d45:
8d5c2430lea0x30(%esp),%ebx
8048d49:
b907000000mov$0x7,%ecx
8048d4e:
89camov%ecx,%edx
8048d50:
2b10sub(%eax),%edx
8048d52:
8910mov%edx,(%eax)
8048d54:
83c004add$0x4,%eax
8048d57:
39d8cmp%ebx,%eax
8048d59:
75f3jne8048d4e
这一段很重要,第一次读的时候不明所以,不知道是在做什么,之后忽视去看后面的,发现结果怎么输入都不对。
回过头来看,发现问题在这里,假如输入的是x,这里是将其变为7-x。
即这个循环是做了一个置换,将我们所输入的数字置换了。
8048d75:
7417je8048d8e
8048d77:
89demov%ebx,%esi
8048d79:
8b4c9c18mov0x18(%esp,%ebx,4),%ecx
8048d7d:
b801000000mov$0x1,%eax
8048d82:
ba3cb20408mov$0x804b23c,%edx
8048d87:
83f901cmp$0x1,%ecx
8048d8a:
7fd6
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 深入 理解 计算机系统 LAB2