Bomb lab

第二个lab啊,总的来说就是通过这个lab学会了好多linux指令以及gdb用法...这里就简单说一下思路吧


上来先是几个常用的命令吧(表示以前都不知道果然是小弱啊....)

strings -t x 文件名 可以将文件中的字符串都打印出来,-t x附带16进制地址

vim下 :split 上下分屏,vsplit左右分屏,后面可以加文件名在分屏的同时打开文件,ctrl+w切换屏幕,close关闭当前屏幕

gdb:print/x 可以将输出切成16进制显示,x/w输出一个字节的内容,x/2w输出两个字节的内容,以此类推

   b +函数名设置断点,b +*地址在制定地址设置断点

   d 1将标号为1的断点删除,以此类推d 2,d 3....d直接回车删除所有断点

   在断点停止后c继续执行

   run运行程序,后面可以加程序运行时需要的参数,比如这个lab可以把已经通过的字符串卸载文件里(比如psol.txt),然后run psol.txt

   kil杀死运行中程序

貌似这个lab里需要用的就这些,神马单步执行啊、查看寄存器的值啊我都没用上...(好吧其实是不会用)..如果有漏掉的回来再补充

另外在writeup给出的地址可以下一个gdb的说明,挺实用的


正式工作之前一定要好好看书,尤其是64位的部分

至少要知道传参时的寄存器地址,依次是:rdi, rsi, rdx, rcx, r8, r9.....

还有一个要知道的是sscanf的函数原型

int sscanf( const char *, const char *, ...);

返回值是成功读取值的个数,第一个字符串是源,第二个串是格式,后面参数个数不定

lab里面除了phase1都要用到sscanf,每一次调用结束后都会检查返回值是否是所需要的个数,不是的话直接爆掉,但是元素个数比需求多是没关系的,而且因为每一个phase是按行读也不会对后面产生影响,secret_phase就用到了这一点


第一步先在linux下objdump -d bomb > ***出汇编代码,strings -t bomb > ***把所有可打印的字符都输出出来(姑且把这个文件叫str吧)

gdb bomb之后先b explode_bomb加断点,这样基本上不手滑点c+enter是炸不了的....

屏幕够大的话vim用split命令多显示几个文本,我这里是显示两个代码+psol.txt/str,这样的话方便一些

再开一个终端运行gdb

准备工作就完成了


接下来就是愉快的拆炸弹了= =

phase _1 代码非常短,看到strings_not_equal直接就能猜出来是干啥的了= =然后进str文件找到对应地址的字符串,pass

phase _2 我花了很长时间研究了read_six_numbers是怎么回事,最后发现原来就是顺序的读六个数....

mov %rsp, %rsi 将数组的首地址(即rsp)传给read函数,然后调用函数读取这六个数

后面就是判断这六个数是否满足条件了,一个循环,不太难看出来

phase_3 代码好长...但是实际上不太难,先看看sscanf的参数是啥,按地址进str文件发现格式字符串是%d %c %d,两个整数一个字符

看到jmpq *意识到这大概是一个switch,中间的代码还很人性的用00给分割开了= =

然后gdb下用 x/数字w 看一下跳转表,然后再分析一下代码就ok了

phase_4 这个代码好短!最后发现居然是递归....照例先看sscanf参数, 开始没找到字符串,后来发现是和前面那六个数共用了最后两个%d

然后根据汇编代码把递归函数大致写出来,带着未知数解一下方程算出所需数字即可

phase_5 跟踪一段内存中的数组,跳转的比较烦==(原谅我记不太清这个phase具体的实现了....)

phase_6 代码又是很长==仔细看了看可以分成三段,上来先看输入数据是不是在范围内,第二段则是判断输入数字是否有重复,最后一段要给链表排序,/x 看看那个地址直接显示了node1==这个排序折腾了我三个小时...犯了个很脑残的错误

secret_phase 神秘的隐藏关。直接在vim里命令模式下/secret_phase,发现在phase_defused这个函数中被调用,既然如此就先读一下代码吧><,上来就看到一个跳转,前面是和6作比较,<6直接跳到结束,再看前面调用函数有说明num_input_strings,猜测大概是判断已经读取字符串的数目,过了6个才能过隐藏关嘛~于是在跳转后面的语句加上断点,run之后果然在6关全过后停了下来。接下来是个sscanf,但是读取的地址有些奇怪,0x603e30,过去看一样没发现什么,再然后是一个比较两个字符串是否相等,看起来是要从刚才的地址读取一个字符串然后和已知字符串比较,相同才能进实验关。sscanf格式化字符串是%d %d %s,于是再前往那个地址看了一看,这个地址目前是有数据的,于是先查ascii码表看看这是什么字符,咦?奇怪,这两个数字好眼熟....等等,这不是我刚才第四题输入的数字么= =...好吧,果断在第四题后面补上需要的字符串LovelyYoyo,再run,成功进入隐藏关~(据说正确的做法应该是研究read_line函数?==)进了隐藏关之后就比较简单了,建议直接把代码随便画画翻译成类似高级语言的形式,这里的数据结构应该是二叉树。


敲入数字,All Finished!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值