Самоучитель по программированию систем защиты

       

Перехват операций открытия, создания и удаления файлов



Перехват операций открытия, создания и удаления файлов

Реализация драйвером перехвата файловых операций основана на недокументированном механизме перехвата системных сервисов, описанном в разделе «Реализация защиты на уровне собственного API для ОС Windows NT».

Принцип функционирования драйвера основан на механизме замены адресов функций, предоставляемых «родным» API. Обработчик прерывания int 2E для вызова соответствующего системного сервиса использует таблицу распределения системных сервисов KeServiceDescriptorTable, экспортируемую ntoskrnl.exe.

Во время инициализации драйвера в функции DriverEntry, после успешного создания объекта-устройства, устанавливаются собственные обработчики файловых операций. Для этого сначала надо получить адрес таблицы распределения системных сервисов:

ServiceTable = KeServicepescriptorTable;

Зная индексный номер функции, реализующей системный сервис, можно ио таблице определить адрес ее начала и заменить его на адрес начала собственного обработчика режима ядра.

Это делается следующим образом:

#define SYSCALL(_function)

ServiceTable->ServiceTable[ *(PULONG)((PUCHAR)_function+l)]

RealCreateFile = SYSCALL( ZwCreateFile );

//RealCreateFile - оригинальный обработчик создания файла;

SYSCALL( ZwCreateFile ) = (PVOID) HookCreateFile;

//HookCreateFile - собственный обработчик создания файла;



RealO'penFile = SYSCALL ( ZwOpenFile );

//RealOpenFile - оригинальный обработчик открытия файла;

SYSCALL( ZwOpenFile ) = (PVOID) HookOpenFile;

//HookOpenFile - собственный обработчик открытия файла;

При перехвате функций ZwCreateFile и ZwOpenFile необходимо учитывать, что операции запуска исполняемых файлов, переименования и удаления объектов производятся именно этими функциями при установленных следующим образом флагах: .

DesiredAccess & DELETE - операция удаления файла,

DesiredAccess & FILE_EXECUTE)

(DesiredAccess & GENERIC_EXECUTE) - запуск исполняемого файла.

Отдельную задачу представляет собой различение операций с объектами типа PIPE или СОМ-порт. В ряде случаев это может быть сделано по имени, например, memcmp(AnsiString.Buffer, "\\dosdevices\\com", 15) после выполнения фрагмента кода:

UnString.Length = (USHORT)

ObjectAttributes->ObjectName->Length;

UnString.MaximumLength = (USHORT)

ObjectAttributes->ObjectName-> ., ,.

MaximumLength-; . ,

UnString.Buffer = ObjectAttributes->ObjectName->Buffer;.

RtlUnicodeStringToAnsiString

.. ( SAnsiString, SUnString, TRUE ),.;

 



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