1、目的
在一般情况下,对于系统的常规操作如创建进程、创建互斥体、创建文件等可以进行SSDT Hook进行拦截,但在x64位系统下,有PG的保护,常规的SSDT Hook会导致蓝屏。但基于ObjectType的一些Hook也可以做到相应的功能且不会导致系统 BSOD。
2、相关结构分析
2.1 XP上的相关结构
2.1.1 WinDbg调试结构
首先是 _OBJECT_HEADER结构
0: kd> dt _object_header
nt!_OBJECT_HEADER
+0x000 PointerCount : Int4B
+0x004 HandleCount : Int4B
+0x004 NextToFree : Ptr32 Void
+0x008 Type : Ptr32 _OBJECT_TYPE
+0x00c NameInfoOffset : UChar
+0x00d HandleInfoOffset : UChar
+0x00e QuotaInfoOffset : UChar
+0x00f Flags : UChar
+0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : Ptr32 Void
+0x014 SecurityDescriptor : Ptr32 Void
+0x018 Body : _QUAD
在第四个字段就是 _OBJECT_TYPE,其结构如下:
0: kd> dt _OBJECT_TYPE
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY
+0x040 Name : _UNICODE_STRING
+0x048 DefaultObject : Ptr32 Void
+0x04c Index : Uint4B
+0x050 TotalNumberOfObjects : Uint4B
+0x054 TotalNumberOfHandles : Uint4B
+0x058 HighWaterNumberOfObjects : Uint4B
+0x05c HighWaterNumberOfHandles : Uint4B
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : Uint4B
+0x0b0 ObjectLocks : [4] _ERESOURCE
其中的TypeInfo为 _OBJECT_TYPE_INITIALIZER结构,其内容如下:
0: kd> dt _OBJECT_TYPE_INITIALIZER
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : Uint2B
+0x002 UseDefaultObject : UChar
+0x003 CaseInsensitive : UChar
+0x004 InvalidAttributes : Uint4B
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : Uint4B
+0x01c SecurityRequired : UChar
+0x01d MaintainHandleCount : UChar
+0x01e MaintainTypeList : UChar
+0x020 PoolType : _POOL_TYPE
+0x024 DefaultPagedPoolCharge : Uint4B
+0x028 DefaultNonPagedPoolCharge : Uint4B
+0x02c DumpProcedure : Ptr32 void
+0x030 OpenProcedure : Ptr32 long
+0x034 CloseProcedure : Ptr32 void
+0x038 DeleteProcedure : Ptr32 void
+0x03c ParseProcedure : Ptr32 long
+0x040 SecurityProcedure : Ptr32 long
+0x044 QueryNameProcedure : Ptr32 long
+0x048 OkayToCloseProcedure : Ptr32 unsigned char
其中靠后的如 OpenProcedure、CloseProcedure、ParseProcedure等就是我们关注的需要Hook的字段,通过Hook这些字段来实现打开创建相应的对象的过滤操作。
2.1.2 实际中使用的情况
我们经过一些操作来看看XP上的进程对象的相关字段对应的函数
先通过!process命令获取explorer.exe的EPROCESS
0: kd> !process 0 0 explorer.exe
Failed to get VadRoot
PROCESS 89fc3338 SessionId: 0 Cid: 0604 Peb: 7ffd4000 ParentCid: 05f4
DirBase: 0aac01c0 ObjectTable: e1835490 HandleCount: 487.
Image: explorer.exe
获取到的结果为PROCESS 89fc3338, 看看对应的数据如下:
0: kd> dt _eprocess 89fc3338
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER 0x01d99c3e`eb1d80e8
+0x078 ExitTime : _LARGE_INTEGER 0x0
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : 0x00000604 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8a2a8688 - 0x8a0b8738 ]
+0x090 QuotaUsage : [3] 0x34a8
+0x09c QuotaPeak : [3] 0x4650
+0x0a8 CommitCharge : 0xfe0
+0x0ac PeakVirtualSize : 0x6aee000
+0x0b0 VirtualSize : 0x6031000
+0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0x8a2a86b4 - 0x8a0b8764 ]
+0x0bc DebugPort : (null)
+0x0c0 ExceptionPort : 0xe166ca10 Void
+0x0c4 ObjectTable : 0xe1835490 _HANDLE_TABLE
+0x0c8 Token : _EX_FAST_REF
+0x0cc WorkingSetLock : _FAST_MUTEX
+0x0ec WorkingSetPage : 0x16b59
+0x0f0 AddressCreationLock : _FAST_MUTEX
+0x110 HyperSpaceLock : 0
+0x114 ForkInProgress : (null)
+0x118 HardwareTrigger : 0
+0x11c VadRoot : 0x8a32c2a8 Void
+0x120 VadHint : 0x8a32c2a8 Void
+0x124 CloneRoot : (null)
+0x128 NumberOfPrivatePages : 0xa5e
+0x12c NumberOfLockedPages : 0
+0x130 Win32Process : 0xe1d749e0 Void
+0x134 Job : (null)
+0x138 SectionObject : 0xe1d7bbd0 Void
+0x13c SectionBaseAddress : 0x01000000 Void
+0x140 QuotaBlock : 0x8a4b7e58 _EPROCESS_QUOTA_BLOCK
+0x144 WorkingSetWatch : (null)
+0x148 Win32WindowStation : 0x00000038 Void
+0x14c InheritedFromUniqueProcessId : 0x000005f4 Void
+0x150 LdtInformation : (null)
+0x154 VadFreeHint : (null)
+0x158 VdmObjects : (null)
+0x15c DeviceMap : 0xe19f0990 Void
+0x160 PhysicalVadList : _LIST_ENTRY [ 0x89fc3498 - 0x89fc3498 ]
+0x168 PageDirectoryPte : _HARDWARE_PTE
+0x168 Filler : 0
+0x170 Session : 0xba5d0000 Void
+0x174 ImageFileName : [16] "explorer.exe"
......
其中用不着EPROCESS的结构,获取这个的地址是为了获取_OBJECT_HEADER的地址,在XP环境的代码中可以用以下来获取到_OBJECT_HEADER地址,因为_OBJECT_HEADER结构中的Body部分就是获取的对应的对象,如EPROCESS。
#define ObObjectToObjectHeader(x) ((POBJECT_HEADER)(((PUCHAR)(x))-0x18))
操作如下:
0: kd> dt _object_header 89fc3338-0x18
nt!_OBJECT_HEADER
+0x000 PointerCount : 0n185
+0x004 HandleCount : 0n6
+0x004 NextToFree : 0x00000006 Void
+0x008 Type : 0x8a4a4ca0 _OBJECT_TYPE
+0x00c NameInfoOffset : 0 ''
+0x00d HandleInfoOffset : 0 ''
+0x00e QuotaInfoOffset : 0 ''
+0x00f Flags : 0x20 ' '
+0x010 ObjectCreateInfo : 0x8a4b7e58 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : 0x8a4b7e58 Void
+0x014 SecurityDescriptor : 0xe1cd5ed3 Void
+0x018 Body : _QUAD
再继续打印_OBJECT_TYPE
0: kd> dt _object_type 0x8a4a4ca0
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY [ 0x8a4a4cd8 - 0x8a4a4cd8 ]
+0x040 Name : _UNICODE_STRING "Process"
+0x048 DefaultObject : (null)
+0x04c Index : 5
+0x050 TotalNumberOfObjects : 0x11
+0x054 TotalNumberOfHandles : 0x51
+0x058 HighWaterNumberOfObjects : 0x13
+0x05c HighWaterNumberOfHandles : 0x51
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : 0x636f7250
+0x0b0 ObjectLocks : [4] _ERESOURCE
然后是_OBJECT_TYPE_INITIALIZER
0: kd> dx -id 0,0,8055d0c0 -r1 (*((ntkrpamp!_OBJECT_TYPE_INITIALIZER *)0x8a4a4d00))
(*((ntkrpamp!_OBJECT_TYPE_INITIALIZER *)0x8a4a4d00)) [Type: _OBJECT_TYPE_INITIALIZER]
[+0x000] Length : 0x4c [Type: unsigned short]
[+0x002] UseDefaultObject : 0x0 [Type: unsigned char]
[+0x003] CaseInsensitive : 0x0 [Type: unsigned char]
[+0x004] InvalidAttributes : 0xb0 [Type: unsigned long]
[+0x008] GenericMapping [Type: _GENERIC_MAPPING]
[+0x018] ValidAccessMask : 0x1f0fff [Type: unsigned long]
[+0x01c] SecurityRequired : 0x1 [Type: unsigned char]
[+0x01d] MaintainHandleCount : 0x0 [Type: unsigned char]
[+0x01e] MaintainTypeList : 0x0 [Type: unsigned char]
[+0x020] PoolType : NonPagedPool (0) [Type: _POOL_TYPE]
[+0x024] DefaultPagedPoolCharge : 0x1000 [Type: unsigned long]
[+0x028] DefaultNonPagedPoolCharge : 0x290 [Type: unsigned long]
[+0x02c] DumpProcedure : 0x0 [Type: void (*)(void *,_OBJECT_DUMP_CONTROL *)]
[+0x030] OpenProcedure : 0x0 [Type: long (*)(_OB_OPEN_REASON,_EPROCESS *,void *,unsigned long,unsigned long)]
[+0x034] CloseProcedure : 0x0 [Type: void (*)(_EPROCESS *,void *,unsigned long,unsigned long,unsigned long)]
[+0x038] DeleteProcedure : 0x805d263a [Type: void (*)(void *)]
[+0x03c] ParseProcedure : 0x0 [Type: long (*)(void *,void *,_ACCESS_STATE *,char,unsigned long,_UNICODE_STRING *,_UNICODE_STRING *,void *,_SECURITY_QUALITY_OF_SERVICE *,void * *)]
[+0x040] SecurityProcedure : 0x805f9a74 [Type: long (*)(void *,_SECURITY_OPERATION_CODE,unsigned long *,void *,unsigned long *,void * *,_POOL_TYPE,_GENERIC_MAPPING *,char)]
[+0x044] QueryNameProcedure : 0x0 [Type: long (*)(void *,unsigned char,_OBJECT_NAME_INFORMATION *,unsigned long,unsigned long *)]
[+0x048] OkayToCloseProcedure : 0x0 [Type: unsigned char (*)(_EPROCESS *,void *,void *,char)]
在此就可以看到相关函数的定义及实际地址,如DeleteProcedure : 0x805d263a [Type: void (*)(void *)] 就是地址为0x805d263a 函数声明为 void*(void*)的函数。
2.2 Win7 x64以上64位系统的结构分析
2.2.1 WinDbg调试结构
7: kd> dt _object_header
nt!_OBJECT_HEADER
+0x000 PointerCount : Int8B
+0x008 HandleCount : Int8B
+0x008 NextToFree : Ptr64 Void
+0x010 Lock : _EX_PUSH_LOCK
+0x018 TypeIndex : UChar
+0x019 TraceFlags : UChar
+0x01a InfoMask : UChar
+0x01b Flags : UChar
+0x020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION
+0x020 QuotaBlockCharged : Ptr64 Void
+0x028 SecurityDescriptor : Ptr64 Void
+0x030 Body : _QUAD
在64位系统上 _OBJECT_HEADER中并没有字段直接包含_OBJECT_TYPE结构,而是一个索引,索引的是一个名叫 ObTypeIndexTable的表,这个表是一个包含所有ObjectType的表结构,详细可见我另一篇文章
而在这种情况下,实现编程中可以直接通过ObGetObjectType函数直接从实际对象获取的ObjectType的指针。
但_OBJECT_TYPE的结构化仍然可以在WinDbg中获取到,如下:
7: kd> dt _object_type
nt!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY
+0x010 Name : _UNICODE_STRING
+0x020 DefaultObject : Ptr64 Void
+0x028 Index : UChar
+0x02c TotalNumberOfObjects : Uint4B
+0x030 TotalNumberOfHandles : Uint4B
+0x034 HighWaterNumberOfObjects : Uint4B
+0x038 HighWaterNumberOfHandles : Uint4B
+0x040 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0b0 TypeLock : _EX_PUSH_LOCK
+0x0b8 Key : Uint4B
+0x0c0 CallbackList : _LIST_ENTRY
然后是_OBJECT_TYPE_INITIALIZER
7: kd> dt _OBJECT_TYPE_INITIALIZER
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : Uint2B
+0x002 ObjectTypeFlags : UChar
+0x002 CaseInsensitive : Pos 0, 1 Bit
+0x002 UnnamedObjectsOnly : Pos 1, 1 Bit
+0x002 UseDefaultObject : Pos 2, 1 Bit
+0x002 SecurityRequired : Pos 3, 1 Bit
+0x002 MaintainHandleCount : Pos 4, 1 Bit
+0x002 MaintainTypeList : Pos 5, 1 Bit
+0x002 SupportsObjectCallbacks : Pos 6, 1 Bit
+0x002 CacheAligned : Pos 7, 1 Bit
+0x004 ObjectTypeCode : Uint4B
+0x008 InvalidAttributes : Uint4B
+0x00c GenericMapping : _GENERIC_MAPPING
+0x01c ValidAccessMask : Uint4B
+0x020 RetainAccess : Uint4B
+0x024 PoolType : _POOL_TYPE
+0x028 DefaultPagedPoolCharge : Uint4B
+0x02c DefaultNonPagedPoolCharge : Uint4B
+0x030 DumpProcedure : Ptr64 void
+0x038 OpenProcedure : Ptr64 long
+0x040 CloseProcedure : Ptr64 void
+0x048 DeleteProcedure : Ptr64 void
+0x050 ParseProcedure : Ptr64 long
+0x058 SecurityProcedure : Ptr64 long
+0x060 QueryNameProcedure : Ptr64 long
+0x068 OkayToCloseProcedure : Ptr64 unsigned char
其结构和xp有些差别,但需要的几个函数大同小异。
2.2.2 实际中使用的情况
先通过 《遍历Windows内核ObjectType》文章的方法得到EPROCESS对象的_OBJECT_TYPE指针:
5: kd> g
【PrintObjectTypeList】::【DriverEntry】 Hello Kernel World! CurrentProcessId:0x0000000000000004 CurrentIRQL:0x0
【ObRegisterCallback】::【GetObTypeIndexTable】Found ObTypeIndexTable Address:0xFFFFF80006678100
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:00 Address:0xFFFFFA80610603C0 Name:Type
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:01 Address:0xFFFFFA8061060270 Name:Directory
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:02 Address:0xFFFFFA806106C700 Name:SymbolicLink
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:03 Address:0xFFFFFA806106C4B0 Name:Token
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:04 Address:0xFFFFFA806106C290 Name:Job
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:05 Address:0xFFFFFA8061065F30 Name:Process
【PrintObjectTypeList】::【PrintObTypeIndexList】Index:06 Address:0xFFFFFA8061065DE0 Name:Thread
其地址为0xFFFFFA8061065F30,再格式化其结构如下:
5: kd> dt _object_type 0xFFFFFA8061065F30
nt!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY [ 0xfffffa80`61065f30 - 0xfffffa80`61065f30 ]
+0x010 Name : _UNICODE_STRING "Process"
+0x020 DefaultObject : (null)
+0x028 Index : 0x7 ''
+0x02c TotalNumberOfObjects : 0x2f
+0x030 TotalNumberOfHandles : 0x11a
+0x034 HighWaterNumberOfObjects : 0x32
+0x038 HighWaterNumberOfHandles : 0x11e
+0x040 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0b0 TypeLock : _EX_PUSH_LOCK
+0x0b8 Key : 0x636f7250
+0x0c0 CallbackList : _LIST_ENTRY [ 0xfffff8a0`00f59b50 - 0xfffff8a0`00f59b50 ]
再获取_OBJECT_TYPE_INITIALIZER,如下:
5: kd> dx -id 0,0,fffffa8061066b00 -r1 (*((ntkrnlmp!_OBJECT_TYPE_INITIALIZER *)0xfffffa8061065f70))
(*((ntkrnlmp!_OBJECT_TYPE_INITIALIZER *)0xfffffa8061065f70)) [Type: _OBJECT_TYPE_INITIALIZER]
[+0x000] Length : 0x70 [Type: unsigned short]
[+0x002] ObjectTypeFlags : 0x4a [Type: unsigned char]
[+0x002 ( 0: 0)] CaseInsensitive : 0x0 [Type: unsigned char]
[+0x002 ( 1: 1)] UnnamedObjectsOnly : 0x1 [Type: unsigned char]
[+0x002 ( 2: 2)] UseDefaultObject : 0x0 [Type: unsigned char]
[+0x002 ( 3: 3)] SecurityRequired : 0x1 [Type: unsigned char]
[+0x002 ( 4: 4)] MaintainHandleCount : 0x0 [Type: unsigned char]
[+0x002 ( 5: 5)] MaintainTypeList : 0x0 [Type: unsigned char]
[+0x002 ( 6: 6)] SupportsObjectCallbacks : 0x1 [Type: unsigned char]
[+0x002 ( 7: 7)] CacheAligned : 0x0 [Type: unsigned char]
[+0x004] ObjectTypeCode : 0x0 [Type: unsigned long]
[+0x008] InvalidAttributes : 0xb0 [Type: unsigned long]
[+0x00c] GenericMapping [Type: _GENERIC_MAPPING]
[+0x01c] ValidAccessMask : 0x1fffff [Type: unsigned long]
[+0x020] RetainAccess : 0x101000 [Type: unsigned long]
[+0x024] PoolType : NonPagedPool (0) [Type: _POOL_TYPE]
[+0x028] DefaultPagedPoolCharge : 0x1000 [Type: unsigned long]
[+0x02c] DefaultNonPagedPoolCharge : 0x550 [Type: unsigned long]
[+0x030] DumpProcedure : 0x0 : 0x0 [Type: void (__cdecl*)(void *,_OBJECT_DUMP_CONTROL *)]
[+0x038] OpenProcedure : 0xfffff80006765ac8 : ntkrnlmp!PspProcessOpen+0x0 [Type: long (__cdecl*)(_OB_OPEN_REASON,char,_EPROCESS *,void *,unsigned long *,unsigned long)]
[+0x040] CloseProcedure : 0xfffff80006765b10 : ntkrnlmp!PspProcessClose+0x0 [Type: void (__cdecl*)(_EPROCESS *,void *,unsigned __int64,unsigned __int64)]
[+0x048] DeleteProcedure : 0xfffff8000672b814 : ntkrnlmp!PspProcessDelete+0x0 [Type: void (__cdecl*)(void *)]
[+0x050] ParseProcedure : 0x0 : 0x0 [Type: long (__cdecl*)(void *,void *,_ACCESS_STATE *,char,unsigned long,_UNICODE_STRING *,_UNICODE_STRING *,void *,_SECURITY_QUALITY_OF_SERVICE *,void * *)]
[+0x058] SecurityProcedure : 0xfffff80006735dd8 : ntkrnlmp!SeDefaultObjectMethod+0x0 [Type: long (__cdecl*)(void *,_SECURITY_OPERATION_CODE,unsigned long *,void *,unsigned long *,void * *,_POOL_TYPE,_GENERIC_MAPPING *,char)]
[+0x060] QueryNameProcedure : 0x0 : 0x0 [Type: long (__cdecl*)(void *,unsigned char,_OBJECT_NAME_INFORMATION *,unsigned long,unsigned long *,char)]
[+0x068] OkayToCloseProcedure : 0x0 : 0x0 [Type: unsigned char (__cdecl*)(_EPROCESS *,void *,void *,char)]
其中的OpenProcedure、CloseProcedure、DeleteProcedure都有相应的值。
3、相应函数的可能原型
3.1 XP x32位
这些结构参考微软泄露出来的源码和ReactOS获取得到:
3.1.1 DumpProcedure
typedef struct _OBJECT_DUMP_CONTROL {
PVOID Stream;
ULONG Detail;
} OB_DUMP_CONTROL, *POB_DUMP_CONTROL;
typedef VOID (*OB_DUMP_METHOD)(
IN PVOID Object,
IN POB_DUMP_CONTROL Control OPTIONAL
);
3.1.2 OpenProcedure
typedef NTSTATUS (*OB_OPEN_METHOD)(
IN OB_OPEN_REASON OpenReason,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount
);
3.1.3 CloseProcedure
typedef VOID (*OB_CLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG ProcessHandleCount,
IN ULONG SystemHandleCount
);
3.1.4 DeleteProcedure
typedef VOID (*OB_DELETE_METHOD)(
IN PVOID Object
);
3.1.5 ParseProcedure
typedef NTSTATUS (*OB_PARSE_METHOD)(
IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object
);
3.1.6 SecurityProcedure
typedef NTSTATUS (*OB_SECURITY_METHOD)(
IN PVOID Object,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG CapturedLength,
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping
);
3.1.7 QueryNameProcedure
typedef NTSTATUS (*OB_QUERYNAME_METHOD)(
IN PVOID Object,
IN BOOLEAN HasObjectName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength
);
3.1.8 OkayToCloseProcedure
typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN HANDLE Handle,
IN KPROCESSOR_MODE PreviousMode
);
3.2 Win7 x64及以上
参考XP源代码加上2.2.2节最后WinDbg调试显示的结果
3.2.1 DumpProcedure
typedef struct _OBJECT_DUMP_CONTROL {
PVOID Stream;
ULONG Detail;
} OB_DUMP_CONTROL, *POB_DUMP_CONTROL;
typedef VOID (*OB_DUMP_METHOD)(
IN PVOID Object,
IN POB_DUMP_CONTROL Control OPTIONAL
);
3.2.2 OpenProcedure
typedef NTSTATUS (*OB_OPEN_METHOD)(
IN OB_OPEN_REASON OpenReason,
IN CHAR Flag,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN OUT PACCESS_MASK GrantedAccess,
IN ULONG HandleCount
);
3.2.3 CloseProcedure
typedef VOID (*OB_CLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN OUT PACCESS_MASK GrantedAccess,
IN ULONGLONG ReferenceHandleCount
);
3.2.4 DeleteProcedure
typedef VOID (*OB_DELETE_METHOD)(
IN PVOID Object
);
3.2.5 ParseProcedure
typedef NTSTATUS (*OB_PARSE_METHOD)(
IN PVOID ParseObject,
IN POBJECT_TYPE ObjectType,
IN OUT PACCESS_STATE AccessState,
IN CHAR Flag,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object
);
3.2.6 SecurityProcedure
typedef NTSTATUS (*OB_SECURITY_METHOD)(
IN PVOID Object,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG CapturedLength,
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping,
IN CHAR Flag
);
3.2.7 QueryNameProcedure
typedef NTSTATUS (*OB_QUERYNAME_METHOD)(
IN PVOID Object,
IN BOOLEAN HasObjectName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength,
IN CHAR Flag
);
3.2.8 OkayToCloseProcedure
typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN HANDLE Handle,
IN KPROCESSOR_MODE PreviousMode
);