记录一次学校实验Bomb Lab
技术30-11-2023
前言
这是学校的某课程的最终实验课。其实也就是大名鼎鼎的CS:APP Bomb Lab,即阅读汇编拆炸弹。
这也是我为什么要进行记录的原因。
实验预计耗时:学校给了20天的时间。
我的耗时约6小时:当天实验课+晚上睡前2小时+今天早上一小时(11.29-11.30)
使用工具:objdump+gdb(使用了插件pwndbg进行高亮)
建议:不借助任何高级的逆向工具,使用原生的objdump+gdb,这样才能达到本次实验的训练效果。
经验
本次实验有很多快速破题技巧,我在做到后面的时候,才开始觉悟。
- 关注cmp,即限定条件
- 关注地址值,对应到题目就是内容为破题点
- 猜测逻辑,每个炸弹对应一个概念,你可以猜测这概念之下代码会什么样的
- 回溯破题,逆着来不一定好,因为循环+条件会有很多分支,从结果导向,逆出来的分支链路会比正向少了很多
一、炸弹一:字符串比较
通过读给出的C源代码,可以知道交互逻辑为读取、调用解析判断。
反编译定位main。
找到第一个函数的地址,进入查看他的代码。
我们找到了比较的地址。接着就是去调试查看地址里面的内容。
输入验证,答案正确。
二、炸弹二:循环
继续上面的代码跟进,查看第二个实验的代码逻辑。
显然是读取6个数,然后循环判断,我们要过了这个炸弹,目标即绕过即可。重点关注比较的逻辑上下文,大体是,不能小于0,后面的话后一个元素等于前一个元素加索引。
于是构造数列:0, 1, 3, 6, 10, 15
验证!通过。
三、炸弹三:条件分支
继续审计代码。
这回代码的意思是条件分支,所以我们可以大体猜测他的逻辑就是:输入,匹配,通过。
所以我们可以从结果导向,从汇编出口开始,逆向追回整个可选分支链。
最终发现,最终的目标就是让分支赋值的变量,和我们的第二个参数一样,而第一个参数选择,分支。这样简单。我们随便选择构造一个即可。这里我选择0 464,验证通过。
四、炸弹四:递归
这题是递归,我的猜想是,显然是根据有一个回溯,然后根据返回结果来判断是否通过。我们审计汇编代码,也发现确实是如此。
这里调用了func4函数,要求返回结果为27,输入参数的话,要求第一个不能大于14,且第二个要。为27。那么我们来看一下func4函数的逻辑。
显然,他是一个双分支的回溯调用。因为对着猜数列太难了。所以直接写代码!
所以可行解为9 27,验证成功!
五、炸弹五:指针
听到这个标题,我的想法是考我们地址和地址里面的内容的区别,不知道是不是,看一下汇编。
看开头可以知道,参数限制长度为6.输入内容为字符串。
后面半段,主要是对字符串进行循环处理,然后比较判断。最终是一个值,这里用类ASCII编码的知识。最终绕过条件为值55。所以我们要构造。他对输出的处理如下:*arry++ & 0xF,而对值加的内容,是又另外一个数组。我们通过gdb去看这个数组内容。
我们选择0,1,2,4,5,6。接着就是什么字符0xf为这些索引了。直接写脚本吧。
最终验证成功!
六、炸弹六:链表/指针/结构体
还是老套路,直接看汇编代码。发现这次有点长,那就分段来看。
首先是第一个循环:
他的意思为:所有数不大于6,且两两不相等。
接着往下面看,可以发现,依旧是一个循环。
结合上面情况,可以知道是结合node在进行操作。
总结上面循环的作为为:根据输入数字的索引,取node里面取值存入新的数组中。然后下面的循环就是对节点进行链化操作。
最后是对链表进行检测,进行5次,每个小于后面即可绕过。故可解为6 3 1 5 4 2。验证通过。
七、炸弹七:彩蛋
在做上面那题过程中,其实我已经注意到了彩蛋。
且吸取上面的一些操作,下面解决非常快。我们快速溯源谁调用了他。发现是输出成功函数。
这里有一系列参数移动操作,我们定位看一下内容。发现就是炸弹4的输入嘛。
溯源触发条件。
是这样一个字符串。
目前,破解全部完成,接着就是常规老套路的读函数汇编了。
熟悉的感觉,一眼就是二叉树?为啥,因为我看到0xfffffffff,写算法题我经常这样操作。思路差不多这样。
观察到是一个二叉树。看树的内容。
画出图来观察,应该是下面这种情况。
因为如果找到n,返回0。递归左子树为2result,递归右子树为2result+1。而绕过条件如下:
所以遍历顺序的可选方式为右。即0x32.(50).验证通过。
感慨
拍摄于我的另外一个实验室(学校有两个,这个比较少来)
现在是11月30日,11月的最后一天,而我的桌面日历是9月。这学期累爆了,周末也要上课,很多时候都在做一些无意义的事情,加上星期比赛忘记请假被记录旷课,内心对课内学习的压抑上到了极点。但有时候觉得自己这样其实也算好的,很多人为课内花费了比我更多的精力。我写实验是比较快的,这学期的实验我基本都是当天发实验,当堂就能结束。现在所有实验室课的作业都完成了,就差一个每天都要早八去打卡的Java实验,以及期末最后的课程实训。
可能过去我会把实验写得认真一些,但是自从我上学期写的代码,老师就只是简单跑一下输入输出之后,我便不在想花心思在课程实验。美其名曰课程设计,但是完全无视我在代码中运用的设计模式,无视我在程序中提升的鲁棒性。我觉得我花时间做一个完美的程序,也和其他同学一样。所以这学期我把大部分精力用来做自己的事情。去参加技术交流会。听了一些逆天发言,深感这种产学的脱轨。
不过有时候,想了想,其实当个纯朴的人也挺好的,你懂得多,能力大,你的烦恼就会更多。我挺希望自己比较无知,可以选择的东西少一些,这样我就不会太烦了。当一个纯朴的人,不在乎那么多,其实开开心心的,也过得不会那么差。对于我这种单核单线程的人来说,只能专注于一件事。大二我已经不想希望多自由了,希望大三的时候,不会卡我太多规划吧。