-
-
[原创]Win7可变对象头结构之InfoMask解析
-
发表于:
2010-8-11 02:04
11820
-
[原创]Win7可变对象头结构之InfoMask解析
对Windows对象管理有一定了解的人都知道,在固定对象头(OBJECT_HEADER)前面是一块可变区域,称为可变对象头,它所包含的结构内容并不固定。在Win7之前,可变区域实际有哪些结构,通常是由OBJECT_HEADER中的几个偏移值指出。如下:
lkd> dt _OBJECT_HEADER(WinXP SP2)
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
其中的NameInfoOffset、HandleInfoOffset、QuotaInfoOffset就是用于指出该结构相对于固定对象头(OBJECT_HEADER)的偏移。如果NtGlobalFlags设置了MaintainTypeList标志,那么由于CreatorInfo的存在,这个部分还会更复杂一点,还得依据OBJECT_HEADER->Flag中的标志位来作一些判断才能具体确定某个结构的具体偏移。在Win7中,这一部分显然经过了精心设计,一个InfoMask域再加一个ObpInfoMaskToOffset表就搞定了,显得更加简捷快速。
顾名思义,InfoMask就是一个掩码,它的每一位表示可变对象头中某个指定的结构是否存在。在Win7中,对象的结构大体上没有太大变化,固定对象头的前面仍然是可变对象头。根据不同类型的对象及实际情况,可变对象头可能包含以下5个结构中的一个或几个:
(Size=0x08)ntkrpamp!_OBJECT_HEADER_PROCESS_INFO
(Size=0x10)ntkrpamp!_OBJECT_HEADER_QUOTA_INFO
(Size=0x08)ntkrpamp!_OBJECT_HEADER_HANDLE_INFO
(Size=0x10)ntkrpamp!_OBJECT_HEADER_NAME_INFO
(Size=0x10)ntkrpamp!_OBJECT_HEADER_CREATOR_INFO
这些结构对应的掩码分别为:
#define OB_INFOMASK_PROCESS_INFO 0x10
#define OB_INFOMASK_QUOTA 0x08
#define OB_INFOMASK_HANDLE 0x04
#define OB_INFOMASK_NAME 0x02
#define OB_INFOMASK_CREATOR_INFO 0x01
因为可变对象头可能包含5种结构,每一种结构包括存在或不存在两种情况,那么一共是2^5=32种结果。所以,ObpInfoMaskToOffset表定义如下:
BYTE ObpInfoMaskToOffset[32];
ULONG i = 0;
ULONG offset = 0;
do
{
offset = 0;
if ( i & OB_INFOMASK_CREATOR_INFO )
offset = sizeof(_OBJECT_HEADER_CREATOR_INFO);
if ( i & OB_INFOMASK_NAME )
offset += sizeof(_OBJECT_HEADER_NAME_INFO);
if ( i & OB_INFOMASK_HANDLE )
offset += sizeof(_OBJECT_HEADER_HANDLE_INFO);
if ( i & OB_INFOMASK_QUOTA )
offset += sizeof(_OBJECT_HEADER_QUOTA_INFO);
if ( i & OB_INFOMASK_PROCESS_INFO )
offset += sizeof(_OBJECT_HEADER_PROCESS_INFO);
ObpInfoMaskToOffset[i++] = offset;
}while(i<32);
kd> db ObpInfoMaskToOffset
83b97e60 00 10 10 20 08 18 18 28-10 20 20 30 18 28 28 38 ... ...(. 0.((8
83b97e70 08 18 18 28 10 20 20 30-18 28 28 38 20 30 30 40 ...(. 0.((8 00@
kd> dt _OBJECT_TYPE 84e4aa38 //查看对象类型
nt!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY [ [color=#FF0000]0x8603a548 [/color]- 0x863593e8 ] //为了便观察到同类型的所有对象,我设置了MaintainTypeList标志
+0x008 Name : _UNICODE_STRING "WindowStation"
+0x010 DefaultObject : (null)
+0x014 Index : 0x14 ''
+0x018 TotalNumberOfObjects : 6
+0x01c TotalNumberOfHandles : 0x35
+0x020 HighWaterNumberOfObjects : 6
+0x024 HighWaterNumberOfHandles : 0x3f
+0x028 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x078 TypeLock : _EX_PUSH_LOCK
+0x07c Key : 0x646e6957
+0x080 CallbackList : _LIST_ENTRY [ 0x84e4aab8 - 0x84e4aab8 ]
kd> !pool 0x8603a548 //观察第一个对象的内存池分配
Pool page 8603a548 region is Nonpaged pool
8603a500 size: 18 previous size: 48 (Allocated) MmSi
*[color=#FF0000]8603a518 [/color]size: b0 previous size: 18 (Allocated) *Wind (Protected)
Owning component : Unknown (update pooltag.txt)
8603a5c8 size: 78 previous size: b0 (Allocated) EtwR (Protected)
...
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!