先来一张图。下面文字参考《 Undocumented Windows 2000 Secrets》
四
1. Dispatcher 对象 此类对象位于系统的最底层,在它们的对象体的开始处都有一个共享
的公共数据结构 ----DISPATCHER_HEADER (参见列表 7-1 )。在它们的对象头中包含一个对象类型 ID 和对象体的长度(保存在 32 位的 DWORD 变量中)。所有 Dispatcher 对象结构体的名字都以字母 K 开始,这表示它们是内核( Kernel )对象。 DISPATCHER_HEADER 结构的存在使得对象是 “ 可等待的( waitable ) ” 。这意味着,此种类型的对象可以被传递给同步函数 KeWaitForSingleObject() 和 KeWaitForMultipleObjects() , Win32 函数 WaitForSingleObject() 和 WaitForMultipleObjects() 就构建于它们之上。
2. I/O 系统数据结构( I/O 对象) 这类对象是最高层的对象,其对象体的开始位置是一个 SHORT 类型的成员,该成员用来标识该对象的 ID 。通常,此 ID 之后还有一个 SHORT 或 WORD 类型的成员用来记录对象体的大小。不过,此类对象并不都遵守这一规则。
3. 其他对象 不属于上述两种对象的对象。
从现在起就要注意 Dispatcher 对象和 I/O 对象的类型 ID ,因为这些 ID 都是单独维护的,所以有些 ID 可能会发生重复。表 7-1 给出了我所知道的 Dispatcher 对象的类型。
表 7-1. Dispatcher 对象汇总 ID |
类 型 |
C 结构 |
定 义 | |
0 |
DISP_TYPE_NOTIFICATION_EVENT |
KEVENT |
ntddk.h | |
1 |
DISP_TYPE_SYNCHRONIZATION_EVENT |
KEVENT |
ntddk.h | |
2 |
DISP_TYPE_MUTANT |
KMUTANT,KMUTEX |
ntddk.h | |
3 |
DISP_TYPE_PROCESS |
KPROCESS |
w2k_def.h | |
4 |
DISP_TYPE_QUEUE |
KQUEUE |
w2k_def.h | |
5 |
DISP_TYPE_SEMAPHORE |
KSEMAPHORE |
ntddk.h | |
6 |
DISP_TYPE_THREAD |
KTHREAD |
w2k_def.h | |
8 |
DISP_TYPE_NOTIFICATION_TIMER |
KTIMER |
ntddk.h | |
9 |
DISP_TYPE_SYNCHRONIZATION_TIMER |
KTIMER |
ntddk.h |
表 7-2. I/O 对象汇总
ID |
类 型 |
C 结构 |
定 义 | |||||||
1 |
IO_TYPE_AD_APTER |
ADAPTER_OBJECT | ||||||||
2 |
IO_TYPE_CONTROLLER |
CONTROLLER_OBJECT |
ntddk.h | |||||||
3 |
IO_TYPE_DEVICE |
DEVICE_OBJECT |
ntddk.h | |||||||
4 |
IO_TYPE_DRIVER |
DRIVER_OBJECT |
ntddk.h | |||||||
5 |
IO_TYPE_FILE |
FILE_OBJECT |
ntddk.h | |||||||
6 |
IO_TYPE_IRP |
IRP |
ntddk.h | |||||||
7 |
IO_TYPE_MASTER_ADAPTER |
| ||||||||
8 |
IO_TYPE_OPEN_PACKET |
| ||||||||
9 |
IO_TYPE_TIMER |
IO_TIMER |
w2k_def.h | |||||||
10 |
IO_TYPE_VPB |
VPB |
ntddk.h | |||||||
11 |
IO_TYPE_ERROR_LOG |
IO_ERROR_LOG_ENTRY |
w2k_def.h | |||||||
12 |
IO_TYPE_ERROR_MESSAGE |
IO_ERROR_LOG_MESSAGE |
ntddk.h | |||||||
13 |
IO_TYPE_DEVICE_OBJECT_EXTENSION |
DEVOBJ_EXTENSION |
ntddk.h | |||||||
18 |
IO_TYPE_APC |
KAPC |
ntddk.h | |||||||
19 |
IO_TYPE_DPC |
KDPC |
ntddk.h | |||||||
20 |
IO_TYPE_DEVICE_QUEUE |
KDEVICE_QUEUE |
ntddk.h | |||||||
21 |
IO_TYPE_EVENT_PAIR |
KEVENT_PAIR |
w2k_def.h | |||||||
22 |
IO_TYPE_INTERRUPT |
KINTERRUPT | ||||||||
23 |
IO_TYPE_PROFILE |
KPROFILE |
如果 OBJECT_CREATOR_INFO 结构存在的话,那么它将总是出现在 OBJECT_HEADER 结构之前。
OBJECT_CREATOR_INFO 结构中的 ObjectList 成员是一个双向链表(参见第二章的列表 2-7 )中的一个节点。该双向链表由类型相同的对象构成。默认情况下,仅有 Port 和 WaitablePort 对象在它们的对象表头中包含 OBJECT_CREATOR_INFO 结构。使用 SystemObjectInformation 标志的 ZwQuerySystemInformation() 函数就是使用 ObjectList 来返回当前已分配对象的完整列表,这些对象将按照对象类型进行分类。在《 Windows NT/2000 Native API Reference 》中, Gray Nebbett 指出 “ [….] 仅在系统启动时,使用 NtGlobalFlags() 设置了 FLG_MAINTAIN_OBJECT_TYPELIST ,该信息标志才有效 ” ( Nebbett 2000, p.25 )
typedef struct _OBJECT_HANDLE_DB
如果 ObjectFlags 的 OB_FLAG_SINGLE_PROCESS 标志被设置,那么 OBJECT_HANDLE_DB 结构中的 Process 成员(位于该结构的一个 union 子结构中)将指向一个进程对象。如果一个以上的进程持有该对象的句柄,那么 OB_FLAG_SINGLE_PROCESS 标志将被清除,此时 HandleDBList 成员(该成员与前面的 Process 成员一起构成了 OBJECT_HANDLE_DB 结构中的一个 union 子结构)将指向一个 OBJECT_HANDLE_DB_LIST 结构,该结构包含一个 OBJECT_HANDLE_DB 结构数组。
=========================
类型对象的对象体由一个 OBJECT_TYPE 结构体和一个内嵌的 OBJECT_TYPE_INITIALIZER 结构组成,列表 7-9 给出了这两个结构体的定义。 ObCreateObject() 在创建对象的过程中,使用 OBJECT_TYPE_INITIALIZER 结构来构建适当的对象头。例如, ObpAllocateObject() (由 ntoskrnl.exe 导出)分别使用 MaintainHandleCount 和 MaintainTypeList 来决定新创建的对象表头中是否需要包含 OBJECT_HANDLE_DB 和 OBJECT_CREATOR_INFO 结构。如果设置了 MaintainTypeList 标志,那么此类型的对象将会构成一个双向链表, OBJECT_TYPE 结构中的 ObjectListHead 成员是该链表的表头和表尾(这意味着该双向链表是一个环形结构)。 OBJECT_TYPE_INITIALIZER 结构中的 DefaultPagedPoolCharge 和 DefaultNonPagedPoolCharge 成员提供了默认的限额和开销大小(在前面讨论 OBJECT_QUOTA_CHARGES 结构时曾讨论过限额问题)。
表 7-4. 有效的对象类型 (后面还有很多,不帖了
索引 |
标志 |
名称 |
C 结构 |
是否公开 |
符号 | |||||
1 |
“ ObjT ” |
“ Type ” |
OBJECT_TYPE |
No |
ObpTypeObjectType | |||||
2 |
“ Dire ” |
“ Directory ” |
OBJECT_DIRECTORY |
No |
ObpDirectoryObjectType | |||||
3 |
“ Symb ” |
“ SymbolicLink ” |
|
No |
ObpSymbolicLinkObjectType | |||||
4 |
“ Toke ” |
“ Token ” |
TOKEN |
No |
SepTokenObjectType | |||||
5 |
“ Proc ” |
“ Process ” |
EPROCESS |
Yes |
PsProcessType | |||||
6 |
“ Thre ” |
“ Thread ” |
ETHREAD |
Yes |
PsThreadType | |||||
7 |
“ Job ” |
“ Job ” |
Yes |
PsJobType | ||||||
8 |
“ Even ” |
“ Event ” |
KEVENT |
Yes |
ExEventObjectType | |||||
9 |
“ Even ” |
“ EventPair ” |
KEVENT_PAIR |
No |
ExEventPairObjectType |