逆向-分支结构上

前面把一些基本的运算都记录完了,后面开始流程结构,其流程结构主要分为分支结构和循环结构。对于流程结构的逆向识别,主要在于首先需要识别是什么,然后识别语句体(花括号上下界位置),因为确定好了这两步后,其里面的主体内容就是前面的基本运算或者又是流程结构(递归进行逐步分解)。

对于流程结构主要就以debug版为主了,因为debug版更加利于研究其结构如何,而release中除了结构以外,还混有一些的优化,对于优化的情况,会再额外对其release进行分析。

先看分支语句,其大体上可分为if和switch,因为其两者的实现机制有稍许的不同,所以这里打算分开来记录,这一篇先记录if语句。

对于if语句主要分以下三类

单分支
双分支
多分支

下面先来看一下单分支的情况

int main(int argc, char* argv[])
{
    if(argc)
    {
        printf("if argc");
    }
    printf("hello world\r\n");
    return 0;
}

对应的汇编代码,这里是Release版代码,因为debug差不多所以就选择一个观察

9:        if(argc)
00401028 83 7D 08 00          cmp         dword ptr [ebp+8],0
0040102C 74 0D                je          main+2Bh (0040103b)//为零则跳转,跳转的位置是if结束
10:       {
11:           printf("if argc");
0040102E 68 2C 20 42 00       push        offset string "if argc" (0042202c)
00401033 E8 38 00 00 00       call        printf (00401070)
00401038 83 C4 04             add         esp,4
12:       }
13:       printf("hello world\r\n");
0040103B 68 1C 20 42 00       push        offset string "hello world\r\n" (0042201c)

对于上面的汇编代码,如果argc为零则进行跳转,其跳转的地址就是if语句的结束(下花括号),而上花括号就是je跳转的下一行代码开始,这样子我们就可以确定了if语句块的上下界位置了。

然后对于跳转逻辑,可以发现此处的汇编逻辑代码与我们的高级代码的逻辑是相反的,因为按照if语句的规定,满足if判定的表达式才能执行if的语句块,而汇编语言的条件跳转却是满足某条件则跳转(绕过语句块不执行),这一点是和C语言是相反的。

那么如果C语言编译可以把if和else的语句块进行相互的调换,那么是不是就能和C语言的逻辑一致呢(调换后if的执行块在下面,那么条件符合就会跳转到下面执行)。

是的,这样子理论上是可行的,只是因为C语言的根据代码行的位置来决定编译后的二进制代码的地址高低的(有时会使用标号相减来得到代码段的长度),所以C编译器不能随意改变代码行在内存中的顺序。

下面简化一下单分支的汇编情况

jxx IF_END
IF_BEGIN:
	....
IF_END:   


结构特性
    条件跳转是增量跳转 - 向下跳
    跳转的目标标号上面没有jmp

确定好if语句的上下界后,然后对其条件的反条件进行还原即可。

 

下面来看双分支结构的情况

int main(int argc, char* argv[])
{
    if(argc)
    {
        printf("if if");
    }
    else
    {
        printf("else else");
    }
    return 0;
}

对应的汇编代码讲解

9:        if(argc)
0040FB98 83 7D 08 00          cmp        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值