2014-01-20 236 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的應始終退出當前線程,因爲它可以被編譯成沒有任何代碼返回。