2014-01-20 153 views
2

我可以挂接任何其他功能,但不能ExitProcess。IAT挂钩 - 无法挂钩ExitProcess

这里是为了证明这个代码:http://pastebin.com/EzHGMe8K

它调用挂钩函数,但是当NewExitProcess返回我得到一个访问冲突。对睡眠的调用很好,就像ExitProcess以外的任何钩子函数一样。

编辑:虽然挂钩ExitThread时,我得到同样的问题。

+0

无再现。目前还不清楚你希望你的程序何时退出。当您的程序终止时,现在将iostream管道销毁,现在再次调用您的替换函数将会很糟糕。避免重新发明这个轮子并使用Detours,以便在任何Windows版本上正常工作,甚至是将ExitThread等函数转发给另一个DLL的函数。并允许您在程序退出前正确恢复绕行。 –

+0

该程序按预期对我工作。没有崩溃。这正是你测试的代码吗? – typ1232

+0

@ typ1232,是的。我使用了VC++ 2013和发布模式。不知何故,它在调试模式下没有崩溃。 – NFRCR

回答

-1

当仰视了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的应始终退出当前线程,因为它可以被编译成没有任何代码返回。