【Windows内核原理与实现】读书笔记(三)

来源:互联网 发布:java字符串单个字符 编辑:程序博客网 时间:2024/05/16 17:07

Windows内核中对象管理

Windows对象管理器的基本设计意图是:

  • 为执行体的数据结构提供一种统一又可扩展的定义和控制机制。
  • 提供统一的安全访问机制。
  • 在无需修改已有系统代码的情况下,加入新的对象类型。
  • 提供一组标准的API来对对象执行各种操作。
  • 提供一种命名机制,与文件系统的命名机制集成在一起。

每一个对象都由两部分构成:对象头和对象体,所有对象的对象头都具有统一的格式,对象头包含了对象管理所需要的基本信息,包括对象名称、类型、引用计数以及安全描述符等。在Windows中,每一种对象都需要一个对应类型的类型对象(即OBJECT_TYPE对象)。系统定义的对象种类是有限的,WRK支持31种对象(内置),各有一个全局的POBJECT。TYPE变量指向其类型对象。

WRK限定不超过48个类型对象,系统全局变量ObpObjectTypes数组记录了所有已创建的类型对象。

对象的构造是由两部分来完成的:(1)调用ObCreateObject,根据指定的类型对象来完成对象头的初始化,并且按照指定的大小来分配对象体的内存;(2)完成对象体的初始化。前者可以统一完成,而后者不可以,因为各种类型的对象有自己不同的初始化逻辑。

类型对象可以跟踪记录当前所有此种类型的对象。因为所有的对象都是在ObpAllocateObject和ObpFreeobject中分配和释放的。

对象管理器的两个接口函数ObOpenObjectByName和ObReferenceObjectByName,正是通过ObpLookupObjectName来完成其打开对象或引用对象的功能的,另一个接口函数ObInsertObject,它的作用是把一个对象插入到一个进程的句柄表中,它也通过ObpLookupObjectName来验证待插入的对象是否在全局名字空间中并不存在。

ObpLookupObjectName的基本执行逻辑:

  • 参数检查
  • 如果调用者指定了RootDirectoryHandle参数,则利用此RootDirectory的Parse方法来解析对象,直到解析成功或者不成功,或者指示从头解析。
  • 如果调用者没有指定RootDirectoryHandle参数,则系统从全局的根目录ObpRootDirectoryObject开始解析。这种情况下,传递进来的对象名称必须以"\"开始。如果待查找的名称仅仅是"\",则执行特殊处理。否则,执行下面的逻辑:(1)首先判断名称是否以"\??\"开头,是的话,需要拿到当前进程的DeviceMap(设备表),以进一步查询。(2)如果名称正好是"\??",则直接返回当前进程的DeviceMap作为结果。(3)调用ObpLookupDirectoryEntry函数,层层递进,或者碰到具有Parse方法的对象,由它来解析余下的名称字符串,或者碰到子目录对象,从而可以在子目录对象中进一步查询下一级名称。

进程如果需要使用对象,必须通过句柄来完成。在内核中,将一个句柄转换成对应的对象,可以通过ObReferenceObjectByHandle函数来完成。

对象的声明周期由对象的引用计数来管理,一旦引用计数为零,则对象的声明周期结束,它所占用的内存也可以被回收。对象的引用计数来源于两个方面:(1)内核中指针引用;(2)进程打开一个对象并获得一个句柄,它以后通过此句柄来引用此对象。

原创粉丝点击