• 函数逆向分析


    函数逆向分析

    作者:ONDragon

    环境:Windows 7 VC6.0。

     

    一、     函数源码

    __cdecl int CTestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    __stdcall int STestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    __fastcall int FTestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    int TestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    int main(int argc, char* argv[])

    {

        

         TestPlus(10,11,12);

         CTestPlus(1,2,3);

         STestPlus(4,5,6);

         FTestPlus(7,8,9);

         return 0;

    }

     

    二、     解释函数作用

    //__cdecl 标准C语言调用函数,函数参数从右至左入栈,调用者平衡堆栈(后面详细解释)

    __cdecl int CTestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    //__stdcall 标准调用函数,函数参数从右至左入栈,函数自己平衡堆栈(后面详细解释)

    __stdcall int STestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    //__fastcall 快速调用函数,参数从右至左入栈,除去前两个参数,例如:c入栈,但是a,b,不入栈,而是进入寄存器,因为CPU使用寄存器最快,所以叫做__fastcall

    __fastcall int FTestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    // 默认则是__cdecl 标准C语言调用函数

    int TestPlus(int a,int b,int c)

    {

         return a + b + c;

    }

    int main(int argc, char* argv[])

    {

        

         TestPlus(10,11,12);

         CTestPlus(1,2,3);

         STestPlus(4,5,6);

         FTestPlus(7,8,9);

         return 0;

    }

    三、     具体分析过程

    1.      下断点

     

     

    在调试窗口中,可以打开相应的窗口,我们打开内存,堆栈,寄存器窗口就行。

     

    然后转到汇编操作界面,选择Disassembly.

     

    2.      分析TestPlus函数(CTestPlus相同只分析一个)

     

     

    如上图:

    1,是三个函数参数10,11,12(__cdecl 标准C语言调用函数,函数参数从右至左入栈,调用者平衡堆栈。)

    2,从右至左入栈,依次是12,11,10.

    3,调用者平衡堆栈是哪个函数调用了TestPlus,哪个函数就平衡堆栈,例如这个TestPlus是Main函数调用的,所以就由Main函数平衡堆栈 add esp 0C,C的十六进制刚好是12,一个参数四个字节3 * 4 刚好12个字节。

    4,单步调试进入函数TestPlus,Call汇编对应C语言函数的意思。

     

    5,进入TestPlus函数

     

    6, 解释函数汇编代码

    Push ebp 保护现场,保存上一个函数的Ebp

    Mov ebp,esp

    Sub esp,40h 开辟缓存区

    Push ebx

    Push esi

    Push edi 保护现场保存上一个函数的ebx,esi,edi的值

    Lea edi,[ebp-40h]

    Mov ecx,10h

    Mov eax,0ccccccccch

    Rep stos dword ptr[edi] 用CC int 3断点填充刚开辟的缓冲区域(原因:保护程序,程序出错直接进入CC中断不执行)

    7, 进入函数的主要功能区域a + b + c

    [ebp + 8] 第一个参数 10 记做var_1

    [ebp + 0Ch] 第二个参数 11 记做var_2

    [ebp + 10h] 第三个参数 12 记做 var_3

    8, 加法开始

    Mov eax ,var_1

    Add eax,var_2

    Add eax,var_3

    这几条汇编十分简单就不讲了。

    9, 返回值一般放到eax寄存器里面。

    恢复现场:

    pop         edi

    pop         esi

    pop         ebx

    mov         esp,ebp

    pop         ebp

    返回,汇编ret相当于C语言的return.

    Ret

    3.      分析STestPlus函数

    1,函数开始和返回和前面的函数相同,就不分析了,直接分析有差异的部分。

     

    2, __cdecl 调用时add esp ,0Ch平衡堆栈,__stdcall则没有,因为是函数本身平衡堆栈,继续看。

     

    3, __stdcall 与 __cdecl 只有平衡堆栈方法不同,是通过ret 0Ch来平衡堆栈的刚好3个参数每个4个字节3 * 4 刚好12位Ch.

    4.      分析FTestPlus函数

    1,__fastcall 处理函数参数的顺序从右至左,但是如上图,9入栈,但是8,7都是通过寄存器来处理的参数,所以快。

     

    2,加法部分差不多,平衡堆栈方式是 ret 4。

    四、     总结:

    普通函数和__cdecl:

    参数入栈从右到左,调用者平衡堆栈。

    __stdcall:

    参数入栈从右到左,自己平衡堆栈。

    __fastcall:

    参数入栈从右到左,但是前两个参数依次进入ecx,edx寄存器,自己平衡堆栈。

  • 相关阅读:
    Java数组
    Java非访问修饰符
    Java 循环结构
    Java修饰符
    Java语句
    DDK
    HDC中的前景色与背景色
    如何控制一个程序只能有一个进程
    把一个bmp转换成cur显示出来(掩码mask)
    怎么设置IE代理服务器
  • 原文地址:https://www.cnblogs.com/DeeLMind/p/6846009.html
Copyright © 2020-2023  润新知