Реализация защиты на уровне "родного" API для ОС Windows NT
Один из способов обеспечения прозрачной защиты связан с заменой механизма предоставления функций "родного" API. Как уже рассматривалось в главе "Общая архитектура Windows NT", системные сервисы могут быть предоставлены коду пользовательского режима посредством использования библиотеки ntdll.dll. В ntdll.dll вызов системных сервисов происходит с помощью программного прерывания int 2E. После чего обработчик прерывания для вызова соответствующего системного сервиса использует таблицу распределения системных сервисов (KeServiceDescriptorTable), экспортируемую ntoskrnl.exe (ядро и исполнительная система).
Структура этой таблицы следующая:
- указатель на массив, содержащий 4-х байтовые адреса точек входа системных сервисов в ntoskrnl.exe (4 байта);
- 00000000 (4 байта);
- количество системных сервисов (4 байта);
- указатель на массив, содержащий однобайтовые значения, определяющие сколько байт надо извлечь из стека режима пользователя, содержащего параметры функции (4 байта).
Зная индексный номер функции, реализующей системный сервис, можно по таблице определить адрес ее начала и заменить его на адрес начала собственного обработчика режима ядра. После исполнения собственного обработчика необходимо передать управление по старому адресу, чтобы дать возможность стандартному обработчику выполнить запрошенные действия.
Так как эта таблица находится в системной области памяти, то такая замена может выполняться только кодом режима ядра (например, драйвером).
Примером подобного средства защиты может служить программный продукт RegMon for Windows NT, выполняющий перехват системных сервисов, реализующих обращение к реестру Windows NT.