曲径通幽论坛
标题:
关于函数调用的反汇编分析(原创)
[打印本页]
作者:
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