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

来源:互联网 发布:淘宝便宜技巧 编辑:程序博客网 时间:2024/05/21 06:29

刚刚开始学习深入理解计算机系统(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已完成。

0 0
原创粉丝点击