CSAPP lab binary bomb 二进制炸弹

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010223904/article/details/47219967

binary bomb (二进制炸弹),这是CSAPP的一个lab。大概的意思是:给出一个二进制的可执行文件,及其对应的C语言主程序(只有主程序,其中调用的函数没有源代码)。运行这个可执行文件的时候,会有若干个“关卡”,每一个“关卡”会要求学生输入一些东西,经过处理后,如果与预计的相符,就解除了“炸弹”,进入下一关。如果输入不对,“炸弹”爆炸。学生要做的,就是利用GDB, objdump等工具,找出每一个关卡应该输入什么东西。

大三的一个实验,当时做得很头疼。

相关代码及说明下载

Phase_1

在cmd中输入 gdb bomb.exe用gdb 开始调试 bomb,输入l 可以查看源码
这里写图片描述

首先要解决的是 phase_1,输入b phase_1 在调用phase_1()函数前设置断点,然后用命令 r运行程序。
这里写图片描述
在断点前停止,查看汇编的代码( 为什么这个和VC下看到的汇编的参数顺序是相反的? )
这里写图片描述
从汇编的代码中可以看出来, test %eax, %eax这里决定会不会跳到call 0x40ifa4(explode_bomb),要是跳到这里那就是炸弹爆炸了 ,所以我们要跳过这里,执行 je 0x401868(phase_1+34), phase_1+34也就是leave 。Test是逻辑运算指令,执行 BIT与BIT 之间的逻辑运算,修改标志位。所以 test %eax, %eax结果要为0 ,才不会引爆炸弹。 eax里面存放的是strig_not_equal的返回值, 所以eax里面的值应为 0,也就是说两个字符串应该相等。 那么很自然地就想到,我们要输入的字符串就是和程序里面的某个字符串相同的字符串。
观察代码知道 phase_1函数主要就是调用string_not_equal,传进去的参数是传给 phase_1的参数和存在内存中地址为 0x4061a2的值。
用命令查看 0x4061a2这个地址存放的值。
这里写图片描述
测试
这里写图片描述
成功!!!

Phase_2

phase有两个地方要跳过对explode_bomb函数的调用。
这里写图片描述
+27行的Cmp 是算数运算指令,也就是比较两个值,这两个值进行减法运算,结果为 0就执行je 语句。
也就是说此时 eax寄存器里面的值应该是0x1,也就是 ebp指向的地址下面24字节的地址存放的为 0x1
+9行应该是给read_six_number 函数传参,也就是说 read_six_number的参数是在-0x24(%ebp) 这个地址里的。
根据 read_six_number猜测那么很可能我们要输入的参数是一组数字。
这里写图片描述
这里包含一个循环
+60行的imul 语句里, %edx是-0xc(%ebp)+1 ,也就是 2,%eax 是-0x24(%ebp+4*0),也就是前面说的那个作为参数的地址指向的值。
重点在 +70行的cmp %eax, %edx 这里,根据前面的语句,这里的 %edx是前面那个imul 计算得到的值, %eax是-0xc24(%ebp+4*1) ,%eax是在上面 imul语句中的%eax 的基础上加上 4
83行的Coml 是决定循环的次数,应该是五次。
根据
这里写图片描述
每下一次循环 imul中的%edx 都加1, %eax都加4

要是把 -0x24(%ebp)当做数组的值,那么这里就是比较数组里的元素乘以下标加 1等不等于下一个元素。
已经知道额第一个元素是 1,那么整个数组应该是
1 2 4 120 720
这里写图片描述
成功!!!

Phase_3

这里写图片描述
这里调用了 sscanf函数,这个函数是按照一定的格式读取输入,也就是说参数里面有表示格式的信息
这里写图片描述
在call sscanf函数之前,前面的指令是传参的准备和压入返回地址,压入参数根据参数列表从有到左压的,那么 sscanf最左边那个参数是0x4061c0这个地址存储的值。
我们查到 sscanf的函数原型如下
Int sscanf( string str, string fmt, mixed var1, mixed var2 … );
  int scanf(const char *format ,[argument]… );
查看一下 0x4061c0这个地址存储的值这个地址存放的到底是什么
这里写图片描述
那么显然,这就是第二个函数原型中的 char* format信息。
这里写图片描述
根据 0x8(%esp)知道这个format 参数是作为倒数第二个参数压入的,
根据代码知道最左边的参数就是 phase_3的参数,也就是我们的输入, sscanf是从我们的输入读取除一个整型 一个char 一个整型
这里写图片描述
从这里就知道读取出来的数据存放的地方
sscanf返回后,这些地方就存上了我们输入的信息
这里写图片描述
这里是验证 sscanf有没有正确返回。因为sscanf没有出错的话,应该是返回 3的。唉,卡了我半天。
这里写图片描述
要是跳到 +269的话,会触发炸弹。所以 %eax要比0x7 小。而%eax就是前面 sscanf读取出来的第一个%d,这样就知道了输入的第一个数不能大于 7
这里写图片描述
+75 jmp因为前面有个*,程序会跳转到 0x4061cc(,%eax,4)这个地址里的值对应的地址 ….
%eax就是输出的第一个数,假设是 1,0x4061cc(,%eax,4) 就是0x4061D0
查看这个地址的值
这里写图片描述
查看 0x0040192f处的指令
这里写图片描述
比较 -0x10(%ebp)中的值也就是读取的 %d %c %d中第二个 %d的值。0xd6 换成十进制是 777。
跳到 +130再跳到+278
这里写图片描述
movzbl是带有“ 零扩展”的 mov
网上查到的 eax,ax,ah,al的关系
这里写图片描述
那么这里要求我们输入的第三个数和前面 +106赋给-0x9(%ebp) 的值一样,也就是 62,对应的字符是>
综上,我们要输入的是 1 b 214(答案不唯一)
这里写图片描述
要输入的东西太多,把前面所有结果输入 key.txt试一下
这里写图片描述
成功!!!

Phase_4

这里写图片描述
又看到有 sscanf,查看format 的信息
这里写图片描述
是一个整型
这里写图片描述
+48行的jne 是检测sscanf有没有正确返回的,不会触发炸弹
因为 %eax肯定是不会大于%eax的,所以 +42行的jg 不会执行,也不会触发炸弹。
这里写图片描述
这里说明 sscanf读出来的那个%d被当做参数传给了 func4,%eax 里面存放了 func4的返回值,那么就要求func4的返回值为 0x37
重新 debug,设置断点在func4,随便输入一个值进入 func4,查看func4 的反汇编

发现函数调用了自己,那么这就是一个递归函数
这里写图片描述
+22行的调用和+38 行的调用分别是把外层函数的参数减 1和减2 作为参数传入,然后 +27和+43 说明他是 func4(a)=func(a-1)+func(a-2)
这里写图片描述
参数小于等于 1的时候跳到+47
这里写图片描述
这里说明参数为 1或0 的时候不再递归了,直接把返回值设为 1.
也就是说 func4(0)=1,func4(1)=1, func4(a)=func(a-1)+func(a-2) ,很明显这是一个斐波那契数列
想要返回 0x37,也就是十进制的55,很容易可以知道要输入 9作为func4 的参数
输入 key.txt试一下
这里写图片描述
成功!!!

Phase_5

这里写图片描述
这里可以看出来是把 phase_5的参数传给string_length ,然后比较 string_lenth的返回值是不是6,不是就爆炸,从 string_lenth的函数名就知道了我们要输入的内容的最左边应该是长度为 6的字符串
通读代码,发现这里面应该包含了一段循环
这里写图片描述
由-0xc%ebp这里的值控制循环次数
这里写图片描述
这里可以看出来我们要使得 string_not_equal返回值为0 ,也就是 -0x14(%ebp )处的值和 0x401db2处的值相等,查看0x401db2处的值
这里写图片描述
确定了 -0x14(%ebp)处之后的的值应该是giant
找到哪里改写了 -0x14(%ebp)之后的值
这里写图片描述
这里是改变 -0x14(%ebp)+ -0xc(%ebp)处的值,也就是循环赋giant了,
依次改变以 -0x14(%ebp)为开始位置的char的数组的值
那么 g、i 、a、 n、t 就存在于 al中,寻找改变al值的语句
这里写图片描述
这里写图片描述
结合上面的 eax,ax,ah,al的关系,这一整段的作用就是取得 (0x8[%ebp]+-0xc(%ebp)) &0xf的值,作为下标取得0x4050fc中的值
查看 0x4050fc处的内存
这里写图片描述
giant分别对应 15 0 5 11 13 1
所以 (0x8[%ebp]+-0xc(%ebp)) &0xf要取得15 0 5 11 13 1
其中 0x8[%ebp]是我们输入的内容的地址 -0xc(%ebp)是循环计数,也就是说我们输入的内容写成 ASCII码应该是
xf x0 x5 xb xd x1 x 表示任取
随便取得 3f 30 35 3b 3d 31
? 0 5 ; = 1
测试
这里写图片描述
这里写图片描述

Phase_6

猜你喜欢

转载自blog.csdn.net/u010223904/article/details/47219967