本文主要是介绍CSAPP 深入理解计算机系统课程实验 bomb实验 反向编译 汇编(4),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
隐藏关卡。Secretphase
这个隐藏关卡还是很难发现的,自己带的班上的学生中,仅有3个学生发现并解除了炸弹。中间也出现了一些小小问题,在给他们验收的时候也有意识的去引导他们发现一些小问题,并讨论解决。
首先是隐藏关卡的发现,其实在汇编代码中就有一个secret_phase.就是看怎么跳到隐藏关卡了,搜索发现,是通过phase_defused作为入口点的。其实这里可以不分析这个函数,看到在main函数中没通关一关就会调用这个函数,可以在这个函数中设置断点,可以直接利用jump跳到隐藏关卡去做。后面分析这个函数也会发现为什么每次通过一关它会调用,大概是用来比较一下你是否已经全部通关吧。
接下来是常规的进入隐藏关卡:
Phase_defused的汇编代码分析一下:
这里是首先判断一下是否已经通过了六个关卡。
接下来是sscanf函数的调用,在这里有三个ebp的偏移,按照以前通关的经验分析,应该是要输入三个东西,输入的格式规定在立即数0x804a200中查看,另外调用之后的返回值可以发现确实如果输入的小于3就不会进入隐藏关卡。关于sscanf函数一直猜测它的返回值就是输入的个数,没有具体进入去看,但是中间在某一关中输入了123456这6个数,查看了返回值eax居然是2,但是在这里却可以返回大于3的数,所以这个函数也是很有意思的,不像我们猜测的那么简单,但是并不影响我们解除炸弹,我们分析这个sscanf函数应该是根据不同的情况返回不同范围的值,不是具体个数的值,有兴趣的朋友可以自己深入研究一下。
通过gdb调试看看立即数里面的输入的格式,首先先在phasedefused函数中的0x804959处设置断点,是要将全部六个关卡都通过后,跳到断点处。
看到确实是输入三个东西,其中前两个是两个数字,最后一个是一个字符串
再接着就是看到调用了string_not_equal这个函数,调用之前先传参,可以看到,一个是从一个立即数0x804a209中传入的,另外一个则是通过sscanf输入的参数传入的,比较它们要相同才会跳入。
把里面涉及的立即数都给查看一下
可以看到8 1 非常熟悉,就是第四关我们输入的数,可以看到应该就是在第四关的时候除了输入一个8 1之外还在额外输入一个字符串 DrEvil(涉及这个实验的一个博士)就会输出后面那串你发现了隐藏关卡的提示信息。在这里我问班上有一个做了的同学,我说第四关中有几个答案,除了8,1之外还有9,1和11,1,那这样设计不是不合理了啊,输入其他答案的同学必须要用8,1才可以跳。那个同学点点头。其实并不是这样的,字符串比较的时候,传递的参数是-0x5c(%ebp)正好是对应的后面输入的那串字符串,所以前面已经判断你已经通过所有关卡了,这里只要判断你在第四关有没有输入这个字符串。所以只要输入了那三组中其中任一组再加那个字符串就可以通过了。所有的猜想都可以通过调试查看内容来验证一下,接下来就来验证一下,首先现在第四关输入9,1和DrEvil。
输入之后发现果然是这样的。然后进一步看一下每个地方存的是些什么内容。
这样看到传入到string_no_equal的参数确实只是后面的字符串
接下来就要来看看隐藏关中的内容了,
首先是栈的一系列操作,然后对输入的值进行strtol函数的调用stringtolong也就是转换为长整型,而且根据比较可知输入的值减1后要小于等于0x3e8。
接下来可以看到是调用了fun7,调用前先传入参数,可以看到第一个参数是立即数0x804c178中的内容,第二个参数是我们输入的值经过前面的出后的值。看到调用完fun7后的返回值要等于5.
用gdb调试看一下,立即数里面的内容:是一个$符号,对应的ASCII值为36
看到该关主要就是分析fun7调用以后返回值如何是5,接下来就来分析一下fun7这个函数的汇编代码。
首先是栈操作
看出将出入的参数赋值给寄存器,edx,设edx中存的是x,第一次的时候x=36,第二个参数赋值给ecx寄存器中,设为y。
第一种情况,将eax赋值为-1,如果edx中的值为x=0就返回为-1;接下来看第二种情况,
如果x>y,看到后面又调用了fun7看出来fun7是一个递归函数,在前面关卡中我们也遇到过,调用之前要传递参数,将edx偏移0x4再次作为第一个参数x,输入的y作为第二个参数。返回值是做了乘以2的操作。接下来是x==y的情况:
这种情况下,返回值为0。
再看x<y的情况:
这种情况下,也是要递归调用fun7函数,传入的第一个参数变成了edx偏移0x8.第二个参数与为y,返回值为2eax+1.
由于分析返回值必须为5,则只有第三种情况,所以5=4+1(case3),eax=2,2=2*1(case1),所以eax要等于1,1=2*0+1(case3),eax=0(case2)。由于递归调用是从最里面返回的。最里面返回值应该为0.外层递归调用也是case3-case1-case3-case2。不同的是,case3,edx偏移0x8,case1,edx偏移0x4.
按照上面的分析,那么我们输入的数应该就是edx经过(case3-case1-case3-case2)一系列偏移后的值:
由图可知输入的数为0x2f转换为十进制就是47也就是这一关的密钥。
其实后来跟班上同学探讨了一下,发现这个题应该是一个二叉查找树。小于的在一边加0x4,大于的时候在右边加0x8. 就是说输入的是47,比36大,右边走,比50小左边走,又比45大右边走,最后找到了47相等。
至此通过全部关卡:
这篇关于CSAPP 深入理解计算机系统课程实验 bomb实验 反向编译 汇编(4)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!