Сбой нескольких программ при отсоединении от UnhookWindowsHookEx()
Я делаю глобальный хук, чтобы добавить мою DLL в цепочку хуков:
HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, 0);
Внутри моей DLL я использую Detours для перехвата нескольких вызовов функций WINAPI. Все работает отлично, за исключением вызовов WaitForSingleObject. Всякий раз, когда я добавляю WaitForSingleObject к удаленным функциям, некоторые программы завершают работу, когда я отсоединяю свою DLL (Chrome, Skype, ...). Вот как выглядит DLL:
DWORD (WINAPI* Real_WaitForSingleObject)( HANDLE hHandle, DWORD dwMilliseconds) = WaitForSingleObject;
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch(Reason) {
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
return Real_WaitForSingleObject(hHandle, dwMilliseconds);
}
extern "C" __declspec(dllexport) int meconnect(int code, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(NULL, code, wParam, lParam);
}
Может ли кто-нибудь помочь мне понять, почему это происходит и как я могу обойти эту проблему? Спасибо!
2 ответа
Вы обходите функцию, которую использует практически любой процесс. И это особенно опасно, поскольку весьма вероятно, что такой процесс вызовет активную функцию. Блокирующий вызов практически в любом случае. Как только он разблокируется, код возобновит ваш обходной путь, которого больше нет.
Kaboom.
Реально, единственный способ разгрузить ваш обходной путь - это выйти из системы, чтобы все процессы, которые могли быть отклонены, больше не выполнялись.
Я думаю, что это происходит потому, что многие программы (Chrome, Skype, ...) имеют пул потоков, где фоновые потоки ожидают в WaitForSingleObject() чего-то интересного для них, и когда это происходит, этот поток проснись и сделай что-нибудь.
Итак, ваш поток A вызывает DetourDetach, в то время как другой поток B того же процесса в данный момент находится внутри Mine_WaitForSingleObject(). Затем DLL выгружается, и все вылетает. Вы можете проверить с помощью отладчика, присоединиться к этому проблемному процессу, установить точку останова в DLL_PROCESS_DETACH, и когда точка останова достигнет, просмотрите стеки других потоков для Mine_WaitForSingleObject.
Я не уверен, как это исправить. Но есть один способ, который вы можете попробовать - перечислить потоки и вызвать DetourUpdateThread() для каждого потока процесса. Таким образом, возможно, Detours сделает что-то с этим.