Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #58, СЕНТЯБРЬ 2005 г.

Windows на страже порядка

Deeoni$

Спецвыпуск: Хакер, номер #058, стр. 058-004-3


Теперь рассмотрим это подробнее. Допустим, у нас есть процесс A, поставивший хук WH_GETMESSAGE и наблюдающий за сообщениями, которые обрабатываются окнами в системе. Поток процесса B собирается направить сообщение какому-либо окну. Система проверяет, не установлена ли для данного потока соответствующая ловушка, затем выясняет, спроецирована ли DLL, содержащая функцию хука, на адресное пространство процесса B. Если указанная DLL еще не спроецирована, система отображает ее на адресное пространство процесса B и увеличивает счетчик блокировок проекции DLL в процессе B на один. После этого ОС проверяет, не совпадают ли значения hMod этой DLL, относящиеся к процессам A и B. Если hMod в обоих процессах одинаковы, то и адрес функции хука в этих процессах тоже одинаков. Тогда система может просто вызвать lpfn в адресном пространстве процесса A. Если же hMod отличаются, то определяется адрес функции в адресном пространстве процесса B по формуле:

lpfn B = hMod B + (lpfn A – hMod A)

Вычитая hMod из lpfn A, мы получаем смещение адреса функции ловушки. Добавляя это смещение к hMod B, будем иметь адрес lpfn, соответствующий проекции DLL в адресном пространстве процесса B. При этом счетчик блокировки в процессе B увеличивается на один и вызывается lpfn в адресном пространстве процесса B. После возврата из функции счетчик блокировки проекции DLL в адресном пространстве процесса B уменьшается на один.

Когда система внедряет или проецирует DLL, содержащую функцию фильтра ловушки, проецируется вся DLL, а не только эта функция. А значит, потокам, выполняемым в контексте процесса B, теперь доступны все функции такой DLL.

В отличие от внедрения DLL с помощью реестра, этот способ позволяет в любой момент отключить DLL от адресного пространства процесса вызовом функции:

BOOL UnhookWindowsHookEx(HHOOK hhk);

Единственный параметр hhk – это хэндл хука, который мы хотим убрать и который возвращается при вызове SetWindowsHookEx. Когда поток обращается к этой функции, система просматривает внутренний список процессов, в которые ей пришлось внедрить данную DLL, и уменьшает счетчик ее блокировок на один. Как только этот счетчик обнуляется, DLL автоматически выгружается. Система увеличивает его непосредственно перед вызовом lpfn. Это позволяет избежать нарушения доступа к памяти. Если бы счетчик не увеличивался, то другой поток мог бы вызвать UnhookWindowsHookEx в тот момент, когда поток процесса B пытается выполнить код функции ловушки.

Внедрение DLL с помощью удаленных потоков

Этот способ внедрения DLL самый гибкий из всех. В нем используются многие особенности Windows, например потоки и синхронизация потоков, управление виртуальной памятью и многое другое. Суть этого метода заключается в том, чтобы создать в чужом процессе поток, который подгрузит в этот процесс нужную нам DLL. Большинство API-функций Windows позволяют процессу управлять лишь самим собой, тем самым исключается риск испортить что-нибудь в работе других приложений. Однако есть и такие функции, которые позволяют управлять чужим процессом. Изначально многие из них были рассчитаны на применение в отладчиках и других инструментальных средствах. Но ничто не мешает использовать их и в обычных программах.

Назад на стр. 058-004-2  Содержание  Вперед на стр. 058-004-4