Новый фильтрующий механизм в Vista SP1 и Serever 2008
От: Andrew.W Worobow https://github.com/Worobow
Дата: 17.01.08 15:57
Оценка: 40 (6)
В Vista SP1 и Server 2008 появился новый фильтрующий механизм для объектов ядра. Это было сделано для того чтобы обеспечить необходимым механизмом фильтрации те приложения которые в этом нуждаются, например всевозможное антивирусное ПО и ПО обеспечивающее так называемое Securyty Enveronment. Да и ждать другого было просто глупо, так это важная часть рынка ОС, и запретив хоть никогда легально и не поддерживаемое хучинье SSDT, МС не мог не предложить что-то в замен. Вот поэтому и появились поддержка callback'ов для реестра и вот появляется такая же поддержка для объектов.

Откровенно говоря, нового-то вообщем-то ничего и не появилось, с созданием этой новой фильтрующей поддержки, ведь собственно и раньше при знании некоторых недокументированных структур можно было фильтровать практически все методы работы с объектами. Здесь я речь веду об структуре OBJECT_TYPE_INITIALIZER, которая входит в структуру OBJECT_HEADER. Там есть набор указателей на специальные процедуры связанные с действиями (методами) над всеми объектами. А это ни много ни мало как DumpProcedure, OpenProcedure, CloseProcedure, DeleteProcedure, ParseProcedure, SecurityProcedure, QueryNameProcedure, OkayToCloseProcedure. Но так как все это совершенно не документированно, то честь прототипов этих процедур расковыренна и есть в сети, а часть нет.

С WDK структура OBJECT_HEADER, объявлена как заглушка, как просто указатель. Но в сети есть много мест где лежит ее определение.
На пример тут OBJECT_HEADER.

Получить объект из HANDLE, можно легально, для этого надо воспользоваться функцией ObReferenceObjectByHandle которая вернет указатель на объект, PFILE_OBJECT, PKEVENT, PEPROCESS or PKPROCESS, PETHREAD or PKTHREAD, PTKM, PKRESOURCEMANAGER, PKENLISTMENT, PKTRANSACTION. Это на самом деле так называемое тело объекта, а заголовок лежит выше. И перейти от тела к заголовку можно стандартным МС'овским макросом — CONTAINING_RECORD, точнее OBJECT_TO_OBJECT_HEADER, поищите в сети его определение лежит на сотне страниц. Я это пишу, только чтобы меня не обвинили потом в раскрытии некой внутренней информации. Но все же давайте приведем его и тут.

#define OBJECT_TO_OBJECT_HEADER(obj) \
    CONTAINING_RECORD( (obj), OBJECT_HEADER, Body )


Понятно что для того что бы им воспользоваться необходимо знать структуру OBJECT_HEADER.

Таким образом, мы переходим к заголовку объекта, из которого можно получить указатель на структуру определяющую тип данного объекта POBJECT_TYPE. Конечно, можно было и не вытаскивать тип POBJECT_TYPE из OBJECT_HEADER, ведь WINDOWS экспортирует несколько типов, посмотрите в WDM.h

extern POBJECT_TYPE *IoFileObjectType;
extern POBJECT_TYPE *ExEventObjectType;
extern POBJECT_TYPE *ExSemaphoreObjectType;
extern POBJECT_TYPE *TmTransactionManagerObjectType;
extern POBJECT_TYPE *TmResourceManagerObjectType;
extern POBJECT_TYPE *TmEnlistmentObjectType;
extern POBJECT_TYPE *TmTransactionObjectType;
extern POBJECT_TYPE *PsProcessType;
extern POBJECT_TYPE *PsThreadType;


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

Структура POBJECT_TYPE, также объявлена в WDK как заглушка, как указатель на структуру OBJECT_TYPE, но опять же в сети есть не мало мест где эта структура раскрывается. Например тут — POBJECT_TYPE. Там же есть и составляющая её структура OBJECT_TYPE_INITIALIZER, в которой эти процедуры и объявлены, точнее это то место где, вы можете указать свою процедуру метода, и получить фильтр этих операций. Например указав OpenProcedure, вы будите вызваны ровно когда, в данном случае файл открывается.

Но хочу сразу, разочаровать, дело в том, что все эти не документированные структуры очень часто меняются, и вот например в x64 висте они/она другие. Таким образом, строить системы фильтрации на этом стааааром механизме, можно но необходимо учитывать этот факт. Для проверки можно например проверять получив заголовок объекта для файла, куда указывает тип, если на (*IoFileObjectType) то ОК, если нет, то увы. Кроме того, должна совпадать длинна указанная в структуре OBJECT_TYPE_INITIALIZER, с действительным размером этой структуры.


Но тем не менее, можно радоваться в Vista SP1 и Server 2008, появился легальный способ получить callback'и для объектов.

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

Для того чтобы зарегистрировать callback надо вызвать ObRegisterCallbacks заполнив структуру OB_CALLBACK_REGISTRATION и массив callback'в OB_OPERATION_REGISTRATION указав операции OB_OPERATION_HANDLE_CREATE и/или OB_OPERATION_HANDLE_DUPLICATE. Я думаю что здесь излагать подробности излишне — в MSDN'е есть все.

Маловато конечно но что делать хоть что-то, и зато легально.

Все это декларировано, что работает только Windows Server 2008 и Vista SP1.

Описание недокументированных структур ядра можно смотреть тут Windows Vista Kernel Structures там конечно не все правильно, и полно, но что есть, то есть. По-моему народ там только для x32 битной версии структуры привел. А это как раз меньше всего интересно.

В висте x64 все структуры кроме OBJECT_TYPE, не изменились, а эта изменилась. Но все равно, с правильной структурой фильтрация работает!



Ссссылки
---------


ДИСПЕТЧЕР ОБЪЕКТОВ WINDOWS NT ИЗНУТРИ -- Не дюженный труд! Но как всегда уже не актуальный, но для ознакомления подойдет.
New Object Manager Filtering APIs -- Блог с более подробным описанием нового мезанизма, но опять таки все уже есть в MSDN'e
Kernel Data and Filtering Support for Windows Server 2008 -- Главный документ и описание, от МС'а




*
Не все кто уехал, предал Россию.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.