if-else简单逆向分析

if-else简单逆向分析

分析过程

这里随便搞了一个乱写的函数基本只用了if-else语句,现在的目的是根据该函数的反汇编结果还原为C函数

汇编指令:

void fun(int x, int y)
{
00AB1800  push        ebp  
00AB1801  mov         ebp,esp  
00AB1803  sub         esp,0D8h  
00AB1809  push        ebx  
00AB180A  push        esi  
00AB180B  push        edi  
00AB180C  lea         edi,[ebp-18h]  
00AB180F  mov         ecx,6  
00AB1814  mov         eax,0CCCCCCCCh  
00AB1819  rep stos    dword ptr es:[edi]  
00AB181B  mov         ecx,offset _C478F8FA_main@cpp (0ABC067h)  
00AB1820  call        @__CheckForDebuggerJustMyCode@4 (0AB1311h)  
00AB1825  mov         eax,dword ptr [0ABA000h]  
00AB182A  mov         dword ptr [ebp-0x4],eax  
00AB182D  mov         dword ptr [ebp-0x8],2  
00AB1834  mov         eax,dword ptr [ebp+0x8]  
00AB1837  cmp         eax,dword ptr [ebp+0xc]  
00AB183A  jl          __$EncStackInitStart+3Bh (0AB1847h)  
00AB183C  mov         eax,dword ptr [ebp-0x8]  
00AB183F  add         eax,1  
00AB1842  mov         dword ptr [ebp-0x8],eax  
00AB1845  jmp         __$EncStackInitStart+58h (0AB1864h)  
00AB1847  mov         eax,dword ptr [ebp+0x8]  
00AB184A  cmp         eax,dword ptr [ebp+0xc]  
00AB184D  jge         __$EncStackInitStart+4Dh (0AB1859h)  
00AB184F  mov         eax,dword ptr [ebp-0x4]  
00AB1852  mov         dword ptr [0ABA000h],eax  
00AB1857  jmp         __$EncStackInitStart+58h (0AB1864h)  
00AB1859  mov         eax,dword ptr [ebp-0x4]  
00AB185C  add         eax,dword ptr [ebp-0x8]  
00AB185F  mov         dword ptr [0ABA000h],eax  
00AB1864  pop         edi  
00AB1865  pop         esi  
00AB1866  pop         ebx  
00AB1867  add         esp,0D8h  
00AB186D  cmp         ebp,esp  
00AB186F  call        __RTC_CheckEsp (0AB1235h)  
00AB1874  mov         esp,ebp  
00AB1876  pop         ebp  
00AB1877  ret  

这里保留了指令的内存地址,目的是为了能够清楚地找到跳转指令所跳转地地方

1、找到核心部分

00AB1825  mov         eax,dword ptr [0ABA000h]  
00AB182A  mov         dword ptr [ebp-0x4],eax  
00AB182D  mov         dword ptr [ebp-0x8],2  
00AB1834  mov         eax,dword ptr [ebp+0x8]  
00AB1837  cmp         eax,dword ptr [ebp+0xc]  
00AB183A  jl          __$EncStackInitStart+3Bh (0AB1847h)  
00AB183C  mov         eax,dword ptr [ebp-0x8]  
00AB183F  add         eax,1  
00AB1842  mov         dword ptr [ebp-0x8],eax  
00AB1845  jmp         __$EncStackInitStart+58h (0AB1864h)  
00AB1847  mov         eax,dword ptr [ebp+0x8]  
00AB184A  cmp         eax,dword ptr [ebp+0xc]  
00AB184D  jge         __$EncStackInitStart+4Dh (0AB1859h)  
00AB184F  mov         eax,dword ptr [ebp-0x4]  
00AB1852  mov         dword ptr [0ABA000h],eax  
00AB1857  jmp         __$EncStackInitStart+58h (0AB1864h)  
00AB1859  mov         eax,dword ptr [ebp-0x4]  
00AB185C  add         eax,dword ptr [ebp-0x8]  
00AB185F  mov         dword ptr [0ABA000h],eax  

这部分的指令是执行函数功能的核心指令,其余的那些指令是用于为函数分配内存空间和平衡堆栈用的

2、分析参数

如果只给一个函数内部的指令,看不到参数压栈指令。此时,可以去分析ret,ebp-0x8,ebp-0xc等值从而找到参数的个数。

00AB1834  mov         eax,dword ptr [ebp+0x8]  
00AB1837  cmp         eax,dword ptr [ebp+0xc]  

从这两步和ret可以初步推断,这个函数参数有两个参数。由此,我令x=[ebp+0x8],y=[ebp+0xc],这里的调用约定按照_cdecl即,参数从右至左依次入栈由调用者清理栈区

3、分析全局变量

函数中多次出现mov eax,dword ptr [0ABA000h] 类似的指令,我可以猜测[0ABA000]这里存的是全局变量。在该函数调用中只有这一个地址出现,那么我们判断这次调用中应该只使用了一个全局变量。由此,我令a=[0ABA000h]

4、分析局部变量

局部变量会存储在调用函数时为函数分配的缓冲区中,ebp-0x4,ebp-0x8等地方会被用于存储局部变量。我们观察核心部分,找到局部变量。令b=[ebp-0x4],c=[ebp-0x8]

5、功能分析

先看跳转指令,cmp a,b后接着一个jcc指令,一般来说这里会有一个if-else语句。跳转后,又发现了一个语句,如下

00AB1834  mov         eax,dword ptr [ebp+0x8]  
00AB1837  cmp         eax,dword ptr [ebp+0xc]  
00AB183A  jl          __$EncStackInitStart+3Bh (0AB1847h)  
00AB1847  mov         eax,dword ptr [ebp+0x8]  
00AB184A  cmp         eax,dword ptr [ebp+0xc]  
00AB184D  jge         __$EncStackInitStart+4Dh (0AB1859h)  

这是一个if-else if语句的典型特征。这里的jl是小于跳转,jge是大于等于跳转。在这一次的汇编指令中一共有四个jmp分析时需要弄清楚判断条件和四个指令之间的跳转关系

在这里插入图片描述

由分析可得到以下伪代码:

if(x>=y) then c=c+1 else if(x<y) then b = a else a=c+b

下面是分析时画的堆栈图:

在这里插入图片描述

6、返回值分析

函数的返回值一般是放在eax中的,不在eax中的我也没见过,之后可能能见着。所以我们需要去分析汇编指令看看是否有mov eax,相关的给eax赋值的指令。

00AB1859  mov         eax,dword ptr [ebp-0x4]  
00AB185C  add         eax,dword ptr [ebp-0x8]  
00AB185F  mov         dword ptr [0ABA000h],eax  

在函数结尾处我们只看见了这玩意,但是几个指令显然是if-else if-else这里面的指令,并未存在明显的给eax赋值的指令,所以推断该函数无返回值,为void类型

7、还原C函数

int a;//因为不知道这个全局变量原先的值是多少所以不赋值,默认为零
void fun(int x, int y)
{
    int b = a;
    int c = 2;
    if(x >= y)
    {
        c = c + 1;
    }
    else if(x < y)
    {
        b = a;
    }
    else
    {
        a = c + b;
    }
}

总结

  1. if-else 语句反汇编后有很明显的特征,在分析时一定要搞清楚判断条件和jxx的跳转关系。

  2. 以上的实验基于x86体系,x64的其实大差不差,最近在学x86所以就这样了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值