本实验结合网上大佬资料和自己研究得出。只完成了1~5.
建议去读读汇编,熟悉一下。(因为本人懒汉)
应该是有隐藏关卡,参照这个博客。不过不同学校似乎题目有差异,本校没找到大佬。
CSAPP实验——逆向工程拆除“二进制炸弹”程序_二进制拆弹实验阶段7-CSDN博客
目录
添加权限:
phase_1:
callp是调用了个函数
而这个操作前面两句,就是为它做准备。%esi就是它的参数的地址,也就是我们调用这个函数传的参数。
函数顾名思义,字符串要相等。
去gdp直接 print (char*)0x... 读这个esi内容,可以得到一个字符串,即为答案。
phase_2:
去读汇编,可以根据这个图读,或者自己画一下。(初度困难较大)
%r13在数组第四个位置。比较rbp位置和该位置的数值是否相等,最多比三次因为rbp一直在上移。
接着就是比较%rbp存的数 和 %rbp+3存的数是否相等,不相等爆炸,相等rbp上移一个int,接着操作。
所以可以看出6个数中前三个依次要与后三个数相同。且不能都是0。
phase_3:
1.函数前的栈空间分配,
2.加载局部变量地址,两个lea讲两个地址存在rcx和rdx寄存器中,这两个地址将用作 sscanf 的参数。
3.设置了 sscanf 调用的前两个参数:
esi 寄存器中存储的是格式字符串的地址 0x401ebe。
eax是这里是作为返回值,记录输入的字符数目的。
然后进行了输入,如果 sscanf 没有成功读取超过一个值(%eax ,eax寄存器中存放的是上一次操作的返回值),就引爆了炸弹。
可以在esi看看输入值的格式:是两个整数。
然后读rsp + 3,如果7比它大("Jump if above"),引爆炸弹。可得出我们输入的第一个参数不能比7大。
然后第一个参数赋给eax, jmpq根据这个值跳转,会给%eax赋不同的值。
Jmpq是个基址加偏移跳转指令。可以看出这是个swich
————
学习读一下swich:
然后最后就是这些值和rsp+2比,也就是输入的第二个参数,只有相同才能通过。
数组{0x217, 0xd6, 0x153, 0x77, 0x160, 0x397, 0x19c , 0x39e}根据上方的偏移配对!
将十六进制转换为十进制:
故
0 535
2 214
3 339
4 119
5 352
6 919
7 412
1 926
每行均为正确答案。
phase_4:
自己读过来,做到这里应该很好做了。
func4,你能看出是在做什么吗?
%edi 如果小于等于1,直接返回。
否则递归调用func4(%edi) ,返回值%eax存到了%ebp中,然后第二次调用,最后结果加起来一起返回了。
该函数是求斐波那契数列第n项的值:
Func4(x)
{
If( x<=1)return x;
return func4(x-1) + func4(x-2);
}
只有函数返回值等于0x37时,才能跳过炸弹。
列一下:
func(2) == func(1) + func(0)
值: 0 1 1 2 3 5 8 13 21 34 55
下标: 2 3 4 5 6 7 8 9
phase_5:
cltq 是一个指令的缩写,代表 "Convert Lower to Quad"。这个指令将 %eax 寄存器的内容扩展符号扩展到 %rax 寄存器。
循环,每次%edx都加一,eax都会在0x401ba0偏移eax*4的地址处取值(即第eax-1个数),同时eax的值会加给ecx。
我们可以看下这个地址:
分析跳点:
index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
dest 10 2 14 7 8 12 15 11 0 4 1 13 3 9 6 5
src 8 10 1 12 9 15 14 3 4 13 0 7 5 11 2 6
最后edx要为12,即循环12次。12次的和要为我们输入的第二个整形。
而终点应为15:
11->13->9->4->8->0->10->1->2->14->6->15 ,和为93
我们输入的应是11的下标:7
所以最终输入:7 93