曲径通幽论坛

标题: 关于函数调用的反汇编分析(原创) [打印本页]

作者: beyes    时间: 2008-11-16 22:44
标题: 关于函数调用的反汇编分析(原创)
Quote:

#include <stdio.h>

int func(int,int);

int main( void )

{
    int a = 10;
    int b = 20;
    int d;

    d = func(a,b);
    printf("%d",d);
    return 0;
}
int func(int a,int b)
{
    int c;
    c = a + b;
    return c;
}

作者: beyes    时间: 2008-11-16 22:44
进入 main 后开始进行调试时,对应的代码为(调试环境为 VC6.0):
Quote:

[blockquote]int main(void)
{
00401020  push        ebp                                ;每当进入一个函数时,对ebp保护是必须的,因为在后面的应用中,必须用到 ebp 来进行相对偏移寻址的操作
00401021  mov        ebp,esp                          ;当前堆栈指针给 ebp
00401023  sub        esp,4Ch                          ;堆栈指针减去 4ch,从原来的 esp 到 esp-4 ,开辟了一个空间(堆栈),供 func() 函数使用
00401026  push        ebx                               
00401027  push        esi
00401028  push        edi                                ;进行相关寄存器的保护,因为后面需要用到这些寄存器

00401029  lea        edi,[ebp-4Ch]                  ;取得新开辟堆栈的头地址并送往 EDI
0040102C  mov        ecx,13h                   
00401031  mov        eax,0CCCCCCCCh       
00401036  rep stos    dword ptr [edi]              ;需要对新开辟栈中开始的 19 个字单元,即 19x4 个字节单元都填充CCH,初始化这部分堆栈


int a = 10;
00401038  mov        dword ptr [ebp-4],0Ah              ;a 变量属于 main 域,所以压入 main 的堆栈保存

int b = 20;
0040103F  mov        dword ptr [ebp-8],14h              ;b 和 a 一样

int d;                                                                          ;d 未初始化,故不需要压栈保存

d = func(a,b);
00401046  mov        eax,dword ptr [ebp-8]              ;从堆栈中取出b(从左到右取)存到 eax
00401049  push        eax                                          ;因为要传入 func 中,所以压入 func 的堆栈

0040104A  mov        ecx,dword ptr [ebp-4]              ;取出a
0040104D  push        ecx                                          ;入栈保存


0040104E  call        @ILT+5(_func) (0040100a)      ;进入 func 函数,注意,执行call指令时,处理器会自动把 add esp,8 这条指令的地址(0x0040104D)入栈保存

00401053  add        esp,8                                        ;平衡堆栈,这里esp调整到了b,a压栈参数的顶上,也就是说不再需要b,a两个参数
00401056  mov        dword ptr [ebp-0Ch],eax

printf("%4d",d);
00401059  mov        edx,dword ptr [ebp-0Ch]
0040105C  push        edx
0040105D  push        offset string "%4d" (0042201c)
00401062  call        printf (004010e0)
00401067  add        esp,8

return 0;
0040106A  xor        eax,eax
}
[/blockquote]
作者: beyes    时间: 2008-11-16 22:45
反函数的代码:
Quote:

[blockquote]int func(int a,int b)
{
004010A0 push ebp                        ;进入func后,对main中的ebp入栈保存,因为在func中同样需要用到ebp来进行想对偏移寻址
004010A1 mov ebp,esp                  ;ebp 获得当前堆栈指针

004010A3 sub esp,44h                  ;esp-44h,在移动堆栈指针,拉出一段栈空间给 func 使用

004010A6 push ebx                   
004010A7 push esi
004010A8 push edi                        ;入栈保存


004010A9 lea edi,[ebp-44h]
004010AC mov ecx,11h
004010B1 mov eax,0CCCCCCCCh
004010B6 rep stos dword ptr [edi]        ;同样初始化这一段空间(实际上这段初始化的空间并未用到)

int c;
c = a + b;
004010B8 mov eax,dword ptr [ebp+8]              ;取得传入的参数a
004010BB add eax,dword ptr [ebp+0Ch]          ;a + b
004010BE mov dword ptr [ebp-4],eax              ;计算的结果仍然先放在栈中保存

return c;
004010C1 mov eax,dword ptr [ebp-4]              ;函数需要用 eax 来返回
}


004010C4  pop        edi
004010C5  pop        esi
004010C6  pop        ebx                                  ;出栈还原


004010C7  mov        esp,ebp                          ;调整堆栈指针
004010C9  pop        ebp                                ; 复原 "main" 中的 ebp (像 ebp ,是轮到哪个函数执行就被哪个函数所使用的)
004010CA  ret                                                  ; 子程序返回

[/blockquote]




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2