CA2_BombLab记录

前言

Todo:晚上再补充内容

强烈建议做这个lab之前先看完CSAPP对应部分以及网课对应部分,特别是要把常用寄存器的作用搞明白

第一题

先观察bomb.c文件,发现有几个重要的函数,其中phase_1phase_6是我们需要破解的,read_line是用来读取用户输入的,phase_defused是用来输出破解成功的信息的,explode_bomb是用来输出破解失败的信息的

第一题我们可以先在phase_1处打上断点,然后随便输入一个值,观察情况

phase_1及其短小,其中有一个地址0x402400,我们用x/s 0x402400查看一下,发现是一个字符串Border relations with Canada have never been better.,就得到答案了

第二题

首先对phase_2打上断点,然后随便输入一个值

发现会首先调用read_six_numbers,暗示我们应该输入6个数字0x400f0a处有cmpl $0x1,(%rsp)其后面一行是je 0x400f30 <phase_2+52>说明返回值必须为1

所以给read_six_numbers打上断点,看看它在干什么

`read_six_numbers`

发现有一连串的操作,挺绕的,先继续往下看到有一个地址0x4025c3,用x/s查看一下,发现内容是”%d %d %d %d %d %d”,外加0x40148f处的 cmp $0x5,%eax(成功读取的数值不是6就直接引爆炸弹) 说明我们确实应该输入6个数字.

退出之前在仔细观察一下那一些leaq指令发现他们是以rsi寄存器中存储的地址为基准的,再回头看看phase_2的代码,我们发现它在调用read_six_numbers之前申请了0x28位地址空间,然后把栈顶指针rsp赋值给了rsi(作为参数传递),所以这个read_six_numbers函数是通过栈来传递参数的

`传递参数`

我尝试输入 1 2 3 4 5 6,然后在read_six_numbers退出的时候参看栈的情况

`查看内存`

我的猜测是正确的,我们的输入被逆序压入栈中(一个int类型占用4bytes)

继续往下看,发现下一行语句是cmpl $0x1,(%rsp),而rsp处存储第一个输入,所以第一个数是1,再分析这些语句

`程序逻辑`

我们发现有一个循环,每循环一次数值*2,直到循环结束,所以答案是1 2 4 8 16 32

第三题

`第三题`

首先对Phase_3打上断点,然后随便输入一个值

`phase_3`

发现一个地址,用x/s 0x4025cf查看,

`查看地址`

根据Phase_2的经验,我们应该要输入两个数字
继续往下看,0x400f60处的cmp $0x1,%eax也表明我们至少要输入两个数字,否则直接explode_bomb
重新随便输入两个数字,发现0x400f6a处的cmpl $0x7,0x8(%rsp),rsp是栈指针,0x8(%rsp)是我们输入的第一个元素,所以说明我们输入的第一个数字不能大于7

`第一个数字不能大于7`

接下来就是重点了,我们看见0x400f75处有指令jmp *0x402470(,%rax,8)

`大坑`

这是一个大坑,这条指令表示直接跳转到 0x402470 + M8 所存储的地址处(而不是 0x402470 + M8 处!!!)

使用x/x查看0x402470处的内容

`查看内存`

发现是一连串地址(顺序是从右到左是因为Intel处理器采用的是小端排序)
对应关系

`一连串地址`

上面若干跳转最后都变成比较第二个数和 %eax 中数是否相等,所以第一个数字和第二个数字有对应关系:

第一个数字 第二个数字十六进制 第二个数字十进制
0 cf 207
1 137 311
2 2c3 707
3 100 256
4 185 389
5 ce 206
6 2aa 682
7 147 327

答案是任意一个都行,比如第一个数字是 0,第二个数字是 207

第四题

照常给phase_4打上断点,我们发现依旧是输入两个数字

0x40102e处的cmpl $0xe,0x8(%rsp)0x401033处的jbe 0x40103a <phase_4+46>表示第一个数字必须小于0xe

0x401058处发现它会调用func4,通过观察,似乎edi,esi,edx寄存器被作为参数传递给了func4

继续往后看,发现0x40104d处的test %eax,%eax0x40104f处的jne 0x401058 <phase_4+76>表示eax(返回值)必须等于0
然后,在第0x401051行,cmpl $0x0,0xc(%rsp),第0x401056je 0x40105d <phase_4+81>得出第二个参数应该是0

打一个断点,看func4到底在搞什么东西😁

很明显,这是一个递归,在网上找了一张流程图(我画的太丑了,不想放上来😂)

通过流程图可以看出,有一条路是不用走递归的,(就是最左边一条)

所以edi(就是我们输入的第一个参数)应该是7

所以输入应该是7 0

第五题

照常打上断点,随便输入一个值

发现有调用string_length函数,所以我们应该输入一个字符串
仔细下一行我们可以看出字符串长度应该为6

发现了一个地址,指向的字符串是“maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?”明显长度不对

给那一行打上断点,查看运行至那一行时候的rdx寄存器的值,然后用x/s查看0x4024b0的字符串,发现是“secret phase!”靠,又被摆了一道,看来不能投机取巧,只能慢慢分析了

往后看,就会发现有一个地址0x40245e似乎被传递给了strings_not_equal,对应的字符串是“flyers” ,长度是对的,应该就是目标字符串了

所以,应该分析循环的逻辑

逻辑有点复杂,所以我画了一张流程图来辅助理解

可以看出,“Flyers”对应字符串“maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?”中的位置分别是9,15,14,5,6,7,我们需要让我们输入的字符串模16得到的数是这几个数

为了方便,我选取了ionefg

第六题

第六题的代码很长,我先把它分成几个部分

第一部分

照常打上断点,随便输入一个值

发现在经历了一系列栈操作后,又调用了read_six_numbers函数,根据第二题的经验,输入的6个数字会被依次逆序压入栈中,分别存储在%rsp%rsp+4%rsp+8%rsp+12%rsp+16%rsp+20

虽然这个函数的代码很长,有很多跳转语句,但是经过仔细观察,我发现可以大致分为几个部分

第一部分依次遍历每个元素,保证各个元素在1-6之间且不相等

第二部分

第二部分用7-数组的逐个元素,并更新各个数组元素

0x401183处我们发现了一个地址,使用x/128x查看附近的内存,我们发现它是叫node_n,其中每个node偏移8位的位置指向下一个node,所以它是一个链表

第三部分

接下来就进入了第三部分

经过分析,我们发现第二个部分是把各节点的地址依次存放进栈中

我们查看一下内存的情况,发现在0x7fffffffda300x7fffffffda50处依次存储着各个值,这些值的顺序是我们输入数字的顺序

第四部分

第四部分是验证数据(存储在rsp+20开始的指针序列)是否是按照逆序排列

按照逆序,应该是3 4 5 6 1 2所以指针应该是(顺序是node3->node4->node5->node6->node1->node2)

node中数据的排序3 4 5 6 1 2,所以输入4 3 2 1 6 5

结束!

Todo:似乎还有隐藏彩蛋,等以后分析


CA2_BombLab记录
https://20040702.xyz/2023/09/10/BombLab/
作者
Seeker
发布于
2023年9月10日
许可协议