莫灰灰版主说“Object hook 自己定义Process Type和Thread Type才是王道。 ”
今天咱就来这个。
Windows系统的各种资源以对象(Object)的形式来组织,例如File Object, Driver Object,Device Object等等,但实际上这些所谓的“对象”在系统的对象管理器(Object Manager)看来只是完整对象的一个部分——对象实体(Object Body)。各种Object的共有的信息(例如,对象类型、对象的引用计数、句柄数等信息)保存在OBJECT_HEADER与其他的几个结构中。换而言之,在对象管理器内部,不同类型的对象具有相同的Object Header,但Object Body部分却是不同的。
一个对象由三部分组成,在Object Header之前是一段变长的区域,由四个独立的结构体组成:
一个对象可以包含全部四个结构,也可能只包含其中的某个,因此这段区域是变长的。之后是OBJECT_HEADER结构,NameInfoOffset、HandleInfoOffset、QuotaInfoOffset分别为OBJECT_HEADER到OBJECT_HEADER_NAME_INFO、OBJECT_HEADER_HANDLE_INFO、OBJECT_HEADER_QUOTA_INFO这三个结构的偏移。
看一下OBJECT_HEADER结构的信息:
OBJECT_HEADER的大小为0×18字节,因此Object Body = OBJECT_HEADER + 0×18,但是0×18是个硬编码值,如果OBJECT_HEADER在以后的系统中发生了变化,显然用这个0×18是不可靠的。利用OBJECT_TO_OBJECT_HEADER()传递一个Object Body的地址给它,就可以得到这个对象的OBJECT_HEADER结构。
下面看看_OBJECT_TYPE结构。
继续看一下_OBJECT_TYPE_INITIALIZER结构。
今天咱就来这个。
Windows系统的各种资源以对象(Object)的形式来组织,例如File Object, Driver Object,Device Object等等,但实际上这些所谓的“对象”在系统的对象管理器(Object Manager)看来只是完整对象的一个部分——对象实体(Object Body)。各种Object的共有的信息(例如,对象类型、对象的引用计数、句柄数等信息)保存在OBJECT_HEADER与其他的几个结构中。换而言之,在对象管理器内部,不同类型的对象具有相同的Object Header,但Object Body部分却是不同的。
一个对象由三部分组成,在Object Header之前是一段变长的区域,由四个独立的结构体组成:
代码:
typedef struct _OBJECT_HEADER_QUOTA_INFO {
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PEPROCESS ExclusiveProcess;
#ifdef _WIN64
ULONG64 Reserved; // Win64 requires these structures to be 16 byte aligned.
#endif
} OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;
typedef struct _OBJECT_HEADER_HANDLE_INFO {
union {
POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase;
OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
};
} OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
// begin_ntosp
typedef struct _OBJECT_HEADER_NAME_INFO {
POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
#if DBG
ULONG Reserved2;
LONG DbgDereferenceCount;
#ifdef _WIN64
ULONG64 Reserved3; // Win64 requires these structures to be 16 byte aligned.
#endif
#endif
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
// end_ntosp
typedef struct _OBJECT_HEADER_CREATOR_INFO {
LIST_ENTRY TypeList;
HANDLE CreatorUniqueProcess;
USHORT CreatorBackTraceIndex;
USHORT Reserved;
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
看一下OBJECT_HEADER结构的信息:
代码:
kd> dt nt!_object_header 8985d9f0
nt!_OBJECT_HEADER
+0x000 PointerCount : 6
+0x004 HandleCount : 0
+0x004 NextToFree : (null)
+0x008 Type : 0x898df3b0 _OBJECT_TYPE
+0x00c NameInfoOffset : 0x10 ''
+0x00d HandleInfoOffset : 0 ''
+0x00e QuotaInfoOffset : 0 ''
+0x00f Flags : 0x32 '2'
+0x010 ObjectCreateInfo : 0x00000001 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : 0x00000001
+0x014 SecurityDescriptor : 0xe100c843
+0x018 Body : _QUAD
下面看看_OBJECT_TYPE结构。
代码:
lkd> dt 0x8a5f8e70 _OBJECT_TYPE
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY [ 0x8a5f8ea8 - 0x8a5f8ea8 ]
+0x040 Name : _UNICODE_STRING "Process"
+0x048 DefaultObject : (null)
+0x04c Index : 5
+0x050 TotalNumberOfObjects : 0x4b
+0x054 TotalNumberOfHandles : 0xca
+0x058 HighWaterNumberOfObjects : 0x51
+0x05c HighWaterNumberOfHandles : 0xd3
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : 0x636f7250
+0x0b0 ObjectLocks : [4] _ERESOURCE
代码:
lkd> dt _OBJECT_TYPE_INITIALIZER 0x8a5f8e70 +60
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : 0x4c
+0x002 UseDefaultObject : 0 ''
+0x003 CaseInsensitive : 0 ''
+0x004 InvalidAttributes : 0xb0
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : 0x1f0fff
+0x01c SecurityRequired : 0x1 ''
+0x01d MaintainHandleCount : 0 ''
+0x01e MaintainTypeList : 0 ''
+0x020 PoolType : 0 ( NonPagedPool )
+0x024 DefaultPagedPoolCharge : 0x1000
+0x028 DefaultNonPagedPoolCharge : 0x290
+0x02c DumpProcedure : (null)
+0x030 OpenProcedure : (null)
+0x034 CloseProcedure : (null)
+0x038 DeleteProcedure : 0x805d2cdc void nt!PspProcessDelete+0
+0x03c ParseProcedure : (null)
+0x040 SecurityProcedure : 0x805f9150 long nt!SeDefaultObjectMethod+0
+0x044 QueryNameProcedure : (null)
+0x048 OkayToCloseProcedure : (null)
看到OpenProcedure了吧。所以在被hook之前要保存_OBJECT_TYPE结构。
然后替换_OBJECT_TYPE。
留下的就是写代码实现了,请自己动手。除非你不会申请内存,不会拷贝,。。。。。。。
要锻炼动手能力,有问题大家交流。