Windows对象(Object)结构--关于Win7的补充
自Window 7开始,_OBJECT_HEADER及其之前的一些结构发生了变化。首先来对比下Win7与XP的_OBJECT_HEADER:
[Windows 7]
0: kd> dt _object_header
nt!_OBJECT_HEADER
+0x000 PointerCount : Int4B
+0x004 HandleCount : Int4B
+0x004 NextToFree : Ptr32 Void
+0x008 Lock : _EX_PUSH_LOCK
+0x00c TypeIndex : UChar
+0x00d TraceFlags : UChar
+0x00e InfoMask : UChar
+0x00f Flags : UChar
+0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : Ptr32 Void
+0x014 SecurityDescriptor : Ptr32 Void
+0x018 Body : _QUAD
[Windows XP sp3]
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
可以看到,+0x008处的指向_OBJECT_TYPE的指针已经没有了,取而代之的是在+0x00c处的类型索引值。
“Vista及其以下版本都是在_object_header结构中保存object_type指针,在Windows7中Object_header只保存Object_type的索引。但Windows7中添加了一个函数,ObGetObjectType,返回Object_type对象指针,所以操作Object_type不需要硬编码了。
NTKERNELAPI
PVOID
NTAPI
ObGetObjectType(
IN PVOID pObject
);
”(见看雪论坛langouster对某贴的
回复
)
来看看这个函数:
0: kd> u ObGetObjectType
nt!ObGetObjectType:
83e4f3f6 8bff mov edi,edi
83e4f3f8 55 push ebp
83e4f3f9 8bec mov ebp,esp
83e4f3fb 8b4508 mov eax,dword ptr [ebp+8]
83e4f3fe 0fb640f4 movzx eax,byte ptr [eax-0Ch]
83e4f402 8b0485c0b8d483 mov eax,dword ptr nt!ObTypeIndexTable (83d4b8c0)[eax*4]
83e4f409 5d pop ebp
83e4f40a c20400 ret 4
实际上就是一个全局数组nt!ObTypeIndexTable保存了所有的对象类型的指针。
另一个重要的变化:
Win7的_OBJECT_HEADER不再有NameInfoOffset、HandleInfoOffset和QuotaInfoOffset来指示从_POOL_HEADER到_OBJECT_HEADER这一段神秘的可变长空间。占据这三个偏移位置的三个成员分别为:TypeIndex、TraceFlags和InfoMask。TypeIndex上文已经说明,TraceFlags目前作用未知,以后搞明白了再补充吧。下面研究InfoMask的作用。为了方便起见,选取了Win7的explorer的进程对象和文件对象作为参考。
0: kd> dt _eprocess 860fed10
nt!_EPROCESS
...
+0x16c ImageFileName : [15] "explorer.exe"
...
0: kd> dt _file_object 86952ec8
nt!_FILE_OBJECT
...
+0x030 FileName : _UNICODE_STRING "Windowsexplorer.exe"
...
通过观察内存,找到了他们的_POOL_HEADER(
_POOL_HEADER/
_OBJECT_HEADER)
0: kd> dd 860fed10-30
860fece0
045e000a e36f7250 00001000 000002f0
860fecf0 00000078 86b2d200
00000195 00000006
860fed00
00000000 00080007 86b2d200 89588b65
860fed10 00260003 00000000 860fed18 860fed18
860fed20 860fed20 860fed20 1ecf9360 00000000
860fed30 00000000 00000000 00000000 86d91210
860fed40 85aa6340 00000000 00010001 00000000
860fed50 00000003 860fed54 860fed54 00000000
0: kd> dd 86952ec8-38
86952e90
0417001f e56c6946 00000400 000000f8
86952ea0 00000000 00000000 92f6f8a0 00000001
86952eb0
00000007 00000000 00000000 000c001c
86952ec0
00000001 00000000 00800005 86186030
86952ed0 86186c50 92f909f8 92f6d490 86953fa8
86952ee0 00000000 00000000 00000000 00010000
86952ef0 01000100 00044042 0038002a 92f76b48
86952f00 00000000 00000000 00000000 00000000
可变长区域内的结构都以_OBJECT_HEADER_开头,所以我们可以先看看Win7下使用了哪些结构:
0: kd> dt nt!_object_header*
ntkrpamp!_OBJECT_HEADER
ntkrpamp!_OBJECT_HEADER_QUOTA_INFO
ntkrpamp!_OBJECT_HEADER_PROCESS_INFO
ntkrpamp!_OBJECT_HEADER_HANDLE_INFO
ntkrpamp!_OBJECT_HEADER_NAME_INFO
ntkrpamp!_OBJECT_HEADER_CREATOR_INFO
0: kd> dt _OBJECT_HEADER_QUOTA_INFO
nt!_OBJECT_HEADER_QUOTA_INFO
+0x000 PagedPoolCharge : Uint4B
+0x004 NonPagedPoolCharge : Uint4B
+0x008 SecurityDescriptorCharge : Uint4B
+0x00c SecurityDescriptorQuotaBlock : Ptr32 Void
0: kd> dt _OBJECT_HEADER_PROCESS_INFO
nt!_OBJECT_HEADER_PROCESS_INFO
+0x000 ExclusiveProcess : Ptr32 _EPROCESS
+0x004 Reserved : Uint4B
0: kd> dt _OBJECT_HEADER_HANDLE_INFO -b
nt!_OBJECT_HEADER_HANDLE_INFO
+0x000 HandleCountDataBase : Ptr32
+0x000 SingleEntry : _OBJECT_HANDLE_COUNT_ENTRY
+0x000 Process : Ptr32
+0x004 HandleCount : Pos 0, 24 Bits
+0x004 LockCount : Pos 24, 8 Bits
0: kd> dt _OBJECT_HEADER_NAME_INFO
nt!_OBJECT_HEADER_NAME_INFO
+0x000 Directory : Ptr32 _OBJECT_DIRECTORY
+0x004 Name : _UNICODE_STRING
+0x00c ReferenceCount : Int4B
0: kd> dt _OBJECT_HEADER_CREATOR_INFO
nt!_OBJECT_HEADER_CREATOR_INFO
+0x000 TypeList : _LIST_ENTRY
+0x008 CreatorUniqueProcess : Ptr32 Void
+0x00c CreatorBackTraceIndex : Uint2B
+0x00e Reserved : Uint2B
观察对比后的,感觉应该是这样的:
0: kd> dd 860fed10-30
860fece0
045e000a e36f7250
00001000 000002f0
860fecf0
00000078 86b2d200
00000195 00000006
860fed00
00000000 00080007 86b2d200 89588b65
860fed10 00260003 00000000 860fed18 860fed18
860fed20 860fed20 860fed20 1ecf9360 00000000
860fed30 00000000 00000000 00000000 86d91210
860fed40 85aa6340 00000000 00010001 00000000
860fed50 00000003 860fed54 860fed54 00000000
0: kd> dd 86952ec8-38
86952e90
0417001f e56c6946
00000400 000000f8
86952ea0
00000000 00000000
92f6f8a0 00000001
86952eb0
00000007 00000000 00000000 000c001c
86952ec0
00000001 00000000 00800005 86186030
86952ed0 86186c50 92f909f8 92f6d490 86953fa8
86952ee0 00000000 00000000 00000000 00010000
86952ef0 01000100 00044042 0038002a 92f76b48
86952f00 00000000 00000000 00000000 00000000
结构算是都硬套上了。现在来猜测一下InfoMask与这些结构的对应关系。
860fed10(_EPROCESS)的InfoMask为:0x8 = 1000b
86952ec8(_FILE_OBJECT)的InfoMask为:0xc = 1100b
那么我们可以:
#define OB_INFOMASK_QUOTA 0x8
#define OB_INFOMASK_HANDLE 0x4
同样方法,分析其他类型的内核对象得到:
#define OB_INFOMASK_NAME 0x2
#define OB_INFOMASK_PROCESS 0x1
_OBJECT_HEADER_CREATOR_INFO结构仍然由+0x00f Flags指示,故没有对应掩码。
本文详细探讨了从Windows XP到Windows 7中_OBJECT_HEADER结构的变化,重点关注Win7的更新,包括与XP的对比和差异。
2879

被折叠的 条评论
为什么被折叠?



