bomblab-二进制炸弹-第四关递归解析

观前提示:本文并非速通指南,偏向于如何一步步思考与解题,也许会分析得有些拖沓。且本文为系列文章,每一篇会分析一关的破解思路,前文提到的知识点后面不会赘述,分析过的类似的汇编代码段也不会再分析,除非是没见过的结构,所以越往后分析得越少。

本文共一千余字。

前言

​ 如果这些解析对你有帮助,那么我会非常荣幸和开心!

​ 如果我的解析存在错误,非常抱歉误导了你!请在评论区提出!我也是一个正在不断学习的学生。

​ 谢谢你!

正式破解

phase_4代码分析

大概扫视一下phase4代码,可以大致分成4部分:

在这里插入图片描述

关于关卡核心逻辑部分,下面我们边分析代码边追踪堆栈内存(内存信息我没截图),就可以分析出一些信息:

  • phase_4传了2个参数给func4,一个是我们输入的第一个参数,一个是9。所以猜测func4的参数列表有2个参数。
  • 从func4出来之后,应该还是按照这个程序的惯例把函数返回结果存到了eax里面。其实这个可能涉及“调用约定”(calling convention)的其中一种——C declaration。图源维基百科:
    • blob
    • blob
  • 简单来说,Cdecl是一种常见的调用约定,特点是参数由调用者在函数调用之前压入栈中,调用完成后由调用者负责清理栈。返回值通常存储在寄存器 %eax 中。后记有附上一篇关于函数调用实现的文章。

在这里插入图片描述

func4函数代码分析

进入func4函数,明显可以注意到它自己调用了自己,它是递归函数:

在这里插入图片描述

绿框部分涉及到的知识(比如 test)在之前的文章里面有说过,不再赘述,在这里只分析func4的递归部分:

在这里插入图片描述

还原成C代码大概如此(不太可能百分百还原):

int func4(int ebx, int edi) {
    int eax;
    if (ebx <= 0) {
        result = 0;
    } else {
        eax = edi;
        
        if (ebx != 1) {
            eax += func4(ebx - 1, edi) + func4(ebx - 2, edi);
        }
    }
    return eax;
}

然后偷个懒,丢到编译器里跑一跑,答案就出来了。

blob

因为纯自己分析太费手了,9层递归,每个分成3项。4层就开始麻烦了:

在这里插入图片描述

完整还原成C代码

int func4(int i, int input) {
    int result;
    if (i <= 0) {
        result = 0;
    } else {
        result = input;
        
        if (i != 1) {
            result += func4(i - 1, input) + func4(i - 2, input);
        }
    }
    return result;
}

void phase_4(char *input){
    int numbersInput[2];
    int num = sscanf(input, "%d %d", &numbersInput[0],&numbersInput[1]);
    
    if(num == 2){
       	numbersInput[1] -= 2;
        if( (unsigned int)numbersInput[1] <= 2 ){
            int result = func4(9,numbersInput[1]);
            
            if(numbersInput[0] == result){
            	return;
        	}
        } 
    }
    explode_bomb();
}

后记

浅谈函数调用的实现

感谢你看到这里!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值