首先反汇编代码,objdump –d bomb > asm.txt,对bomb进行反汇编并将汇编代码输出到asm.txt中。
目录
phase_1
上述反汇编代码显示将0x804a044压栈后直接调用了strings_not_equal函数,意味着phase_1在你输入字符串后直接比对。
所以可以直接gdb查看0x804a044中的字符串,可以使用examine命令(简写是x)来查看内存地址中的值,/s是内存中为字符串格式。
提交后显示如下:
phase_2
显然,在0x8048b6a处调用了函数read_six_number,其反汇编如下:
然后gdb查看了0x804a203处的字符串发现是要获取6个数字
所以画处相应的地址,其中ebx寄存器存储循环次数,eax存储数字,由8048b88处cmp比较得知eax数字变化规律是array[i+1]=array[i]+i;随机取第一个数字为1,得出数组1,2,4,7,11,16
提交后如下:
phase_3
首先观察到在把eax压入栈后又压栈了0x804a20f这个地址,故gdb查看发现是要获取两个数字
联系上面的ebp-10h和ebp-14h得知两个数字存在这两个地址处,0x8048be4处的代码显示ebp-14h处的数字不能超过7,然后下面是一个switch选择语句,尝试输入0,0x26d对应的十进制621,结果如下:
phase_4
首先分析phase_4,和phase_3相同,0x804a20f是要获取两个数字设为num1和num2,分别存在ebp-14h和ebp-10h,然后看到8048cdd处cmp说明了num1不能大于14,下面就调用了fun4函数。因为注意到下面8048cff处要使num2与3相等,所以可以确定num2=3。
然后分析fun4函数,
首先由上可知,phase_4调用的fun4函数的参数形式为fun4(num1,0,14),
观察func4函数,没想出如何解答,暂时性直接穷举,发现13是可行的
结果如下:
phase_5
取eax的低4位,如果其后四位全为1则爆炸。
查看8048d6b处回溯的数组,以十六进制格式输出:
排序结果如下:
0 1 2 3 4 5 6 7 8 9 a b c d e f
a 2 e 7 8 c f b 0 4 1 d 3 9 6 5
依据循环规则,在15次循环中,eax不能取到f,利用反推法,如果取到f ,则上一次eax就为6, 上一次就是6-e,依此类推,顺序为
6,e,2,1,a,0,8,4,9,d,b,7,3,c,5,说明eax第一个值为5
又因为在这个循环中,eax和的值存储在ecx中,
而上面这个cmp则说明这个循环的和应该等于输入的第二个参数即可
故用gdb命令打印寄存器的值来查看ecx的值,发现是115
结果如下:
phase_6
分析如下:一开始读到call 0x804910b <read_six_numbers>,得知这是要输入6个数
然后经过一连串的循环说明这六个数都小于等于6,且各不相同。
上述代码给出了链表的排序和跳出的条件,然后在下面重新对链表进行排序,即调整数值
故只需查看链表的头地址0x804c13c后存的链表的六个元素,重新将其进行排序
解析:p/x按地址顺序打印
第一个地址为0x804c13c,存储了第一个数字0x15d,后面的0x1是标号;
依此类推,第二到六个分别是0x38a,0x21a,0x272,0x177,0x302;
把这六个数字从大到小排序,分别是0x38a,0x302,0x272,0x21a,0x177,0x15d;
得到按原来标号的顺序为2,6,4,3,5,1
结果如下:
Secret_phase
如下输入可打开隐藏关卡
反汇编代码如下:
只需查看在调用fun7前输入的值
又由于fun7函数是一个递归函数,经过判断存储地址为0x804c088+0x8,故用x命令查看存储的值
故结果为50
总结果如下所示:
ps:挂上上面phase2_6的C语言代码
3.
4.
5.
6.