Старые антиотладочные приемы на новый лад

Доступ к физической памяти


В ms-dos код отладчика и системные данные (например, таблица векторов прерываний) находились в одном адресном пространстве с отлаживаемой программой, что открывало большой простор для методов борьбы. Можно было проскандировать память и убить отладчик или просто задействовать отладочные вектора (int01h и int 03h) под нужны защитного механизма, положив туда что-то полезное (скажем, ключ расшифровки), а через некоторое время считать его обратно. Если никакого отладчика нет или он неактивен, искажение отладочных векторов не нарушает работоспособности операционной системы и мы читаем то, что поклали. А вот под отладчиком все будет иначе. Скорее всего произойдет тотальный крах, поскольку при генерации трассировочного прерывания или достижении точки останова, управление будет передано в "космос" (вектор ведь искажен!). Если же отладчик принудительно восстановит вектора, тогда вместо сохраненных данных, защищенная программа прочитает уже не ключ расшифровки, а нечто совершенно иное! Теоретически, на 386+ процессорах отладчик может контролировать доступ к отладочным векторам и эмулировать операции чтения/записи, не производя их на самом деле. Но это потребует двух аппаратных точек останова, которых в x86 процессорах всего четыре, да и тех постоянно не хватает, так что разбрасывается ими не резон.

Операционная система Windows использует раздельные адресные пространства и виртуальную память, а это значит, что отлаживаемое приложение не может "дотянуться" ни до отладчика, ни до векторов прерываний. Можно, конечно, написать драйвер (как известно, драйвер может все или практически все), но о сопутствующих проблемах мы уже говорили. Написание драйверов требует высокой квалификации, к тому же в силу их крошечного размера, драйвера очень просто ломать, а написать сложный драйвер практически нереально — его "пуско-наладка" займет всю оставшуюся жизнь.

В операционных системах семейства NT имеется специальное псевдоустройство "PhysicalMemory", предоставляющее доступ к физической памяти на чтение/запись.
Это действительно физическая память, причем еще до виртуальной трансляции и в ней есть все то, что находится в памяти компьютера в данный момент. Страниц, выгруженных на диск в файл подкачки, там нет, но нам их и не надо. Нам нужен код и данные операционной системы.

При наличии прав администратора мы можем не только читать "PhysicalMemory", но и писать. Да-да! Вы не ослышались и это не опечатка! С прикладного уровня можно проникнуть в святая святых операционной системы, свободно модифицируя код, исполняющийся на привилегированном уровне нулевого кольца (RING0), а это, значит, что мы фактически имеем RING0 на прикладном кольце (RING3)! Любой отладчик может быть уничтожен без проблем, даже если это отладчик-эмулятор. Исключение составляют лишь виртуальные машины типа BOCHS, но, как мы уже говорили, пытаться отладить Windows приложение на них несерьезно. Хакер утонет в посторонних потоках и системных вызовах!

Некоторые считают PhysicalMemory ужасной дырой в безопасности. Дескать, как это так — с прикладного уровня и сразу в дамки! На самом деле здесь нет ничего ненормального. Если у хакера есть права администратора, он может беспрепятственно загружать драйвера, из которых можно делать все, что угодно, причем, в NT загрузка драйвера не требует перезагрузки, а это, значит, что наличие псевдоустройства "PhysicalMemory" никак, я повторяю НИКАК, не отражается на безопасности, а всего лишь делает доступ к физической памяти более комфортным и удобным. В UNIX (модель безопасности которой вырабатывалась годами) издавна существуют псевдоустройства /dev/mem и /dev/kmem предоставляющие доступ к физической памяти до и после трансляции, но никто не собирается их критиковать. Эта функция нужна достаточно многим системным программам и самой операционной системе, если ее изъять программисты начнут писать свои драйвера, предоставляющие доступ к физической памяти, и тогда начнется полный разброд и распад, поскольку в них не исключены всякого рода ошибки. Разработчик драйвера может забыть о проверке уровня привилегий и давать доступ не только администраторам, а всем пользователям системы, что будет нехорошо.


Тем не менее, Microsoft все-таки пошла на довольно-таки спорный шаг и в Windows 2003 Server с установленным Service Pack 1 доступа к PhysicalMemory уже не имеет ни администратор, ни даже System. (см. статью "Changes to Functionality in Microsoft Windows Server 2003 Service Pack 1 Device\PhysicalMemory Object" на сайте Microsoft: www.microsoft.com/technet/prodtechnol/windowsserver2003/library/BookofSP1/e0f862a3-cf16-4a48-bea5-f2004d12ce35.mspx).

Тем не менее, на всех остальных системах данный прием работает вполне нормально, поэтому не стоит списывать его со счетов, а с Windows 2003 Sever SP1 мы еще разберемся! (Не сейчас, в смысле еще не в этой статье, но как-нибудь потом).

Давайте возьмем утилиту objdir из пакета NT DDK и запустим ее с параметром "\Device" (просмотр устройств и псевдоустройств, установленных в системе). Вот что она скажет:

$objdir \Devic

...

ParallelVdm0         Device

ParTechInc0          Device

ParTechInc1          Device

ParTechInc2          Device

PfModNT                    Device

PhysicalMemory    Section

PointerClass0        Device

Processor            Device

RasAcd               Device

RawCdRom             Device


Содержание раздела