写在前面:
你也许会因为做不出来感到很苦恼。如果我说我当时我曾和你一样困扰,到处抄熬了很多个晚上才做出来,即使做完了实验也感觉没有完全弄懂是为什么,你会好一些吗?
看不懂汇编也没关系,千万别慌。冷静下来一步一步调试,或者用工具辅助就能做出来的。
这篇文章中使用pwngdb进行调试,这个工具比gdb好用一些,能直观不少。如果没有的话可以去安装一个。
然后就是做bomblab的一点心得:
前几个用ida逆向出来的c代码可以自己看,也可以配合gpt可以直接出答案。最后一个需要手动看代码,链表排序题。找到链表就做出来一半了。可能的情况只有条件A:正序,倒序 条件B:7-,没有7-,两个条件每隔条件里两个小条件,共四种情况。实在搞不懂挨个试即可,在爆炸之前pwngdb会有提示,ni到前一步停下退出就行。
正文:
回归正题,首先这张图片。因为我们第一次做的时候不知道答案,就会随便输入一个进行测试。想要防止炸弹再下一步ni之后爆炸。每一步调试后,我们需要检查的部分就是DISASM这部分:
先不用管这些代码表示程序在做什么。我们只需要关注操作码部分,像是mov sub xor add 之类的都是很安全的操作,遇到了可以直接步进,很安全。要特别注意的是jg jmp之类的跳转的语句,它们一般都跟在 cmp 之类比较操作后面,以此程序才能完成条件判断。
我们需要看着jmp的下一句究竟跳到哪里了,pwngdb会在绿色箭头下面多给出未来的几步,没有↓就是顺序步进,否则就是跳转到其他部分。如果看到跳转完之后还是很正常的sub xor mov之类,就不用过多担心。还有call 如果在未来几步炸弹会爆炸,那么你就可以看到一个call explode_bomb,这个时候就不要再继续了,答案已经错了,步进到这一步炸弹就会爆炸,于是Ctrl+c退出。
看我下面这个就是答案试错,条件判断没有跳转走,下面炸弹马上爆炸了。
同时还需要关注其他的一些函数,比如这个题其实要输入6个数字,但是你用111进行测试。那么在进行call read_six_number以及其scanff条件比对的时候就可能会爆炸。这时候就要小心了。
如果可以看懂一部分命令的话,看炸蛋爆炸前几步比较了什么,你大概就能知道是为什么爆炸。这个时候就会有修改答案的思路。比如我上面这个,0x56556afc行比较了0x376和0x350,前者大于后者,跳转失败,炸蛋爆炸。这个十六进制376和350就是我链表节点的值,那么就证明我的排序错了。