我可以挂接任何其他功能,但不能ExitProcess。IAT挂钩 - 无法挂钩ExitProcess
这里是为了证明这个代码:http://pastebin.com/EzHGMe8K
它调用挂钩函数,但是当NewExitProcess返回我得到一个访问冲突。对睡眠的调用很好,就像ExitProcess以外的任何钩子函数一样。
编辑:虽然挂钩ExitThread时,我得到同样的问题。
我可以挂接任何其他功能,但不能ExitProcess。IAT挂钩 - 无法挂钩ExitProcess
这里是为了证明这个代码:http://pastebin.com/EzHGMe8K
它调用挂钩函数,但是当NewExitProcess返回我得到一个访问冲突。对睡眠的调用很好,就像ExitProcess以外的任何钩子函数一样。
编辑:虽然挂钩ExitThread时,我得到同样的问题。
当仰视了ExitProcess的函数声明,你会发现这样的事情:
WINBASEAPI
DECLSPEC_NORETURN
VOID
WINAPI
ExitProcess(
_In_ UINT uExitCode
);
有趣的部分是DECLSPEC_NORETURN
其定义为__declspec(noreturn)
。它也是ExitThread
函数使用的一个属性,它也会导致您崩溃。 Looking up on the docs,我们发现这个:
这__declspec属性告诉编译器,函数不返回。因此,编译器知道调用__declspec(noreturn)函数后的代码无法访问。
根据您的发现,它不仅用于禁用编译器警告,还用于优化。这也解释了为什么它可以在调试模式下工作。
我想不出一个好的解决方案,因为你在与优化器作斗争。你在评论中写的解决方案对我来说不起作用(VS2013,发布模式,/ O2)。我想出了一个有点傻,但它似乎为我做的工作:
int *ptr = (int*)&ExitProcess;
ptr++;
ptr--;
((VOID (WINAPI*)(UINT))ptr)(0);
一般来说,挂钩另一个未知程序的ExitProcess的应始终退出当前线程,因为它可以被编译成没有任何代码返回。
无再现。目前还不清楚你希望你的程序何时退出。当您的程序终止时,现在将iostream管道销毁,现在再次调用您的替换函数将会很糟糕。避免重新发明这个轮子并使用Detours,以便在任何Windows版本上正常工作,甚至是将ExitThread等函数转发给另一个DLL的函数。并允许您在程序退出前正确恢复绕行。 –
该程序按预期对我工作。没有崩溃。这正是你测试的代码吗? – typ1232
@ typ1232,是的。我使用了VC++ 2013和发布模式。不知何故,它在调试模式下没有崩溃。 – NFRCR