Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Перехват API-вызовов с использованием раздела импорта - часть 3


Если программа не найдет никаких ссылок на идентификаторы в Kernel32 dll, то и в этом случае функция просто вернет управление и ничего делать не станет. А если такие ссылки есть, мы получим адрес массива структур IMAGE_THUNK_DATA, в котором содержится информация об импортируемых идентификаторах. Далее в списке из KerneI32.dll ведется поиск идентификатора с адресом, совпадающим с искомым. В данном случае мы ищем адрес, соответствующий адресу функции ExitProcess.

Если такого адреса нет, значит, данный модуль не импортирует нужный идентификатор, и ReplaceLWEntryInOneMod просто возвращает управление. Но если адрес обнаруживается, мы вызываем WriteProcessMemory, чтобы заменить его на адрес подставной функции Я применяю WriteProcessMemory, а не InterlockedExchangePomter, потому что она изменяет байты, не обращая внимания на тип защиты страницы памяти, в которой эти байты находятся Так, если страница имеет атрибут защиты PAGE_READONLY, вызов InterlockedExchangePointer приведет к нарушению доступа, а WriteProcessMemory сама модифицирует атрибуты защиты и без проблем выполнит свою задачу.

С этого момента любой поток, выполняющий код в модуле DataBase.exe, при обращении к ExitProcess будет вызывать нашу функцию. А из нее мы сможем легко получить адрес исходной функции ExitProcess в Kernel32.dll и при необходимости вызвать ее,

Обратите внимание, что ReplaceIATEntryInOneMod подменяет вызовы функций только в одном модуле. Если в его адресном пространстве присутствует другая DLL, использующая ExitProcess, она будет вызывать именно ExitProcess из Kernel32.dll.

Если Вы хотите перехватывать обращения к ExitProcess из всех модулей, Вам придстся вызывать ReplacelATEntryInOneMod для каждого модуля в адресном пространстве процесса. Я, кстати, написал еще одну функцию, ReplacelATEntryInAllMods. С помощыо Toolhelp-функций она перечисляет все модули, загруженные в адресное пространство процесса, и для каждого из них вызывает ReplatelATEritryInOneMod, передавая в качестве последнего параметра описатель соответствующего модуля.




Начало  Назад  Вперед