zoukankan      html  css  js  c++  java
  • 函数逆向分析

    函数逆向分析

    作者: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寄存器,自己平衡堆栈。

  • 相关阅读:
    Bootstrap标签(label)的使用
    Docker学习(二)
    linux 的tee命令
    解决 Docker pull 出现的net/http: TLS handshake timeout 的一个办法
    win 10 安装.msi 程序出现the error code is 2503
    Kbuntu16.04利用快捷键调用终端Konsole
    ubuntu上swift开发学习2
    ubuntu上swift开发学习1
    Linux中常用文件传输命令及使用方法
    Kbuntu16.04添加工作空间
  • 原文地址:https://www.cnblogs.com/DeeLMind/p/6846009.html
Copyright © 2011-2022 走看看