Handles Object Manager Initialization and Shutdown
阶段 0 初始化:
1.初始化obci和obnm,创建信息和对象名称链表
2.创建安全描述符缓存
3.初始化默认对象事件和设备映射锁
4.在EPROCESS AND ETHREAD set GrantedAccess 为高等访问权限
5.创建句柄表,并设置到EPROCESS 的ObjectTable上。
6.创建 Type Diretory SymbolicLink 三种对象类型
阶段1初始化:
1.初始化对象目录,L”\”,L”\KernelObjects”, L”\ObjectTypes”
2.检索ObpTypeObjectType->TypeList,将类型对象加入到 L”\ObjectTypes”中
3.创建DosDeviceDirectory L”\GLOBAL??”
4.创建关于dos device directory 的符号连接
对象的具体管理
创建对象 ObCreateObject
我们先看对象头部,这个是对象管理器来管理的,它自己创建对象头部的相关信息。
typedef struct _OBJECT_HEADER
{
LONG PointerCount;
union
{
LONG HandleCount;
volatile PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;
一般情况下创建对象就是根据不同的要求设置对象头,对应的申请空间也是不同大小的,要在ObpAllocateObject中计算对象头的大小,然后申请内存供上层函数完成对象的创建。跟着对象头一起创建的还有quotainfo,handleinfo,nameinfo,creatorinfo.然后将这些信息的偏移地址分别设置到header上,然后初始化header数据结构中的其他变量。设置PointCount 和HandleCount,并设置对象类型,以分辨出是何种对象等等。
以创建timer为例,当上层调用对象管理器的api来创建对象时,使用如下参数创建
/* Create the Object */
Status = ObCreateObject(PreviousMode,
ExTimerType,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(ETIMER),
0,
0,
(PVOID*)&Timer);
我们可以在ObCreateObject获知创建模式,创建属性和创建的对象大小。计算出FinaSize的值(即header中额外的管理信息)和objectSize 是个sizeof(ETIMER)。再根据该对象自己的属性,来决定是创建在换页或是非换页的内存上。
Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
然后如上申请了某个对象内存空间,获得该对象的一个指针,此时系统中存在了一个内核对象的数据实例,当创建成功后,ObCreateObject最后一个参数获得的是一个header->Body,此时我们知道,对于对象的其他数据是通过对象管理器来管理的,而且提供对外接口,当外部引用这个数据的时候,我们会增加引用计数和句柄计数,修改对象头内部数据。
插入对象ObInsertObject
当我们创建成功后,我们修改自己的对象内容,比如:
Timer->ApcAssociated = FALSE;
Timer->WakeTimer = FALSE;
Timer->WakeTimerListEntry.Flink = NULL;
设置完对象数据后,我们调用插入对象,这里一般是获得对象操作的句柄,还是以timer为例
/* Insert the Timer */
Status = ObInsertObject((PVOID)Timer,
NULL,