最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

LAB3实验报告

来源:动视网 责编:小OO 时间:2025-10-01 17:30:18
文档

LAB3实验报告

课程实验报告课程名称:计算机组成与原理实验项目名称:LAB3专业班级:智能2班******学号:*******************完成时间:2015年5月9日计算机科学与工程系【实验目的】理解汇编语言,学会使用调试器。【实验原理】二进制是作为一个目标代码文件提供给学生们的程序,运行时,它提示用户输入6个不同的字符串。如果其中任何一个不正确,就会“爆炸”:打印出一条错误信息。学生通过反汇编和逆向工程来确定是哪六个字符串,从而解除他们各自的雷管。【实验过程】一、准备过程1.先把LA
推荐度:
导读课程实验报告课程名称:计算机组成与原理实验项目名称:LAB3专业班级:智能2班******学号:*******************完成时间:2015年5月9日计算机科学与工程系【实验目的】理解汇编语言,学会使用调试器。【实验原理】二进制是作为一个目标代码文件提供给学生们的程序,运行时,它提示用户输入6个不同的字符串。如果其中任何一个不正确,就会“爆炸”:打印出一条错误信息。学生通过反汇编和逆向工程来确定是哪六个字符串,从而解除他们各自的雷管。【实验过程】一、准备过程1.先把LA


课程实验报告

   课  程 名 称:      计算机组成与原理         

   实验项目名称:           LAB3               

   专  业 班 级:           智能2班            

   *        **           ***              

  学        号:         ************          

   * * *  **            **               

完 成 时 间:    2015    年   5   月   9   日

计算机科学与工程系

【实验目的】

理解汇编语言,学会使用调试器。

【实验原理】

二进制是作为一个目标代码文件提供给学生们的程序,运行时,它提示用户输入6个不同的字符串。如果其中任何一个不正确,就会“爆炸”:打印出一条错误信息。学生通过反汇编和逆向工程来确定是哪六个字符串,从而解除他们各自的雷管。

【实验过程】

一、准备过程

1.先把LAB3文件拷贝到VMware中的ubuntu系统里,然后解压获得3文件,分别为bomb、 bomb.c和README-bomblab.txt以及实现基本内容与要求.txt,首先查看实现基本内容与要求与README-bomblab.txt,大致理解意思后,打开.c文件,进去后发现代码不完整,(由于自己C语言能力不强,所以直接把文件拷贝到windows里,用VS2012编译一下,发现很多错误,从而确认代码不完整),从主观上来想,如果代码完整了,那么还需要给其他文件吗?所以,这个.c文件必定是一个不完整的文件,只能用来作为参考。

2.既然不能够直接从.c文件看出问题,那么就需要从bomb程序里找,如何找?貌似也就只能选择反编译了,然后再通过反编译的代码与给出来的.c源代码相结合,来进行拆。注:反汇编命令是objdump –d XXX

二、开始实验

1.用ctrl+alt+t打开终端命令,由于三个文件的位置在桌面/LAB3,所以需要cd Dsktop/LAB3/来进入到相应的目录

2.然后用反编译命令objdump -d bomb > out.txt对bomb进行反编译,编译出来的文件存到新建的文件out.txt

3.打开out.txt文件,出现了大量汇编代码。

第一关

找到第一关的代码,如下:

首先看从哪里会调用爆炸的函数,显然,我们知道这个函数就是调用爆炸函数,test %eax,%eax与je 8048f83  表示,当%eax=0的时候,调用,也就是不调用爆炸的函数,所以在调用函数的时候,必须返回%eax为0,而这个函数的作用就是判断字符串是否相等。在往上看,可以看到movl $0x804a15c,0x4(%esp),0x804a15c内存地址里面的内容就是我们所需要的字符串。这时候,输入gdb bomb,进入gdb调试,然后输入x/s 0x804a15c查看内存值(其中s指的是以字符串的形式查看内存的值,当你上一次已经x/s了,下一次就可以直接x+空格+内存地址,这样也是以字符串的形式输出,可能是gdb默认保存上一次的输出格式,所以下次执行输出默认的是上一次输出的格式),可以看到该内存地址的值是:We have to stand with our North Korean allies.

然后直接输入r运行程序,然后输入字符串。得到如下结果:

至此,第一关已成功通过。

第二关

汇编代码如下:

从j看出,执行这行会跳转到调用爆炸函数,所以必须第一个数为0,(从c可以看出);同理,j与c必须让第二个数为1,然后m与a,c与j这些代码可知,下一个数必须是前两个数之和,然后跳转到输入下一个数,直到6个数输入完毕。总体上看,这一关让我们输入的是以0为首项的Fibonacc数列,然后在第一关的基础上,直接输入0 1 1 2 3 5这6个数字,然后看结果。

结果如下:

所以,第二关也顺利通关。

第三关

汇编代码:

Movl $0x804a23e,0x4(%esp),用gdb查看0x804a23e 的值

发现这个应该是要求输入两个数字。根据刚才的结论

Call 8048840 <__isoc99_sscanf@plt>是输入数字的个数,并把个数存入到eax中,cmp $0x1,%eax与j表示输入的数字必须大于1才不会引爆;执行j会一样指向引爆函数,所以必须-0xc(%ebp)的值小于7,从c又可以知道输入的第一个数字必须小于5;其中,jmp *0x804a1a0(,%eax,4)相对应的是switch(a),当我们输入的第一个数字为0的时候,查看*0x804a1a4的值,,所以会跳转到0x8048f12那行代码中,继续执行,最后c表示输入的第二个数字必须等于第一个数经过数次运算的结果,我们可以从代码中得出此时的值为147,综合起来就是输入0 147.结果如下:

同理,当输入第一个数为1时, *0x804a1a0 +4*1=*0x804a1a4,此时查看*0x804a1a4对应的值,所以switch会跳转到0x8048f19,然后对eax进行一系列运算得出结果,最后得出的结果是:-1;即1 -1

同理,接下来还可以得出来的输入是:2 217;3 -534;4 0;

结果如下:

所以,第三关完美通过。

第四关

代码如下:

前面的代码都跟第三关差不多,都是要求输入两个数字。t与j告诉我们输入的第一个数字必须为非负数;c与j要求第一个数字必须小于等于14,设第一个数字为x,第二个数字为y,即0<=x<=14;c需要调用func4()函数,让我们转到fun4()的代码中:

第一次调用fun4(),edx为输入的x值,eax=0,ebx=14;根据整个fun4()函数,当x<=7时,调换ebx与esi的值,返回到第四关中,eax!=1,直接跳转最后爆炸。所以,x>7。当输入为8,ecx=7减去1变为6,然后自己调用自己,即为递归函数,此时新的edx=8不变,eax=0不变,ebx=6。根据跟随代入法,最后可以总结成C语言代码:

Int fun(int edx,int eax,int ebx){

Int ecx=ebx;

Ecx=ecx-eax;

If(ecx<0)

Ecx--;

Ecx/=2;

Ecx+=eax;

If(edx>ecx){

Eax=0;

If(edx<=edx){

  Return a;

}else{

  Ecx++;

  Return 2*fun(edx,ecx,ebx)+1;

}

}

Else{

 c--;

  return 2*fun(edx,eax,ecx);

}

}

当输入8 1或者9 1或者11 1时,可避开。

第五关

代码如下:

这题前部分跟上两关一样,要求输入的数字个数多于1个;

根据上面的内存储存的地址与代码,可以得到如下的关系

根据汇编代码可知,edx在循环之后要等于15,否则爆炸,所以,循环体中需要循环15次,而eax等于15的时候,循环结束,所以只有当eax等于5的时候,如上图,才能达到15次。但是由于eax=输入的第一个数&0xf,所以,第一个数可以是5,也可以是21,37,53等等。而第二个数需要等于循环结束后的eax的总和:12+3+7+11+13+9+4+8+0+10+1+2+14+6+15=115,所以第二个数为115。

第六关

汇编代码:

c表示要输入6个数字;l指的是当前数字,s与c与j表明了当前数字不能超过5,因为是无符号的比较,所以它也不能够小于1,也就是当前数字只能取1 2 3 4 5 6,接下来,c与j表示当前那个数与前面那个数不能够相等,往后看发现,会循环6次,也就是说,这6个数字的取值范围为1~6,而且不能相同。按推理,接下来的代码会提示这六个数字如何排序的问题了。m这里我们发现了它保存了一个值,m这个是指针地址+8,这是个循环体,那么我们查询地址+8,发现存储的是一个地址,然后根据这个地址往下查,发现存得又是一个值,那么问题来了:这里可能就是关键。用gdb查询值,结果如下:

因此我们发现,其实这里就是一个链表。最后面的c与j可知,链表的前一个数必须大于后面那个数。所以显而易见,输入的值对应上图的值,即1对应0x1a7,2对应0x6c……..6对应0x255,根据大小排序,应输入:5 6 1 4 3 2 

所以此时6关全部完成!还剩下一个隐藏关卡。

由于能力有限,暂时到此为止了。

文档

LAB3实验报告

课程实验报告课程名称:计算机组成与原理实验项目名称:LAB3专业班级:智能2班******学号:*******************完成时间:2015年5月9日计算机科学与工程系【实验目的】理解汇编语言,学会使用调试器。【实验原理】二进制是作为一个目标代码文件提供给学生们的程序,运行时,它提示用户输入6个不同的字符串。如果其中任何一个不正确,就会“爆炸”:打印出一条错误信息。学生通过反汇编和逆向工程来确定是哪六个字符串,从而解除他们各自的雷管。【实验过程】一、准备过程1.先把LA
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top