《逆向工程核心原理》--- 函数调用约定
函数的约定:
对函数调用时如何传递参数的一种约定,我们知道调用函数前需要将参数压入栈然后再传递给函数,栈就是定义在进程中的一段内存,向下扩展,大小记录在PE头中,运行时确定栈的大小
函数执行完毕后,ESP的值如何变化?
ESP的值恢复到函数调用之前,这样可引用的栈大小不会缩减
函数:
int function(int a, int b) { return a + b; } void main() { function(10, 20); }
主要函数约定如下:
__cdecl约定
__cdecl函数调用约定是我们最长见的一种约定,我们平时在写程序的时候默认会使用该种约定,其特点如下:
- 参数从右向左依次传递,存放在堆栈中。
- 堆栈平衡由调用函数来维护。
- C语言编译时的函数命名规则为下划线加名称:__functionName
_function push ebp mov ebp, esp mov eax, [ebp+8] ;参数1 add eax, [ebp+C] ;加上参数2 pop ebp retn _main push ebp mov ebp, esp push 14h ;参数 2入栈 push 0Ah ;参数 1入栈 call _function ;调用函数 add esp, 8 ;修正栈 xor eax, eax pop ebp retn
__stdcall约定
__stdcall约定是我们在写WinAPI的时候经常用的约定,很多windows下面的API都是该种调用约定,其特点如下:
- 参数从右向左依次传递,存放在堆栈中。
- 堆栈平衡由被调用函数来维护
- C语言编译时的函数命名规则为下划线加名称加@加参数字节大小:
8 push ebp mov ebp, esp mov eax, [ebp] ;参数 1 add eax, [ebp+C] ;加上参数 2 pop ebp retn 8 ;修复栈 _main push ebp mov ebp, esp push 14h ;参数 2入栈 push 0Ah ;参数 1入栈 call 8 ;函数调用 xor eax, eax pop ebp retn
__fastcall约定
从名称上可以看出是速度快,因为其参数是可以放在寄存器中传递的,通常需要在要求高效率的函数中使用此约定,其特点如下:
- 最右侧两个参数由ecx和edx两个寄存器来传递,剩余参数从右往左依次存放在堆栈中。
- 堆栈平衡由被调用函数来维护
- C语言编译时的函数命名规则为@加函数名加@加参数大小:@
该约定是高效率的调用约定,和另外两种约定最大的区别就是参数的传递方式,利用了寄存器来快速的传递
@8 push ebp mov ebp, esp ;保存栈指针 sub esp, 8 ;多了两个局部变量 mov [ebp-8], edx ;保存参数 2 mov [ebp-4], ecx ;保存参数 1 mov eax, [ebp-4] ;参数 1 add eax, [ebp-8] ;加上参数 2 mov esp, ebp ;修正栈 pop ebp retn _main push ebp mov ebp, esp mov edx, 14h ;参数 2给EDX mov ecx, 0Ah ;参数 1给ECX call @8 ;调用函数 xor eax, eax pop ebp retn
相关推荐
wangzhaotongalex 2020-09-22
古叶峰 2020-11-16
linmufeng 2020-09-08
xiaoxiaokeke 2020-07-28
好好学习天天 2020-07-21
83417807 2020-07-19
小方哥哥 2020-07-09
wbczyh 2020-07-05
pwc 2020-06-26
flowerCSDN 2020-06-16
Wonder的学习 2020-06-13
周小董 2020-06-10
luvhl 2020-06-08
nurvnurv 2020-06-05
Andrewjdw 2020-05-27
专注前端开发 2020-03-01
silencehgt 2020-04-17