奇怪的函数调用约定

kar*_*son 4 c++ hook windbg

我正在调试windbg中的x86 DLL,特别是一个假定具有以下签名的函数:

bool __cdecl func(LPVOID p1, LPVOID p2, wchar_t* p3, size_t p4, LPVOID p5)
Run Code Online (Sandbox Code Playgroud)

该功能未导出.AFAIK __cdecl应该接收堆栈上的所有参数,并且调用者应该清除堆栈.

但事情并非如此.WinDBG的说,调用约定__cdecl,但第2个参数的传递ecxedx,就像一个__fastcall功能.函数本身也正在清理堆栈,我认为不应该由__cdecl函数完成.

我试图挂钩该功能但没有成功.我试图做一个绕行功能__cdecl,__fastcall并且都会导致崩溃.

有什么建议?

abe*_*nky 6

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

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

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

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

  • 编译器可以在可执行文件或DLL中自由地优化任何非导出函数.例如,编译器可以内联函数,用常量替换它的一些参数(例如,如果它确定所有调用站点对某些参数使用相同的值),或者重写如此处所述的调用约定.这对于声明为`static`的函数尤其常见. (5认同)
  • 对不起,我忘了提到它是一个DLL,但是没有导出该函数.此外,我不拥有源代码,因为它是第三方DLL.但是我认为你的答案仍然适用. (3认同)