前一階段閑著無聊,用遠程線程注入的方法把DLL注入到Explorer.exe進程實現(xiàn)音樂循環(huán)播放。
在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); // 這里存在死循環(huán)
CloseHandle(hThread); // 執(zhí)行不到這里
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
default:
break;
}
return TRUE;
}
在DLL_PROCESS_ATTACH的時候創(chuàng)建了一個線程,這個線程中創(chuàng)建了一個隱藏的窗口,并利用MCI實現(xiàn)播放音樂,具體就不貼出了。然后在DLL_PROCESS_DETACH中停止和關(guān)閉設(shè)備。
但是在應(yīng)用程序中,發(fā)現(xiàn)注入時無異常,在需要撤銷DLL映射時出現(xiàn)了問題,程序出現(xiàn)了死循環(huán),在等待遠程線程執(zhí)行FreeLibaray完畢時不返回了。
注意上面代碼中DLL_PROCESS_DETACH的代碼,SendMessage用來關(guān)閉窗口,窗口會在WM_DESTROY通知下調(diào)用PostQuitMessage(0)使得線程的消息循環(huán)退出,從而線程退出。但是WaitForSingleObject函數(shù)無法返回。
后來發(fā)現(xiàn)這里存在死循環(huán),因為執(zhí)行DllMain的線程是序列化的,必須等待一個線程執(zhí)行完畢之后另一個線程才能執(zhí)行。在SendMessage后,導(dǎo)致創(chuàng)建的線程即將退出,這時該線程會調(diào)用DllMain,并以DLL_THREAD_DETACH作為通知。可是調(diào)用SendMessage的線程調(diào)用DllMain時卻還在等待即將退出的線程結(jié)束,DllMain還沒有返回,因此存在了死循環(huán)。
因此,在DllMain中不適合調(diào)用WaitForSingleObject等函數(shù)來等待線程完畢。