Выгрузка DLL из всех процессов после отсоединения глобальной ловушки CBT - PullRequest
4 голосов
/ 02 июля 2010

Как правильно выгружать DLL из всех процессов, когда общесистемный хук, который их загружал, выгружается?

С MSDN :

Вы можете освободить глобальный хук процедура с использованием UnhookWindowsHookEx, но эта функция не освобождает DLL, содержащую процедура подключения . Это потому, что глобальный процедуры ловушки вызываются в обрабатывать контекст каждого приложения на рабочем столе, вызывая неявное вызов функции LoadLibrary для все эти процессы. Потому что звонок к функции FreeLibrary нельзя сделано для другого процесса, есть тогда нет возможности освободить DLL. Система в конце концов освобождает DLL после все процессы явно связаны с DLL либо прервана, либо вызвана FreeLibrary и все процессы, которые называется процедура подключения возобновились обработка вне DLL.

Итак, я ищу метод определения, когда ловушка отцеплена, и затем вызов FreeLibrary из всех процессов, которые были подключены. Существуют ли другие способы вызвать мгновенную выгрузку DLL при разгрузке хука?

Ответы [ 2 ]

4 голосов
/ 02 ноября 2010

Крюк DLL выгружаются в своем цикле сообщений.Принудительное их прохождение в цикле сообщений помогает выгрузить их.

Добавьте это после вашего UnhookWindowsHookEx, чтобы заставить все циклы сообщений проснуться:

DWORD dwResult;
SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG|SMTO_NOTIMEOUTIFNOTHUNG, 1000, &dwResult);

Однако у меня все еще есть проблема со временемко времени.Я не знаю, откуда это.Я полагаю, что заблокированный процесс может помешать dll выгружаться, но у меня нет доказательств этого.

1 голос
/ 02 июля 2010

Как правило, вы должны использовать глобальную перехватку окон, если FreeLibrary не требуется вызывать. Если вы хотите сделать это, вы можете использовать DLL-инъекцию (см., Например, http://www.codeproject.com/KB/threads/winspy.aspx и http://www.codeproject.com/KB/system/hooksys.aspx) относительно техники CreateRemoteThread и LoadLibrary. В случае, если вы можете делать то, что вы хотите в удаленном процессе. Вы можете комбинировать оба метода.

Если вы хотите вызвать FreeLibrary только для обновления библиотеки DLL, вы можете сделать это другим способом. Каждая загруженная DLL может быть переименована (например, в cmd.exe) во временное имя, и вы можете вызвать MoveFileEx с флагом MOVEFILE_DELAY_UNTIL_REBOOT. Тогда вы уже можете скопировать и использовать новую версию DLL. Старая DLL будет удалена при следующей перезагрузке компьютера.

...