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

открытие псевдоустройства PhysicalMemory


Возможно, мы захотим предоставить доступ к псевдоустройству PhysicalMemory не только администратору, но и всем другим пользователям. Для этого необходимо изменить права. Естественно, делать это может только администратор, зато потом физическую память будут трогать все кому не лень. Многие вирусы и root-kit'ы именно так и поступают. Они прописывают себя в автозагрузке (или любым другим путем закрепляются в системе) и ждут пока пользователь хотя бы разочек не зайдет в систему под администратором. После этого они меняют права на PhysicalMemory и дальше работают уже из-под пользователя. Легальные программы, в частности защитные механизмы, зачастую поступают так же. Требуя администратора лишь на стадии установки они, тем не менее, успевают за это время существенно ослабить безопасность системы. Ну что тут можно сказать? Никогда не устанавливайте на компьютер программ, которым не вполне доверяете. То есть, не устанавливайте никаких программ вообще. Шутка. Ладно, не будем отвлекаться, а лучше рассмотрим какие шаги необходимо предпринять для изменения атрибутов доступа.

q       открываем \Device\PhysicalMemory, используя NtOpenSection, получаем дескриптор

q       извлекаем из него дескриптор безопасности (security descriptor) через GetSecurityInfo

q       добавляем права на чтение/запись в текущий ACL с помощью функции SetEntriesInAcl

q       обновляем дескриптор безопасности посредством вызова SetSecurityInfo

q       закрываем дескриптор, возвращенный NtOpenSection

Теперь физическую память можно читать и писать. Для этого секцию PhysicalMemory нужно спроецировать на виртуальное адресное пространство, вызвав NativeAPI-функцию NtMapViewOfSection. Ниже показано как это сделать:

// переменные-аргументы

HANDLE Section       = xxx; // ß

входной параметр дескриптор секции

PVOID vAddress       = xxx; // ß

входной параметр виртуальный адрес куда проецировать

DWORD Size    = xxx; // ß

кол-во байт для проецирования от начала секции

// прочие переменные, инициализированные программой

PHYSICAL_ADDRESS pAddress; NTSTATUS ntS; DWORD MappedSize; PVOID MappedAddress=NULL;

// ВНИМАНИЕ! ФУНКЦИИ __GetPhysicalAddress НЕ СУЩЕСТУЕТ В ПРИРОДЕ!

// ОНА ДАНА ЧИСТО УСЛОВНО. НИЖЕ ПО ТЕКСТУ БУДЕТ ОБЪЯСНЕНО ПОЧЕМУ

pAddress = __GetPhysicalAddress((PVOID) vAddress);

// проецируем секцию PhysicalMemory на виртуальное адресное пространство

ntS = NtMapViewOfSection(Section, (HANDLE) -1, &MappedAddress, 0L, Size,

                                  &pAddress, &MappedSize, 1, 0, PAGE_READONLY);



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