bomb lab 的实验挺好玩的,实质上就是逆向分析,然后找到正确的输入,错误的输入会导致跳转”炸弹函数”,就会导致程序结束;

规则:

根据提示,我们不能调试,但可以使用逆向工程解决炸弹;

输入正确的字符串以拆除炸弹;

源码中没有什么有用信息,不过有提示,从代码中可看出有6个需要解决的炸弹;

main

进入IDA分析后,可以发现函数栏有main以及 phase_1 ~ phase_6;

在puts函数之前的判断函数与破解炸弹没什么大关系,所以直接跳过;

main

直接分析phase;(终于找到图床了)

Phase_1

首先进入phase_1,只有6条汇编码;

phase_1汇编

首先进栈,然后设置对比字符串esi,呼叫函数比较两个值,将返回值传给eax,然后不是0的时候就爆炸;

所以只需要输入“加拿大的边境问题”就可以解除炸弹1;

“Border relations with Canada have never been better.”

Phase_2

phase_2

其实phase2的汇编也比较简单,但这里用伪代码能截图直接截满,可以更好地说明;

在read six number 里会有一个判断爆炸,之后&v3的判断和&v4的判断,只要满足这三个条件,就行了,那就来看看它们的条件是什么;

readsix

可以发现三个判断和&v4,&v3有关系,&v4和&v3是存在于栈中,在汇编码中,把rsp指向的地址传送给了rsi(输入数据),意思就是使输入的数据入栈了;

汇编

那很明显是让输入数据的某个部分成为了&v4和&v3,然后去判断;

①read six number 里让输入6个数字都正确就继续,否则炸;

②v3(rsp)指向的值需要是1,否则爆炸,而rsp指向的是rsi,第一个数据,所以第一个数必须是1;

③v4(rsp+4)的上一个数据乘上2需要和v4相同,不然爆炸,所以1的后面是2,2的后面是4,等等;

所以只需要输入 1 2 4 8 16 32;6个数字就可以解除炸弹2;

Phase_3

phase3

开始也是读入2个数据判断(read two number),正确就通过,否则就炸;

输入进去的两个数字会成为v8(rsp+8h),v9(rsp+Ch)的存在,而往后是一个switch选择,根据v8选择;

switch

之后从switch中的数据里与v9比较,如果不同,炸弹爆炸;

cmp

所以我直接写一个最简单的就是 0 207 就解决炸弹3;

simple

Phase_4

phase4

一开始也同phase2一样,判断了输入的数据个数,需要是2个,不然就会跳转爆炸;紧接着比较v8(rsp+8h)和E(14),如果大于了14,也会导致跳转爆炸;

在phase4的后面一部分,会用func4函数运算result,之后result与v9(rsp+Ch)进行逻辑或运算要使得结果为0,不然爆炸;

而func4函数如图所示:

func4

phase4中运用func函数的最开始的参数是 v8 ,0,14;可以看出这是个递归函数,而且越递越复杂;

v3第一轮就应该是7;

它比较的就是7和v8了,但它漏了v8=7的时候,所以当v8=7的时候,就不会调用递归了,直接让result=0;

所以我们让输入成为 7 0 就可以解除第四炸弹;

Phase_5

phase5

这道属于baby级别的逆向CTF了;

输入的字符串需要为6的长度,之后用box里的字典来运算出v3的值,之后比较v3和”flyers”字符串,如果不满足以上情况,炸弹爆炸;

box

那思路就很简单了,就是解方程,比如第一个会是f,那么让f = box[input[1] & 0xF],f在box里的下标是9,所以 9 = x & 0xF,我们求6次这样的x就行了;

最后得出输入数据为:IONEFG,解决第五炸弹;

Phase_6

while1

这是进入phase6之后的代码;也是需要读入6个正确数据,然后进行第一个循环,这个循环要求每个输入的数字小于等于6,且每个数字都不相等;

while2

v16是rsp+18h,而我们输入了24个字节的数据;所以v16代表我们输入的字符,这个循环是让输入的数据成为每个对应位置的自己求负然后加上7,ascii码对应时退出,看起来像是在把数据颠倒,因为数只能是 0 1 2 3 4 5 6;

while3

第三个循环判断每个数据,之后做出不同的操作;如果大于1,就会让node1里的第v8个下标的值成为v6,不然v6=node1[0];

之后让v17[2*i] = v6,v17是rsp+20h;v17就对应了node1~node6;

while4

v18是rsp+28h;也就是v17的第二个数据;v19是rsp+50h;

第一个循环是挪位,然后当v10与v19相等时退出;

第二个循环是v9的后一个数必须小于前一个数,不然爆炸;v9就为node系列;

然后就IDA突发恶疾把数据定义成命令了,然后就看不懂了;

之后解除定义后,让node按序排列就成了;

顺序是node3,node4,node5,node6,node1,node2;

输入便是4 3 2 1 6 5;

deal

总结

相较于data lab,这个实验更简单一点,可能是因为本身就是逆向学的原因,做了这个东西过后对汇编理解更深刻,以及栈的处理,而且觉得逆向并不困难,困难的是不认识的加密形式和一开始看不懂的垃圾代码,如果能够多看多做,学会更多的加密方式和认识更多的垃圾代码,根据数据和逻辑便能够猜出一个大概,然后就是不断地去调试了;

继续加油⑧~

genshin