对象管理器使用对象头中保存的数据来管理这些对象,而无需关注它们的类型,标准对象头中的属性
1.对象名称:使一个对象对于其他的进程也是可见的,便于共享
2.对象目录:提供了一个层次结构来存储对象名称
3.安全描述符:决定了谁可以使用该对象,以及允许它们如何使用它
4.配额花费:列出当一个进程打开一个指向该对象的句柄时,针对该进程收取的资源花费额
5.已打开的句柄计数:记录了“打开一个句柄来指向该对象”的次数
6.对象类型:指向一个类型对象,该对象包含了针对这种类型的对象都是公共的属性
7.引用计数:记录了一个内核模式组件引用该对象地址的次数
除了对象头以外,每个对象也有一个对象体,并且其格式和内容只有这种对象类型才有。
一个执行体组件通过创建一个对象类型,并且为它提供一些服务,就可以控制和维护所有这些类型的对象体中的数据。
对象管理器提供了少量的通用服务来操作对象头中保存的属性,并且可以用在任何类型对象上,windows子系统允许其中一些服务可以直接被windows应用程序使用。这些通用操作有
1.关闭:关闭一个指向某个对象的句柄
2.复制:通过先复制一个句柄,再将其交给另一个进程的方法来共享一个对象
3.查询对象:获得关于一个对象的标准属性信息
4.查询安全性:获取一个对象的安全描述符
5.设置安全性:改变一个对象上的保护设置
6.等待一个对象:用一个对象来同步一个线程的执行
7.等待多个对象:用多个对象来同步一个线程的执行
每个对象都有自己的创建、打开、查询服务(创建一个进程和创建一个文件需要初始化的数据是不同的)
winobj的ObjectTypes中可以看到对象管理器中声明的类型对象的列表
实验:查看对象头和类型对象
1.使用!process 0 0显示系统进程,例如我们选择其中显示的一项
*** NT ACTIVE PROCESS DUMP ****
PROCESS 821b9830 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 00b18000 ObjectTable: e1000c98 HandleCount: 257.
Image: System
其中PROCESS就是进程内核对象的地址,System进程的进程内核对象地址为821b9830
2.使用!objcet命令显示进程内核系统对象的信息
lkd> !object 821b9830
Object: 821b9830 Type: (821b9e70) Process
ObjectHeader: 821b9818 (old version)
HandleCount: 2 PointerCount: 66
3.使用dt命令查看对象头和类型对象
lkd> dt _object_header 821b9818
nt!_OBJECT_HEADER
+0x000 PointerCount : 0n66
+0x004 HandleCount : 0n2
+0x004 NextToFree : 0x00000002 Void
+0x008 Type : 0x821b9e70 _OBJECT_TYPE
+0x00c NameInfoOffset : 0 ‘‘
+0x00d HandleInfoOffset : 0 ‘‘
+0x00e QuotaInfoOffset : 0 ‘‘
+0x00f Flags : 0x22 ‘"‘
+0x010 ObjectCreateInfo : 0x8055b200 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : 0x8055b200 Void
+0x014 SecurityDescriptor : 0xe10003b3 Void
+0x018 Body : _QUAD
对象头的起始地址+0x18个字节就是对象体的起始地址(0x821b9818+0x18=0x821b9830)
lkd> dt _object_type 821b9e70
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY [ 0x821b9ea8 - 0x821b9ea8 ]
+0x040 Name : _UNICODE_STRING "Process"
+0x048 DefaultObject : (null)
+0x04c Index : 5
+0x050 TotalNumberOfObjects : 0x1a
+0x054 TotalNumberOfHandles : 0x6d
+0x058 HighWaterNumberOfObjects : 0x1b
+0x05c HighWaterNumberOfHandles : 0x74
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : 0x636f7250
+0x0b0 ObjectLocks : [4] _ERESOURCE
上面的输出显示出:对象类型结构体包含了对象类型的名称(Name成员),记录了这种类型活动对象的总数,以及这种类型的句柄和对象的尖峰数目。TypeInfo成员保存了一个指针,该指针指向的数据结构保存了对于该对象类型的所有对象都公共的属性,以及一组指向该对象类型的方法的指针
lkd> dt _object_type_initializer 821b9e70+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 : 0x805c8f00 void nt!PspProcessDelete+0
+0x03c ParseProcedure : (null)
+0x040 SecurityProcedure : 0x805ef42e long nt!SeDefaultObjectMethod+0
+0x044 QueryNameProcedure : (null)
+0x048 OkayToCloseProcedure : (null)