湖南大学计算机组成原理实验实验3bomblab资料下载.pdf
《湖南大学计算机组成原理实验实验3bomblab资料下载.pdf》由会员分享,可在线阅读,更多相关《湖南大学计算机组成原理实验实验3bomblab资料下载.pdf(26页珍藏版)》请在冰点文库上搜索。
sub$0x18,%esp这里对esp-240x08048f67:
movl$0x804a15c,0x4(%esp)这是将$0x804a15c处的值存入esp+4中0x08048f6f:
mov0x8(%ebp),%eaxebp+8就是从调用函数处取出第一个参数,放到eax寄存器中0x08048f72:
mov%eax,(%esp)将eax的值传给esp0x08048f75:
call0x8048fab此处是入口函数的地址0x8048fab,该函数要调用的参数为esp+4(即$0x804a15c处的值),和ebp+8(即我们输入的值)该函数的作用是:
判断字符串是否相等考虑一个函数的返回值要存在eax中,则以下的eax已经发生改变,是判断字符串是否相等的结果0x08048f7a:
test%eax,%eax0x08048f7c:
je0x8048f830x08048f7e:
call0x80490d1以上三句,如果eax不为0,则引爆炸弹,如果eax为0,则跳转到leave语句函数结束。
说明eax为0时,可以进入下一关0x08048f83:
leave0x08048f84:
ret解题过程:
本题的栈帧结构如下:
根据以上分析,我们发现,从键盘输入一个值,放到(新)ebp+8中,接着函数进行调用,把他传到esp中,接着,函数再从$0x804a15c这个地址取值,放到esp+8中,接着,程序对这两个参数进行函数调用,调用判断字符串是否相等的程序stringnotequal进行判断,如果二者相等,则返回值为0,不引爆炸弹,反之,只要二者不相等,则炸弹爆炸。
分析结论:
此处的密码存在地址$0x804a15c中,我们只要查看该地址的值,即可完成该题。
打开gdb调试,运行x/s0x804a15c,查看该处的值故第一题的答案为WehavetostandwithourNorthKoreanallies.Phase_2内容如下:
0x08048d6a:
push%ebp0x08048d6b:
mov%esp,%ebp0x08048d6d:
push%esi0x08048d6e:
push%ebx这是两个调用者保存寄存器,因为接下来的循环中使用到了这两个寄存器的值,所以要进行压栈保存。
0x08048d6f:
sub$0x30,%espesp-480x08048d72:
lea-0x20(%ebp),%eax0x08048d75:
mov%eax,0x4(%esp)以上两句把ebp-32处的地址传给esp+4处0x08048d79:
mov0x8(%ebp),%eax0x08048d7c:
mov%eax,(%esp)以上两句把ebp+8处的值传给esp0x08048d7f:
call0x804910b根据函数名观察,要读取6个数,所以这题要输入六个数字0x08048d84:
cmpl$0x0,-0x20(%ebp)0x08048d88:
jne0x8048d90跳转的地址是引爆炸弹,不相等就引爆,所以ebp-32处的值要等于00x08048d8a:
cmpl$0x1,-0x1c(%ebp)0x08048d8e:
je0x8048d950x08048d90:
call0x80490d1如果相等就继续,不相等就爆炸,所以ebp-28处的值要为10x08048d95:
lea-0x18(%ebp),%ebxebp-24传给ebx0x08048d98:
lea-0x8(%ebp),%esiebp-8传给esi以上两句是数据初始化,ebp-24是第三个数据的地址,ebp-8是“第七个”数据的地址,这个esi设置成ebp-8的地址是用作判断的。
接下来是一个循环计算的过程,具体的过程我在后续的解题思路里做了讲解。
0x08048d9b:
mov-0x4(%ebx),%eax0x08048d9e:
add-0x8(%ebx),%eax0x08048da1:
cmp%eax,(%ebx)0x08048da3:
je0x8048daa0x08048da5:
call0x80490d1不相等就引爆,所以此处分析得ebx要与eax的值相等0x08048daa:
add$0x4,%ebxebx+=40x08048dad:
cmp%esi,%ebx0x08048daf:
jne0x8048d9b0x08048db1:
add$0x30,%esp0x08048db4:
pop%ebx0x08048db5:
pop%esi0x08048db6:
pop%ebp0x08048db7:
本题具体思路都已标注说明,下面仅对循环体内容的第一次循环作简要说明。
从0x08048d9b:
mov-0x4(%ebx),%eax此处开始,原来ebx所存的地址为ebp-24,这里将ebx-4,即ebp-28处的值,也就是1,赋给了eax0x08048d9e:
add-0x8(%ebx),%eax这里将ebx-8,也就是ebp-32处的值,也就是0,和eax作add操作,这部得出的结果是:
eax=1+0=10x08048da1:
call0x80490d1不相等就引爆,所以此处分析得ebx要与eax的值相等,而此时的ebx是什么呢?
就是ebp-24,即第三个数,说明第三个数是前两数之和0x08048daa:
add$0x4,%ebx0x08048dad:
jne0x8048d9b以上三句,如果我们输入的值满足条件,那么ebx上移4位继续循环,也就是继续求前两个数之和赋给第三个数。
0x08048db1:
add$0x30,%esp如果ebx存的值(我们要求6个数,所以最多到ebp-12)和esi存的值(ebp-8,第七个数)相等的话函数结束了做到这里应该也明白了,其实就是一个斐波那契数列前六项。
所以这题的答案为011235另附本题栈帧结构如下:
Phase_3内容如下:
0x08048ea1:
push%ebp0x08048ea2:
mov%esp,%ebp0x08048ea4:
sub$0x28,%espesp-400x08048ea7:
lea-0x10(%ebp),%eax0x08048eaa:
mov%eax,0xc(%esp)ebp-16处地址赋给esp+120x08048eae:
lea-0xc(%ebp),%eax0x08048eb1:
mov%eax,0x8(%esp)ebp-12处地址赋给esp+80x08048eb5:
movl$0x804a23e,0x4(%esp)这个地址的值可查,查出来之后发现是:
%d%d,这就说明肯定要输入两个整数!
0x08048ebd:
mov0x8(%ebp),%eax0x08048ec0:
mov%eax,(%esp)ebp+8的值赋给esp0x08048ec3:
call0x8048840跟上面那个%d%d结合思考一下,发现这个题,要输入两个数0x08048ec8:
cmp$0x1,%eax0x08048ecb:
jg0x8048ed20x08048ecd:
call0x80490d1说明eax(此时sscanf函数的返回值)大于1,这个函数的返回值是输入元素的个数0x08048ed2:
cmpl$0x7,-0xc(%ebp)0x08048ed6:
ja0x8048f43如果ebp-12大于7,则跳到(其实就是炸弹啦)说明ebp-12小于等于7.0x08048ed8:
mov-0xc(%ebp),%eaxebp-12的值赋给eax0x08048edb:
jmp*0x804a1a0(,%eax,4)间接跳转,跳到后面这个地址,这是这个函数的核心!
考虑对不同的ebp-12的值有不同的操作,这很像是一个switch操作。
0x08048ee2:
mov$0x0,%eaxeax清零0x08048ee7:
jmp0x8048f3c0x08048ee9:
mov$0x0,%eax0x08048eee:
xchg%ax,%ax0x08048ef0:
jmp0x8048f370x08048ef2:
mov$0x0,%eax0x08048ef7:
jmp0x8048f320x08048ef9:
mov$0x0,%eax0x08048efe:
xchg%ax,%ax0x08048f00:
jmp0x8048f2d0x08048f02:
mov$0x0,%eax0x08048f07:
jmp0x8048f280x08048f09:
mov$0x0,%eax0x08048f0e:
xchg%ax,%ax0x08048f10:
jmp0x8048f230x08048f12:
mov$0x314,%eax*0x804a1a0这个值,就是上面这个地址,eax=7880x08048f17:
jmp0x8048f1e0x08048f19:
mov$0x0,%eax0x08048f1e:
sub$0x35a,%eaxeax=788-0x35a=-700x08048f23:
add$0x2ef,%eax0x08048f28:
sub$0x216,%eax0x08048f2d:
add$0x216,%eax0x08048f32:
sub$0x216,%eax0x08048f37:
add$0x216,%eax0x08048f3c:
sub$0x216,%eax算到这里为止,eax=1470x08048f41:
jmp0x8048f4d0x08048f43:
call0x80490d10x08048f48:
mov$0x0,%eax0x08048f4d:
cmpl$0x5,-0xc(%ebp)0x08048f51:
jg0x8048f58ebp-12处的值大于5就炸了,所以ebp-12处的值小于等于50x08048f53:
cmp-0x10(%ebp),%eax0x08048f56:
je0x8048f5d此时的eax必须等于ebp-16,也就是算到这的eax值,就是对应a的第二个参数b的值0x08048f58:
call0x80490d10x08048f5d:
leave0x08048f5e:
xchg%ax,%ax0x08048f60:
ret问题思路:
首先,题目中给出最清晰的线索是那个地址,我们看一下它的值:
是%d,%d,这要输入两个整数值,考虑栈帧结构,ebp-12的值是参数1,存在esp+8处,ebp-20是参数2,存在esp+12处,要输入的就是这两个数。
接下来看这个函数最麻烦的地方,间接跳转处0x08048edb:
考虑对不同的ebp-12的值,跳到不同的地方,有不同的操作,这很像是一个switch操作。
先还是用gdb看一下,这个*0x804a1a0指的是哪里?
先在原代码中找到这里,再作下一步分析。
因为前面我们得到了ebp-12的值是小于等于7的,再往后看,还有一个条件,是他还小于等于5,所以我们考虑第一个参数值从0到5。
(为讨论方便,设第一个参数为a,第二个为b)那么a=0时,上述跳转到哪里呢?
就是0x08048f12:
mov$0x314,%eax这一行了,所以从这一行开始继续算,直到函数结束,就可以算出来a=0时对应的b,我算了一下,这个b=147显然0147已经是这个题的一组解了,接着算下去也没什么意思,无非就是对应有五组答案,不再深究。
栈帧结构如下:
Phase_4内容如下:
0x08048e2e:
push%ebp0x08048e2f:
mov%esp,%ebp0x08048e31:
sub$0x28,%esp0x08048e34:
lea-0x10(%ebp),%eax0x08048e37:
mov%eax,0xc(%esp)ebp-16处的地址赋给esp+120x08048e3b:
lea-0xc(%ebp),%eax0x08048e3e:
mov%eax,0x8(%esp)ebp-12处的地址赋给esp+8两个参数,ebp-16是参数2ebp-12是参数1,先记着,一会用0x08048e42:
movl$0x804a23e,0x4(%esp)这个值,函数3里查过了,是%d%d,说明这题也要输两个整数进去0x08048e4a:
mov0x8(%ebp),%eax0x08048e4d:
mov%eax,(%esp)ebp+8的值赋给esp0x08048e50:
call0x8048840根据上一题的分析,这个函数,输入两个值,返回值为20x08048e55:
cmp$0x2,%eax0x08048e58:
jne0x8048e660x08048e5a:
mov-0xc(%ebp),%eaxebp-12赋给eax0x08048e5d:
test%eax,%eax0x08048e5f:
js0x8048e66是负数就炸了,那么说明ebp-12(参数1)大于等于00x08048e61:
cmp$0xe,%eax0x08048e64:
jle0x8048e6b小于等于14才能继续,说明ebp-12小于等于14,不然就炸了参数1的范围:
0,140x08048e66:
call0x80490d10x08048e6b:
movl$0xe,0x8(%esp)14赋给esp+80x08048e73:
movl$0x0,0x4(%esp)0赋给esp+40x08048e7b:
mov-0xc(%ebp),%eax0x08048e7e:
mov%eax,(%esp)ebp-12即参数1赋给esp0x08048e81:
call0x8048b60又运行了一个函数func4,传入值为14,0,和参数10x08048e86:
cmp$0x1,%eax这个eax是返回值0x08048e89:
jne0x8048e91返回值不为1,就跳到,做完之后就炸了所以要返回10x08048e8b:
cmpl$0x1,-0x10(%ebp)0x08048e8f:
je0x8048e9d如果相等的话,就结束了。
不然就炸了,所以ebp-16(也就是参数2)要等于10x08048e91:
lea0x0(%esi,%eiz,1),%esi0x08048e98:
call0x80490d10x08048e9d:
leave0x08048e9e:
xchg%ax,%ax0x08048ea0:
ret分析思路:
这题有个func4函数,我感觉太麻烦了就没看,但是要输入的两个值都是有范围的,第一个是0,14内的,第二个是1,所以试一下就行了我试出来一组81可以通过测试,其他答案就不清楚了。
栈帧结构:
Phase_5内容如下:
0x08048db8:
push%ebp0x08048db9:
mov%esp,%ebp0x08048dbb:
push%esi0x08048dbc:
0x08048dbd:
sub$0x20,%espesp-320x08048dc0:
lea-0x10(%ebp),%eax0x08048dc3:
mov%eax,0xc(%esp)ebp-16,这个地址传给esp+120x08048dc7:
lea-0xc(%ebp),%eax0x08048dca:
mov%eax,0x8(%esp)ebp-12,这个地址传给esp+80x08048dce:
movl$0x804a23e,0x4(%esp)还是那个%d%d0x08048dd6:
mov0x8(%ebp),%eax0x08048dd9:
mov%eax,(%esp)ebp+8传给esp0x08048ddc:
call0x8048840还是要输入两个数。
0x08048de1:
cmp$0x1,%eax0x08048de4:
jg0x8048debEax要大于1,不然就炸了,废话,返回值肯定是2。
0x08048de6:
call0x80490d10x08048deb:
mov-0xc(%ebp),%eaxebp-12(参数1)传给eax0x08048dee:
and$0xf,%eax把eax和低4位为1的数作位与操作,传回eax0x08048df1:
mov%eax,-0xc(%ebp)eax传回给ebp-120x08048df4:
cmp$0xf,%eax0x08048df7:
je0x8048e22如果eax此时等于00000000000000000000000000001111,就炸了,而这个eax是哪里来的呢,是原eax(输入参数1)与0xf作位与得到的,所以,这个参数1的低4位,不能都为1。
到目前为止,eax的值,就是参数1的低四位,接下来也是通过eax来计算值的,所以在此处要着重考虑一下。
0x08048df9:
mov$0x0,%ecx0x08048dfe:
mov$0x0,%edx0x08048e03:
mov$0x804a1c0,%ebx这个地址指向的东西,是可以看的,但是我们不妨先继续分析下去,再来看这个值是什么东西下面几句是个循环体,要独立来看0x08048e08:
add$0x1,%edxedx+10x08048e0b:
mov(%ebx,%eax,4),%eax把ebx(也就是0x804a1c0)加4倍eax的地址处的值,传给eax0x08048e0e:
add%eax,%ecxecx+=eax0x08048e10:
cmp$0xf,%eax0x08048e13:
jne0x8048e08如果这次的eax低4位不是1111,就回到继续循环。
以上是循环部分0x08048e15:
mov%eax,-0xc(%ebp)把完成循环的eax传给ebp-120x08048e18:
cmp$0xf,%edx0x08048e1b:
jne0x8048e22把edx和15比较,不相等就炸了,所以完成循环时,这个edx是要等于15的,也就是说,完成了15次循环,加上第一次的edx=0的那一次,共16次。
0x08048e1d:
cmp%ecx,-0x10(%ebp)0x08048e20:
je0x8048e270x08048e22:
call0x80490d1把完成循环的ecx和ebp-16(参数2)相比,如果不相等,那就炸了,循环每进行一次,就给ecx加上一个eax,所以参数2的值,要通过这个循环来计算。
0x08048e27:
add$0x20,%esp0x08048e2a:
pop%ebx0x08048e2b:
pop%esi0x08048e2c:
pop%ebp0x08048e2d:
由上可知,$0x804a1c0的地址指向一个至值。
少有16个元素的数组。
那就用gdb看一下这16个单元都是什么那么我们就从循环伊始来看吧。
进入循环前,eax就是参数1的低四位(不能为1111),所以eax的取值就是0、1、214。
好,这就是在进入循环之前的所有条件。
那么跳出循环的条件呢?
就是eax=15,那最终的eax=15,它是怎么来的?
eax是由mov(%ebx,%eax,4),%eax得到的,那么eax=15的上一个eax的值为6(也就是0110),再从上面那个数组里找到6,得到6的上一个eax的值是14,14的上一个eax值是2,2的上一个eax值是1,1的上一个eax值是10,10的上一个eax值是0,0的上一个eax值是8,8的上一个eax值是4,4的上一个eax值是9,9的上一个eax值是13,13的上一个eax值是11,11的上一个eax值是7,7的上一个eax值是3,3的上一个eax值是12,12的上一个eax值是5,5的上一个eax值是15,15的上一个eax值是6。
推到这里,正好循环了16次。
Eax的正向序列为:
5123711139480101214615所以,进入循环之前,eax的值为5(0101)。
而ecx是这16个eax的累加和,加起来等于120,刨去第一个5,(因为没加进去就改变了),所以ecx的值为115,也就是参数2的值因为eax是参数