前一階段閑著無聊,用遠程線程注入的方法把DLL注入到Explorer.exe進程實現音樂循環播放。
在DLL中的代碼是這樣的:
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad)
{
static HANDLE hThread;
static DWORD dwThreadId;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hInstDll = hInstDll;
hThread = BEGINTHREADEX(NULL, 0, ThreadProc, (PVOID)hInstDll, 0, &dwThreadId);
if (hThread == NULL)
{
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
SendMessage(g_hWnd, WM_CLOSE, 0, 0);
WaitForSingleObject(hThread, INFINITE); // 這里存在死循環
CloseHandle(hThread); // 執行不到這里
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
}
在DLL_PROCESS_ATTACH的時候創建了一個線程,這個線程中創建了一個隱藏的窗口,并利用MCI實現播放音樂,具體就不貼出了。然后在DLL_PROCESS_DETACH中停止和關閉設備。
但是在應用程序中,發現注入時無異常,在需要撤銷DLL映射時出現了問題,程序出現了死循環,在等待遠程線程執行FreeLibaray完畢時不返回了。
注意上面代碼中DLL_PROCESS_DETACH的代碼,SendMessage用來關閉窗口,窗口會在WM_DESTROY通知下調用PostQuitMessage(0)使得線程的消息循環退出,從而線程退出。但是WaitForSingleObject函數無法返回。
后來發現這里存在死循環,因為執行DllMain的線程是序列化的,必須等待一個線程執行完畢之后另一個線程才能執行。在SendMessage后,導致創建的線程即將退出,這時該線程會調用DllMain,并以DLL_THREAD_DETACH作為通知。可是調用SendMessage的線程調用DllMain時卻還在等待即將退出的線程結束,DllMain還沒有返回,因此存在了死循環。
因此,在DllMain中不適合調用WaitForSingleObject等函數來等待線程完畢。