一.基本介绍
函数调用约定,是指当一个函数被调用时,函数的[参数]会被传递给被调用的函数和[返回值]会被返回给调用函数。函数的调用约定就是描述参数是怎么传递和由谁平衡[堆栈]的,当然还有返回值。
二.函数调用约定
0x01Windows_x86下的函数调用约定(C)
-cdecl调用约定
(c语言默认的函数调用方式)调用函数后,使用
ASS ESP,XXX
整理栈。
调用者直接清理压入栈的函数参数。
好处:它可以像c语言中printf()函数一样,向被调用函数传递长度可变的参数。
-stdcall调用约定
(常用于Win32 API,该方式由被调用者清理栈)如果想使用stdcall方式编译源码,只要使用_stdcall关键字即可。
eg建立函数:
int _stdcall add(int a, int b)
栈的清理工作由函数最后的
RETN 8
(该命令含义:RETN + POP 8 字节)来执行。
好处:被调用者函数内部存在着栈清理代码,代码尺寸小。
-fastcall调用约定
(与stdcall类似,但该方式通常使用寄存器传参)头两个参数(从左到右)存入ECX和EDX,余下的参数存入栈中(从右到左)。
好处:可以实现函数的快速调用(对于CPU,访问寄存器比访问内存快很多)。
劣处:寄存器在调用函数前若存有重要数据,或者有其他用途,需要将寄存器中的数据先备份。
0x02WIndows_x64下的调用约定(C)
-fastcall调用约定
x64下的调用约定简化了,一律使用_fastcall,前四个参数用ECX, RDX, R8, R9传递,除了这四个外加RAX, R10, R11,其他寄存器都是非易失的。
0x03LINUX_X64下的函数调用约定
参数从左到右放入寄存器:RDI, RSI, RDX, ECX, R8, R9。当参数为7个以上时,前6个与前面一样,但后面的依次从“右向左”放入栈中。
0x04C++调用约定
-thiscall调用约定
(c++特有的一种调用约定,用于类成员函数的调用约定)如果参数确定,this指针存放于ECX寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有的参数入栈后再入栈,调用者清理栈。_thiscall不是关键字,程序员不能使用。参数按照从右至左的方式入栈。
参考:《逆向工程核心原理》——【韩】李承远
网友评论