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

时间:2022-02-05 01:13:35

本文接 深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_2)继续往下写,意在记录本人在学习CSAPP的bomb程序炸弹实验中的探索过程和发现。

在Notepad++编辑器中找到函数phase_3,代码如下:

08048ea1 <phase_3>:
8048ea1: 55 push %ebp
8048ea2: 89 e5 mov %esp,%ebp
8048ea4: 83 ec 28 sub $0x28,%esp
8048ea7: 8d 45 f0 lea -0x10(%ebp),%eax
8048eaa: 89 44 24 0c mov %eax,0xc(%esp)
8048eae: 8d 45 f4 lea -0xc(%ebp),%eax
8048eb1: 89 44 24 08 mov %eax,0x8(%esp)
8048eb5: c7 44 24 04 3e a2 04 movl $0x804a23e,0x4(%esp)
8048ebc: 08
8048ebd: 8b 45 08 mov 0x8(%ebp),%eax
8048ec0: 89 04 24 mov %eax,(%esp)
8048ec3: e8 78 f9 ff ff call 8048840 <__isoc99_sscanf@plt>
8048ec8: 83 f8 01 cmp $0x1,%eax
8048ecb: 7f 05 jg 8048ed2 <phase_3+0x31>
8048ecd: e8 ff 01 00 00 call 80490d1 <explode_bomb>
8048ed2: 83 7d f4 07 cmpl $0x7,-0xc(%ebp)
8048ed6: 77 6b ja 8048f43 <phase_3+0xa2>
8048ed8: 8b 45 f4 mov -0xc(%ebp),%eax
8048edb: ff 24 85 a0 a1 04 08 jmp *0x804a1a0(,%eax,4)
8048ee2: b8 00 00 00 00 mov $0x0,%eax
8048ee7: eb 53 jmp 8048f3c <phase_3+0x9b>
8048ee9: b8 00 00 00 00 mov $0x0,%eax
8048eee: 66 90 xchg %ax,%ax
8048ef0: eb 45 jmp 8048f37 <phase_3+0x96>
8048ef2: b8 00 00 00 00 mov $0x0,%eax
8048ef7: eb 39 jmp 8048f32 <phase_3+0x91>
8048ef9: b8 00 00 00 00 mov $0x0,%eax
8048efe: 66 90 xchg %ax,%ax
8048f00: eb 2b jmp 8048f2d <phase_3+0x8c>
8048f02: b8 00 00 00 00 mov $0x0,%eax
8048f07: eb 1f jmp 8048f28 <phase_3+0x87>
8048f09: b8 00 00 00 00 mov $0x0,%eax
8048f0e: 66 90 xchg %ax,%ax
8048f10: eb 11 jmp 8048f23 <phase_3+0x82>
8048f12: b8 14 03 00 00 mov $0x314,%eax
8048f17: eb 05 jmp 8048f1e <phase_3+0x7d>
8048f19: b8 00 00 00 00 mov $0x0,%eax
8048f1e: 2d 5a 03 00 00 sub $0x35a,%eax
8048f23: 05 ef 02 00 00 add $0x2ef,%eax
8048f28: 2d 16 02 00 00 sub $0x216,%eax
8048f2d: 05 16 02 00 00 add $0x216,%eax
8048f32: 2d 16 02 00 00 sub $0x216,%eax
8048f37: 05 16 02 00 00 add $0x216,%eax
8048f3c: 2d 16 02 00 00 sub $0x216,%eax
8048f41: eb 0a jmp 8048f4d <phase_3+0xac>
8048f43: e8 89 01 00 00 call 80490d1 <explode_bomb>
8048f48: b8 00 00 00 00 mov $0x0,%eax
8048f4d: 83 7d f4 05 cmpl $0x5,-0xc(%ebp)
8048f51: 7f 05 jg 8048f58 <phase_3+0xb7>
8048f53: 3b 45 f0 cmp -0x10(%ebp),%eax
8048f56: 74 05 je 8048f5d <phase_3+0xbc>
8048f58: e8 74 01 00 00 call 80490d1 <explode_bomb>
8048f5d: c9 leave
8048f5e: 66 90 xchg %ax,%ax
8048f60: c3 ret

在这一关中,使用gdb调试器对程序进行调试可以非常清楚地看到整个执行过程,指令的跳转能够帮助我们很好地理解程序的功能。

从0x8048ea1到0x8048ec0依然是帧的开辟和运算前的一些准备工作。0x8048ec3开始读入数据,从0x8048ea7和0x8048eae可以看出,两个参数分别位于-0x10(%ebp)位置和-0xc(%ebp)位置,分别设为val2和val1(val1的输入顺序在val2之前)。再大概浏览一下接下来的代码,基本都是进行一些数学运算,所以可以推断出这一关的要求应该是输入两个数,它们之间要符合某种计算关系。

从0x8048ed2位置的cmpl指令分析,-0xc(%ebp)位置的参数val1应该是一个不大于7的数字,否则,程序将跳转到0x8048f43位置的<explode_bomb>,即引爆炸弹。

所以输入的第一个参数val1是不大于7的一个整数,第二个参数val2在0x8048f53位置出现,与储存在eax中的计算结果进行比较,若不相等则跳转至0x8048f58位置,同样是引爆的结果,所以,参数1经过中间的一系列计算得到的结果必须和参数2相等,否则将引爆炸弹。

接下来在gdb调试器中进行探索。将第一个参数设定为0,第二个参数设定为一个任意值(因为还不知道将会执行何种操作,并且在gdb调试的过程中,如果没有进行到0x8048f58位置则暂时不会引爆炸弹),这里选择10。打开调试功能,将断点设定在phase_3函数位置,输入r开始调试,首先要将第1、2关的正确答案输入,否则将会引爆炸弹,接下来输入两个参数0和10:

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

进入phase_3函数后,使用ni指令单步进入进行调试,查看程序的运行情况。使用info reg指令查看寄存器情况。当0x8048ec3位置的指令执行完成(即数据读入结束)后,查看寄存器内容:

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

这时候可以看到,eax的值已经被修改为2,而0x8048ec8位置开始的指令就是将eax中的值和1做比较,所以这一步是一定会发生跳转的(多次测试后发现,eax的内容在这里总是被修改为2,和输入的数据无关,猜测可能是输入数据的个数)。

按照0x8048ecb位置的jg跳转指令,函数跳转到0x8048ed2位置,从这一行开始解读,将参数1的值和7做比较,大于则引爆炸弹,否则将参数1的值存在寄存器eax中,接着就是一个无条件跳转指令jmp    *0x804a1a0(,%eax,4),为了看清楚这个指令使程序跳转到了一个什么位置,我们继续使用gdb功能。

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

可以清楚地看到,0x8048edb位置的跳转指令执行后,程序跳转到了0x8048f12位置,这个位置的指令是mov    $0x314,%eax,说明已经开始运算,查看寄存器可以发现,我们输入的第一个参数0也已经成功存入eax寄存器。继续单步调试。看看程序下一步会做什么。

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

通过汇编代码可以看到,0x8048f1e到0x8048f3c位置执行的全部是运算指令,接着是0x8048f41位置的一个无条件跳转指令,跳转到0x8048f4d位置,0x8048f4d位置的内容是cmpl   $0x5,-0xc(%ebp),还是对参数1进行筛选的一个指令,下一条是jg指令,跳转至0x8048f58位置,引爆炸弹。这样可以推断出输入的第一个参数必须小于等于5。之前输入的0也是符合的。而且我们可以看到,运算指令执行完成后,eax中的值变成了147,而0x8048f53位置的cmp    -0x10(%ebp),%eax指令正是将运算结果和参数2进行比较,若相等则函数执行结束,否则引爆炸弹,所以可以推断出当第一个参数为0时,第二个参数的值必定是147,否则将引爆炸弹。

回头观察0x8048edb位置的这个jmp跳转指令,内容是:

8048ed8:	8b 45 f4             	mov    -0xc(%ebp),%eax
8048edb: ff 24 85 a0 a1 04 08 jmp *0x804a1a0(,%eax,4)

跳转到哪个地址,取决于eax中的值是多少,所以参数1输入不同的值,将跳转到不同的位置,执行不同的运算,得到的结果(也就是参数2)也不相同。实际上这个程序实现的应该是一个switch结构,每个输入对应唯一的一个输出。同时,输入的参数1有0,1,2,3,4,5这些值,所以答案不是唯一的。输入1-5分别进行调试,得到几种正确答案:

0,147

1,-641

2,217

3,-534

4,0

5,-534

以上输入都是正确的。

验证一下第一个答案:

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