函数逆向分析

函数逆向分析

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

原文地址:https://www.cnblogs.com/DeeLMind/p/6846009.html