CSAPP:bomblab

这次的实验真的挺有意思的,但是枯燥的汇编代码,实在是让我非常捉急,晦涩难懂,真的还好有汇编器这种东西的出现,否则真的贼要命啊去编写汇编。这次的实验让我增长了见识,还有熟悉地练习了一下gdb,使自己对逆向工程加深了一定见解。

http://csapp.cs.cmu.edu/3e/labs.html

刚开始下载完程序之后,我们并不知道自己该干些什么事情,看看文档writeup,不过反正看起来人家说得挺清楚,就是让你是拆炸弹,又怎么拆?我们先看一下目录。


这里只提供了3个文件,而且README也没说什么。我们直接看看 bomb.c吧。

好像每一行都有一个这样的东西,我们先记住。
尝试运行下 ./bomb,然后随便输入点东西?
CSAPP:bomblab_第1张图片

确实炸了哦,又怎么回事?这给我第一个感觉就是 输入某些东西,如果不正确就错误,其实我第一个实验刚开始也不特别会,因为不会gdb,所以觉得很懵逼,我也是稍微参考了一下别人,才开始做了第一个实验(gdb先稍微自学一下,网上教程很多)。
好,从 gdb bomb进入。

l 进入以后输入此命令,查看一下源码,然后break 37,将源码定位在37行,然后run,然后disas,看看main函数的反编译,密密麻麻的好像没什么提示,我们想找爆的源在哪。再试试disas phase_1


稍微看看汇编码,完完全全好像就是这么 感觉的回事,我们要输入某些东西,使其避开 explode_bomb(顾名思义)

一,phase_1

好吧我们一步步来解开这些谜团吧。
disas phase_1

CSAPP:bomblab_第2张图片

稍微看看二进制码,很晕哦,但我们隐约记得 %esi是第一个参数入口,然后还调用了 strings_not_equal函数比较,难道第一个拆炸弹行为就是对比一下字符串想不想等,不相等就爆炸,那这个 0x402400,是个什么东西。我们使用 x命令访问一下, x 0x402400


果然出现了一串字符串,再看看这么短的汇编码,毫无疑问,这就是答案了。

答案:Border relations with Canada have never been better.

二,phase_2

上面做通了下面这道题也会做得很快,其实道理一样,无非就看看寄存器,和内存给你的信息罢了,这是最简单的方式,好吧,我们继续用最笨的方法来解决这次的爆炸。
break phase_2同样的,我们先设置断点在第二个阶段函数。
disas phase_2

CSAPP:bomblab_第3张图片

前4段特别好理解其实就是先申请一堆空间,我们暂时不管他,我们可以看到 read_six_numbers,再次 顾名思义,他要我们输入6个数字,其实看到这里我们已经可以不管了, run一下,随便输入6个数字即可,不管我们还是看看里面的究竟 disas read_six_numbers
CSAPP:bomblab_第4张图片

简略的看一看,里面就是有个 sscanf读入,而且不正确读入的话也会引发炸弹,我们继续对照函数的调用,看到又有一个地方特别神奇,完完整整是一个地址。然后我查了一查 sscanf的声明: int sscanf( const char *buffer, const char *format, [ argument ] ... );,第2个参数是输入格式,那么刚好对照我们的 [ $0x4025c3,%esi ],怎么验证我们是正确的呢? x/s $esi

真的要我们设置一个读入六个参数的设置。剩下的就不用看了,我们就正常 run,输入六个参数。
disas phase_2再次回到函数 phase_2
CSAPP:bomblab_第5张图片

我们先从 ( 1 )看起,这句话给了我们一个提示,我们第一个参数要是 < 1 >,然后成功的话跳转到 [ lea 0x4(%rsp),%rbx ]( 3 )段中,这里的 [ 0x18(%rsp),%rbp ],这里的 rbp一看就知道是个终结位置,因为6个整形大小就是 0x18 = 24B,然后我们跳到第 ( 2 )段去,着段码也很好理解,不就是 获取前一个位置的数存入寄存%eax,然后 %eax *=2,这不就是就告诉我们这个阶段要的答案是 以1开头的,后一个数比前一个数大2倍的序列吗?,显而易见。

答案:1 2 4 8 16 32

三,phase_3

disas phase_3不必多说,继续看反汇编码。

CSAPP:bomblab_第6张图片

x/s 0x4025cf看到又有一个常数放在第2参数读入了吧?想都不想,直接输出看看。

这次要读入两个整数。这两个整数又是什么呢?
CSAPP:bomblab_第7张图片

( 1 )就告诉我们第一个数字必须是 小于7,然后接着是一个多个选择,我就不解释了,这很容易看懂,然后第 ( 3 )我们看到一个比较 [ $0x137,%eax ],这个数字必须是 等于的否则就会引爆炸弹,所以 print 0x137

所以答案就很容易推算出来。好像这道题有多种答案,但最后一个是确定的,因为我就输入这两个就过了,分支我也没看下去。

答案:1 311

四,phase_4

disas phase_4

CSAPP:bomblab_第8张图片

估计也知道我想说什么了,没错先看看输入的是什么。
x/s 0x4025cf


( 2 )个阶段已经告诉我们了,我们的第 < 1 >个数必须是 小于14
CSAPP:bomblab_第9张图片

从第 ( 1 )个阶段我们可以看到它将我们第 < 1 >个数值输入到函数当中,并且要返回一个 才能跳过炸弹,从第 ( 2 )个阶段中自然解出第 < 2 >个数值必须是 。那么我们现在看看 fun是个什么东西。
disas func4
CSAPP:bomblab_第10张图片

反正我看着就觉得烦,所以有研究的同学可以自己去观察一下这是什么意思。因为这个函数里面根本没有炸弹,我们可以把它直接当作 黑盒测试
我们尝试着输入8,0 5,0 4,0... 你会发通过func函数返回,好像就是 log2(< 1 >)。怎么看呢我们可以看看上面那张图的 ( 1 )阶段通过 print $eax测试call完函数之后的返回值,只要是0就是答案。所以很容易推出来答案是什么。

答案:1 0

五,phase_5

disas phase_5

CSAPP:bomblab_第11张图片

首先,从着两段看出,我们得随便先输入一个字符串。这个字符串只有6个字母大小。
CSAPP:bomblab_第12张图片

我们首先看看第( 2 )段,这里要比较一下两个字符串是否相等那么,同时又有新的发现[ $0x40245e,%esi ]想都不用想,先输出来看一下先,x 0x40245e


我们要输出的是一个和这个字符串相同的字符串,假设我刚刚在 run时输入了 123456,我看一看我的字符串变成什么样子了。 x ($rsp+0x10)

明显这两个字符串不是一回事情。这时候我们就看看 ( 1 )究竟做了什么操作,其实这上面也很简单,看看就懂,我们主要关注的是这句话 [ and $0xf,%edx ]它把我们的字符相与了0xf。然后好像从字符串找找出对应字符来。这个字符串又是什么? x (0x4024b0)

瞬间恍然大悟,炸弹的拆除方法,就是从 将每个字符的低4位作为索引,从中找到的字符串组合起来,使其能够成为flyers。那么我们该输入怎么样的字符串,才是对应的索引呢?别着急。在linux下输入 man ascii
CSAPP:bomblab_第13张图片

我们从 第64的字符编码@开始,依次输入 16个编码,通过 x ($rsp+0x10),就可以找到映射关系,然后就可以找到答案了。这个答案有很多个。但原理就是 取每个字符的低4位作为索引,这也就为什么我说只要 依次输入16个编码即可。

答案:9o>567

六,phase_6

这段代码实在有点长,而且比较难读懂,只能自己一点点手推代码。稍微不细心就会很心乱。我们还是一步步来吧,这个还是得自己手写一下,否则的话也是看得半懵状态,因为这个代码实在太难解释了,我就说说大概定位的每段的意思,也方便你来自己定位断点。
disas phase_6

CSAPP:bomblab_第14张图片

还是原来很老的处理,先读入6个数字,这个上边已经叙述过,直接输入6个数字即可。
然后我们继续往下看
CSAPP:bomblab_第15张图片

这段代码其实是这样的:在 ( 1 )中,输入的 每一个数字-1必须 小于等于5( 2 )并且每一个数字都不能相等。所以我们输入的数字都是如何1,2,3,4,5,6这样才合法。
继续往下看
CSAPP:bomblab_第16张图片

这段代码的意思就是:就是 7-每一个数字,例如刚刚的1,2,4,3,5,6得到的就是6,5,3,4,2,1。
前面这两段都很好理解,接下来这段如果不知道某些东西就gg了。
CSAPP:bomblab_第17张图片

这段代码就是,将某些东西进行排序?没错又有一段很神奇的代码[ $0x6032d0,%edx ],我一开始我也不会看这是什么回事我以为是字符串或者什么的,这要输入下面的命令x/24xw 0x6032d0,你如果一开始使用x 0x6032d0你就会发现有一个node1的出来,要多加几个读入才能输出完整的链,所以x命令后面加了个24。

CSAPP:bomblab_第18张图片

这一看就知道就是个结构体,那么上面的代码的意思其实是:按照相减少之后的排序每个节点重新排列一遍,如果按照1,2,4,3,5,6得到的输出6,5,3,4,2,1,那么排序就是第6个节点排第1,第5个节点排第2,第3个节点排第3...

struct 
{
    int value;
    int order;
    tag* next;
} tag;

接着再往下看

CSAPP:bomblab_第19张图片

( 1 )段很好理解,只是判断是否已经到了链的尾部,最重要的是第 ( 2 )段,它表示前一个节点的值必须比后一个节点的值大。这答案就出来了啊。

答案:4 3 2 1 6 5

我可能不一定完全能让你全懂,代码还是得自己试读,我只能提供一个启发,你自己去试试。突然发现实验居然能这样子做,真的有意思。

你可能感兴趣的:(CSAPP:bomblab)