天天看点

CS:APP3e 深入理解计算机系统_3e bomblab实验

bomb.c

phase_1: Border relations with Canada have never been better.

phase_2: 1 2 4 8 16 32

phase_3: 1 311

phase_4: [0, 1, 3, 7] 0

phase_5: [ionefg]

phase_6: 4 3 2 1 6 5

综上,输入文件应该如下:

psol.txt

运行输出:(也可以手动输入)

\[2017.10.27]更新:学校重新安排了一次相似的实验,只是把一些常量改变了,然后添加了一个“secret_phase”。这次把最后一个阶段将输入逐个7减后的算法详细分析下,上次是利用结果推测过程,没有具体研究算法。

注:下面分析的第六阶段我们学校改过的,密码每个人都不一样(这个的bomb_id为0x28),但算法是和cmu的那个炸弹一样的。secret阶段原CMU炸弹并没有

经过前面的7减算法后,我们如果输入1 6 2 5 3 4, 7减后为6 1 5 2 4 3,查看rsp为:

CS:APP3e 深入理解计算机系统_3e bomblab实验

另外注意到这一句话有一个常量地址

查看该地址内容:

CS:APP3e 深入理解计算机系统_3e bomblab实验

可以观察到每一行(16个字节)是由 4字节xxx常数 + 4字节1~6 + 下一个16字节的地址(除了最后一个16字节除外)

所以,我们如果输入的是1 6 2 5 3 4,7减操作后为 6 1 5 2 4 3,栈中就应该被依次append

3340

32f0

3330

3300

3320

3310

如图:

CS:APP3e 深入理解计算机系统_3e bomblab实验

由上面的栈图,我们的操作就是(用<-代表写入):603340+8<-6032f0 6032f0+8<-603330 603330+8<-603300 603300+8<-603320 603320+8<-603310 而603310+8原本存储的603320没改变为0,验证:

由导火索算法的分析,又因为常量如下:

CS:APP3e 深入理解计算机系统_3e bomblab实验

2e4(0x603310) > 257(0x6032f0) > 235(0x603330) > 169(0x603300) > 098(0x603340) > 05b(0x603320)

所以我们应该将0x6032f0起始的内存块构建为这个样子:

即我们的存入操作为:603310+8<-6032f0 6032f0+8<-603330 603330+8<-603300 603300+8<-603340 603340+8<-603320

由混淆算法的第二阶段分析,我们的存入我们的栈append的地址应该是这个顺序:

603310 6032f0 603330 603300 603340 603320

由混淆算法的第一阶段分析,我们我们输入的数字7减操作后应该为:

3 1 5 2 6 4

所以减7前的密码为:4 6 2 5 1 3

默认情况下并不能激发隐藏关卡:

CS:APP3e 深入理解计算机系统_3e bomblab实验

在bomb的反汇编代码内找到调用<code>secret_phase</code>的函数,居然是<code>phase_defused</code> ...

<code>phase_defused</code>内关键的代码:

注意到常数地址0x4025c2。

CS:APP3e 深入理解计算机系统_3e bomblab实验

所以phase_defused应该是读入了字符,判断是否等于DrEvil,相等的话就进入隐藏关卡。

于是我们在<code>phase_defused</code>中寻找是否有读入的命令,发现就在上面相邻处有:

查看0x4025b9

CS:APP3e 深入理解计算机系统_3e bomblab实验

可见是读入两个整数和一个字符串

查看0x603890

CS:APP3e 深入理解计算机系统_3e bomblab实验

就是我在第四阶段输入的密码——两个整数,所以我们在第四阶段输入10 5 DrEvil即可进入隐藏关卡:

CS:APP3e 深入理解计算机系统_3e bomblab实验

检查调用<code>fun7</code>传入的第一个参数0x603110

CS:APP3e 深入理解计算机系统_3e bomblab实验

进入<code>fun7</code> (必须返回3)

为了方便分析算法,抽象成伪代码:

可以观察到,返回值只有eax = eax*2(偶数)eax = 2*eax+1(奇数)和-1与0这四种情况,所以为了获得3的返回值,我们的递归顺序应该如下:

返回3: 2*1 + 1 -&gt; 返回1: 2*0 + 1 -&gt; 返回0 : 0*2 -&gt; eax=0, esi=edx,return

观察0x603110起始的内存块:

按照递归分析逐步写出rdi的变化和对input_number的限制条件的缩小:

%rdi : 0x603110 -&gt; 0x603150 -&gt; 0x6031d0 -&gt; 603230

input_number的范围:input_number &gt;= 0x24 (要跳L1)input_number != 0x24-&gt; input_number &gt;= 0x32 (要跳L1)input_number != 0x32 -&gt; input_number &lt; 0x6b(不能跳L1)-&gt; input_number &gt;= 0x63(要跳L1)input_number = edx = 0x63

所以,密码应该为0x63即99。

CS:APP3e 深入理解计算机系统_3e bomblab实验