You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
coding<br />
Последствия неаккуратного написания драйверов Загрузчик Windows Vista<br />
ядром (ntoskrnl.exe), вторая — графической подсистемой (win32k.sys), а<br />
остальные две зарезервированы на будущее и пока не используются.<br />
Когда какое-либо приложение пытается получить доступ к реестру, оно<br />
вызывает API-функцию из Advapi32.dll. В случае когда приложение пытается<br />
создать ключ реестра, оно обращается к функции RegCreateKey или<br />
RegCreateKeyEx. В свою очередь код этих функций обращается к шлюзу<br />
NtCreateKey, находящемуся в ntdll.dll. Почему я сказал «шлюз» вместо<br />
«функции» Все очень просто. На самом деле, NtCreateKey не делает ничего,<br />
кроме вызова соответствующего системного сервиса. Схематично<br />
код этой функции выглядит примерно так:<br />
Возможный код NtCreateKey<br />
mov<br />
lea<br />
int<br />
ret<br />
eax,29h<br />
xàêåð 06 /102/ 07<br />
/<br />
edx,[esp+4]<br />
2Eh<br />
Как видно из приведенного примера, сначала в регистр eax заносится<br />
число 29h. Это число означает номер системного сервиса в таблице<br />
дескрипторов системных сервисов. То есть, если говорить проще, 41‐й<br />
элемент в этой таблице является указателем на точку входа в системный<br />
сервис, который создает ключ в реестре. После того как в eax загружено<br />
смещение, а в edx — указатель на передаваемые параметры, вызывается<br />
специальное прерывание 2Eh для перевода процессора в нулевое кольцо.<br />
По найденному в таблице системных сервисов смещению происходит<br />
переход на код, который дальше выполняет все необходимые действия.<br />
Драйвер утилиты RegMon занимался тем, что подменял нужные ему<br />
смещения в этой таблице своими. Таким образом, когда какое-либо<br />
приложение пыталось обратиться к реестру, вызывался код драйвера<br />
RegMon'а, который, собрав нужную ему информацию, делал оригинальный<br />
вызов, чтобы не приводить системы в нерабочее состояние. Но с<br />
выходом Windows Vista эту возможность прикрыли, обосновав это тем, что<br />
этой технологией пользуются руткиты, а для антивирусов, файрволов и<br />
других подобных программ еще в Windows XP был предложен специальный<br />
механизм для перехвата обращений к реестру.<br />
Фильтрация обращений к реестру<br />
С выходом Windows XP появилось понятие registry filtering driver. Дословно<br />
оно переводится как «драйвер, фильтрующий обращения к реестру».<br />
Собственно, из названия вытекает и содержание — это драйвер режима<br />
ядра, который фильтрует обращения к системному реестру. Фильтрация<br />
обращений происходит за счет установки callback-вызова на функции<br />
обращения к реестру. Установить свой callback-вызов можно с помощью<br />
следующей функции:<br />
NTSTATUS<br />
CmRegisterCallback(<br />
IN PEX_CALLBACK_FUNCTION Function,<br />
IN PVOID Context,<br />
OUT PLARGE_INTEGER Cookie<br />
);<br />
Здесь Function — это указатель на функцию callback-вызова, который<br />
надо зарегистрировать. Context — указатель на некую структуру данных,<br />
которая содержит служебную информацию и определяется самим драйвером.<br />
Cookie — указатель на переменную типа LARGE_INTEGER, которая<br />
идентифицирует callback-рутину. В последствии этот параметр будет<br />
использоваться при снятии callback-вызова. Вызов CmRegisterCallback<br />
должен происходить при IRQL, меньшем или равном APC_LEVEL. В<br />
Windows Vista появилась новая функция для этих целей. Ее прототип<br />
представлен ниже.<br />
NTSTATUS<br />
CmRegisterCallbackEx(<br />
IN PEX_CALLBACK_FUNCTION Function,<br />
IN PCUNICODE_STRING Altitude,<br />
IN PVOID Driver,<br />
IN PVOID Context,<br />
OUT PLARGE_INTEGER Cookie<br />
PVOID Reserved<br />
);<br />
Как видно из описания функции, некоторые ее параметры схожи с<br />
предыдущими, но есть и новые. Altitude — это указатель на строку<br />
типа UNICODE_STRING, которая используется в драйверах минифильтрах.<br />
Driver — указатель на структуру объекта драйвера, который<br />
осуществляет вызов. Ну и, наконец, Reserved, название которого<br />
говорит само за себя.<br />
Когда перехватывать обращения к реестру нам больше не нужно, следует<br />
вызвать функцию CmUnRegisterCallback.<br />
115