裸函数 和 调用约定
0.说面
看滴水逆向视频总结
编译器:vc++6.0
1.裸函数 _declspec(naked)
用于告诉编译器不用为函数生成任何汇编代码(包括开辟空间以及ret),方便自己用汇编书写函数部分。
#include<stdio>
void _declspec(naked) fun()
{
_asm
{
push ebp
mov ebp esp
sub esp,0x40
push ebx
push esi
push edi
move eax,0xcccccccc
mov ecx,0x10
lea edi,dword ptr ds:[ebp-0x40]
rep stos dword ptr es:[edi]
/*
函数代码段
*/
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
}
}
int main()
{
fun();
}
也就是说,如果不写_declspec(naked),那编译器会自动为我们生成我们上面写的那些汇编语句。
2.调用约定 基于堆栈平衡
因为调用约定涉及C语言中函数的参数在汇编中压传入方式,对应入栈和出栈,所以基于堆栈平衡。
了解调用约定帮助我们查看汇编语言时,分析如何函数的参数个数。
调用约定 | 参数压栈顺序 | 平衡堆栈 | 说明 |
---|---|---|---|
_cdecl | 从右至左入栈 | 调用者清理 | c/c++默认调用约定 |
_stdcall | 从右至左入栈 | 自身清理堆栈 | |
_fastcall | ecx/edx传入前两个,剩下的从右至左入栈 | 自身清理堆栈 | 将参数传入寄存器,调高速率 |
如下图
_cdecl
_stdcall
进入函数查看
_fastcall
我们再进入函数,
这种方式由于将参数传入寄存器,调用起来速度快,所以叫_fast