奇怪的函数调用约定
Weird function calling convention
我正在 windbg 中调试 x86 DLL,特别是据推测具有以下签名的函数:
bool __cdecl func(LPVOID p1, LPVOID p2, wchar_t* p3, size_t p4, LPVOID p5)
函数未导出。 AFAIK __cdecl
应该接收堆栈上的所有参数并且 调用者 应该清除堆栈。
但事实并非如此。 Windbg 说调用约定是 __cdecl
但前 2 个参数在 ecx
和 edx
上传递,就像 __fastcall
函数一样。此外,函数本身正在清除堆栈,(我认为)不应该由 __cdecl
函数完成。
我试图挂钩该函数但没有成功。我尝试将绕行功能设置为 __cdecl
和 __fastcall
,但都导致崩溃。
有什么建议吗?
如果函数在可执行文件(而非库)中或仅从同一 DLL 中调用,则编译器可以根据需要优化调用约定。
如果编译器知道两端(调用者和被调用者),并且知道函数不会导出到另一个单元(就像库一样),那么它可以以任何方式进行优化。
所以:函数是已完成的可执行文件的一部分吗?你有优化吗?
我建议关闭优化,然后重试。
我正在 windbg 中调试 x86 DLL,特别是据推测具有以下签名的函数:
bool __cdecl func(LPVOID p1, LPVOID p2, wchar_t* p3, size_t p4, LPVOID p5)
函数未导出。 AFAIK __cdecl
应该接收堆栈上的所有参数并且 调用者 应该清除堆栈。
但事实并非如此。 Windbg 说调用约定是 __cdecl
但前 2 个参数在 ecx
和 edx
上传递,就像 __fastcall
函数一样。此外,函数本身正在清除堆栈,(我认为)不应该由 __cdecl
函数完成。
我试图挂钩该函数但没有成功。我尝试将绕行功能设置为 __cdecl
和 __fastcall
,但都导致崩溃。
有什么建议吗?
如果函数在可执行文件(而非库)中或仅从同一 DLL 中调用,则编译器可以根据需要优化调用约定。
如果编译器知道两端(调用者和被调用者),并且知道函数不会导出到另一个单元(就像库一样),那么它可以以任何方式进行优化。
所以:函数是已完成的可执行文件的一部分吗?你有优化吗?
我建议关闭优化,然后重试。