Нужно получить указатель на DriverObject по имени драйвера, использую: ObReferenceObjectByName(&szLinkPath, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDeviceObjectType, KernelMode, NULL, &lpDeviceObject); но не знаю что значит экспортируемая переменная: IoDeviceObjectType, если на ее место поставить NULL, то будет ошибка, от чего зависит значение этой переменной? В одном из драйверов она равна: 805509e0h, вроде указывает куда-то в ntoskrnl.exe P.S. вообще то пишу на fasm'е пример привел для краткости
Эта переменная определяет тип объекта, вот список: POBJECT_TYPE *ExEventPairObjectType; POBJECT_TYPE *PsProcessType; POBJECT_TYPE *PsThreadType; POBJECT_TYPE *PsJobType; POBJECT_TYPE *LpcPortObjectType; POBJECT_TYPE *LpcWaitablePortObjectType; POBJECT_TYPE *IoDriverObjectType; POBJECT_TYPE *IoDeviceObjectType; POBJECT_TYPE *MmSectionObjectType;
Это указатель на OBJECT_TYPE - структура, описывающая тип объекта и содержащая необходимые функции и значения для создания, удаления, парсинга данного типа объектов. typedef struct _OBJECT_TYPE { ERESOURCE Mutex; LIST_ENTRY TypeList; UNICODE_STRING Name; PVOID DefaultObject; ULONG Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; } OBJECT_TYPE, *POBJECT_TYPE; и главное там - OBJECT_TYPE_INITIALIZER, структура, которая передается в функцию ObCreateObjectType: typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; BOOLEAN UseDefaultObject; BOOLEAN Reserved; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; BOOLEAN MaintainTypeList; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; OB_DUMP_METHOD DumpProcedure; OB_OPEN_METHOD OpenProcedure; OB_CLOSE_METHOD CloseProcedure; OB_DELETE_METHOD DeleteProcedure; OB_PARSE_METHOD ParseProcedure; OB_SECURITY_METHOD SecurityProcedure; OB_QUERYNAME_METHOD QueryNameProcedure; OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure; } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
Deyton Еще есть IoFileObjectType и CmpKeyType (для файлов и реестра соответственно, причем IoFileObjectType экспортируется, тогда как CmpKeyType не экспортируется)
К тому же, IoFileObjectType->ParseProcedure не делает ничего, кроме проверки пары параметров на валидность - после этого передает вызов в IoDeviceObjectType->ParseProcedure, которая парсит переданое имя и уже делает все дальнейшие операции (в зависимости от значений в OPEN_PACKET или вызывает обработчики IRP девайса или вызывает FastIo для FastIoOpenQuery/FastIoOpenQueryNetworkInfo - это в случае удачного парсинга, или вызывает самое себя в случае STATUS_NEED_REPARSE или ничего если ошибка).
Ну тогдя и я добавлю свои 5 копеек, как найти то что не экспортируется Код (Text): POBJECT_TYPE CmpKeyObjectType; NTSTATUS InitObjectType() { OBJECT_ATTRIBUTES objectAttributes = {0}; HANDLE runKey = NULL; NTSTATUS ntStatus; UNICODE_STRING RegistryPath; UNICODE_STRING RegistryValue; WCHAR Value[MAX_PATH]; PCM_KEY_BODY KeyBody; RtlInitUnicodeString(&RegistryPath, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); InitializeObjectAttributes(&objectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenKey(&runKey, KEY_ALL_ACCESS, &objectAttributes); if(!NT_SUCCESS(ntStatus)) { return ntStatus; } ntStatus = ObReferenceObjectByHandle(runKey, 0, NULL, KernelMode, (PVOID *)(&KeyBody), NULL); if(NT_SUCCESS(ntStatus)) { POBJECT_HEADER obHeader = OBJECT_TO_OBJECT_HEADER((PVOID)KeyBody); CmpKeyObjectType = obHeader->ObjectType; ObDereferenceObject(KeyBody); } ZwClose(runKey); return ntStatus; }
Да - единственная проблема, что PsProcessType & PsThreadType не имеют OpenProcedure/ParseProcedure и для хуков не представляют интереса, хотя имеют процедуру DeleteProcedure - которая иногда тоже полезной может быть Существует еще IoSymbolicLinkObjectType - если хукнуть имеющуюся там ParseProcedure, винда спустя несколько мгновений валится в синяк (причина - особенности парсинга данного типа объектов, в виду того, что сравнивается ->ParseProcedure и фиксированный адрес, хотя это можно сплайсингом обойти). В принципе, SymbolicLinkObjectType->TypeInfo->ParseProcedure вызывается практически при любом вызове Object Manager.
. Хоть они и не имеют данных методов, но этим типам можно записать свое значение OpenProcedure, тогда при открытии объектов данных типов, наша функция будет вызыватся. Указатель на любой объект-тип (IoFileObjectType, CmpKeyType или любой другой) можно получить, если открыть соответствующий объект в директории \ObjectTypes\ с помощью ObReferenceObjectByName (например, \ObjectTypes\File, \ObjectTypes\Key и т.д.).