您的位置:首页 > 理论基础

深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_1)

2017-04-04 09:52 926 查看
刚刚开始学习深入理解计算机系统(CSAPP)(原书第二版),初次接触到汇编语言,课程实验的第一个任务是二进制炸弹实验(bomb),书上的介绍是这样的:二进制炸弹是一个作为目标代码文件提供给学生的程序,运行时,它提示用户输入6个不同的字符串。如果其中的任何一个不正确,炸弹就会“爆炸”,打印出一条错误信息,并且在一个分级(grading)服务器上记录事件日志。学生们必须通过对程序反汇编和逆向工程来测定应该是哪6个字符串,从而解除他们各自炸弹的雷管。该实验教会学生理解汇编语言,并且强制他们学习怎样使用调试器。

本人初学汇编的小白,此实验日志纯粹为记录实验探索过程,巩固自己的知识而写,如有错误,还请指正~

实际上在完成这个实验的过程中,反汇编和调试是最为重要的两个步骤。由于书本使用的是IA32形式的汇编,所以这里使用了Linux系统中的AT&T汇编。在终端对bomb的可执行程序进行反汇编,命令为

objdump -d bomb


反汇编出的代码有接近2000行,所以这里就不列出了。通过对bomb.c的C程序代码的浏览,发现只需要对汇编代码的所有phase部分加以解读就可以了。


首先对phase_1函数进行解读,在Notepad++中查找phase_1函数,汇编代码如下:

08048f61 <phase_1>:
8048f61:	55                   	push   %ebp
8048f62:	89 e5                	mov    %esp,%ebp
8048f64:	83 ec 18             	sub    $0x18,%esp
8048f67:	c7 44 24 04 5c a1 04 	movl   $0x804a15c,0x4(%esp)
8048f6e:	08
8048f6f:	8b 45 08             	mov    0x8(%ebp),%eax
8048f72:	89 04 24             	mov    %eax,(%esp)
8048f75:	e8 31 00 00 00       	call   8048fab <strings_not_equal>
8048f7a:	85 c0                	test   %eax,%eax
8048f7c:	74 05                	je     8048f83 <phase_1+0x22>
8048f7e:	e8 4e 01 00 00       	call   80490d1 <explode_bomb>
8048f83:	c9                   	leave
8048f84:	c3                   	ret
8048f85:	90                   	nop
8048f86:	90                   	nop
8048f87:	90                   	nop
8048f88:	90                   	nop
8048f89:	90                   	nop
8048f8a:	90                   	nop
8048f8b:	90                   	nop
8048f8c:	90                   	nop
8048f8d:	90                   	nop
8048f8e:	90                   	nop
8048f8f:	90                   	nop

首先是为新函数开辟一个帧,申请24个内存空间,内存0x8048f67位置的movl指令将值0x804a15c放入内存的0x4+%esp位置,%esp为栈顶指针在内存中的地址。接下来的mov指令从调用phase_1函数的上级函数中获取参数,参数的位置是0x8+%ebp,并存入寄存器eax。下一步将寄存器eax中的参数放入一个内存地址单元中,而这个单元的地址被存放在寄存器esp中,操作数的内存地址被存放在寄存器中,这样的行为称为寄存器间接寻址。由于不能直接交换两个内存单元中的变量值,即指令的操作数不能同时为存储器,所以要通过寄存器作为一个中转,实现交换。

接下来调用了0x8048fab位置的函数 <strings_not_equal>,从函数名可以看出这是一个判断字符串是否相等的函数。继续往下看,后两行的test+je指令,实现的功能是判断eax中的值是否为0,若为0,则跳转到0x8048f83位置的leave+ret指令,函数的执行结束,否则调用<explode_bomb>函数,即引爆炸弹。这说明如果发生跳转,即eax中的值为全0时,字符串才是成功匹配的,再查看<strings_not_equal>函数的内容可以发现,如果两字符串相等,那么eax的值就会变为全0的状态。可以推测出,进行比较的两个字符串分别是来自内存地址为0x804a15c位置的字符串和phase_1上级函数的参数。进入gdb调试,对内存0x804a15c位置内容以字符串类型查看:

x/s 0x804a15c

得到的结果为:



退出调试,在终端运行bomb可执行程序,输入上述字符串:



提示phase_1已完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐