曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6017|回复: 2
打印 上一主题 下一主题

关于函数调用的反汇编分析(原创)

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2008-11-16 22:44:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;
}

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2008-11-16 22:45:03 | 只看该作者
反函数的代码:
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]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
板凳
 楼主| 发表于 2008-11-16 22:44:32 | 只看该作者
进入 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]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-13 14:21 , Processed in 0.081294 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表