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

时间:2021-08-19 01:18:31

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

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

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

objdump -d bomb

反汇编出的代码有接近2000行,所以这里就不列出了。通过对bomb.c的C程序代码的浏览,发现只需要对汇编代码的所有phase部分加以解读就可以了。 深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_1)

首先对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

得到的结果为:

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

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

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

提示phase_1已完成。