奇怪的函数调用约定

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 个参数在 ecxedx 上传递,就像 __fastcall 函数一样。此外,函数本身正在清除堆栈,(我认为)不应该由 __cdecl 函数完成。

我试图挂钩该函数但没有成功。我尝试将绕行功能设置为 __cdecl__fastcall,但都导致崩溃。

有什么建议吗?

如果函数在可执行文件(而非库)中或仅从同一 DLL 中调用,则编译器可以根据需要优化调用约定。

如果编译器知道两端(调用者和被调用者),并且知道函数不会导出到另一个单元(就像库一样),那么它可以以任何方式进行优化。

所以:函数是已完成的可执行文件的一部分吗?你有优化吗?

我建议关闭优化,然后重试。