Для многих не секрет, что в ядре ОС присутствует функция открытия объекта по имени, которая, в случае успешного исполнения, создает описатель на объект. Она экспортируемая и удобна в использовании. Если заглянуть в WRK, то можно скопировать себе ее объявление:
NTKERNELAPI NTSTATUS ObOpenObjectByName( __in POBJECT_ATTRIBUTES ObjectAttributes, __in_opt POBJECT_TYPE ObjectType, __in KPROCESSOR_MODE AccessMode, __inout_opt PACCESS_STATE AccessState, __in_opt ACCESS_MASK DesiredAccess, __inout_opt PVOID ParseContext, __out PHANDLE Handle );
То есть, как видно из декларации, параметр типа объекта (ObjectType) опциональный. Так и было до Windows 7. Но взглянем на потроха этой функции в ядре семерки:
82a72b46 33c0 xor eax,eax ... ; выход с ошибкой 82a72b55 b80d0000c0 mov eax,0C000000Dh ; STATUS_INVALID_PARAMETER 82a72b5a e9c2030000 jmp nt!ObOpenObjectByName+0x3ea (82a72f21) ... 82a72b5f 39450c cmp dword ptr [ebp+0Ch],eax ; проверка на NULL 82a72b62 74f1 je nt!ObOpenObjectByName+0x1e (82a72b55)
Как видно из приведенных строк, параметр указателя типа (ebp+0Ch) перестал быть опциональным. К сожалению не все типы объектов ядра экспортируются. И к тому же, функция создания типа объектов (ObCreateObjectType) экспортирована. Это позволяет создавать типы объектов ядра в драйверах. Довольно элегантное решение предложил jibe. В ядре Windows 7 экспортируется функция ObGetObjectType:
POBJECT_TYPE NTAPI ObGetObjectType( __in PVOID Object );
Эта функция позволяет получить тип объекта ядра по указателю на сам объект. Достаточно вызвать ее один раз, указав в качестве параметра любой тип объекта (например: ExEventObjectType) и мы получим внутренний указатель на объект типа объектов, то есть не экспортируемый символ ObpTypeObjectType. Это позволит нам открывать любой объект типа объектов по имени той же функцией ObOpenObjectByName. Имея на руках указатель на не экспортируемый тип, мы с легкостью можем создавать описатели (вызывать ObOpenObjectByName) на объекты по имени, как и на младших версиях ОС.
ΞρεΤΙκ