参考
前言
简而言之,Windows内核对象=内核+对象。类似CPP中面向对象编程的概念。
就是一个内核中实例化的结构。c语言的结构体。无非就是跑在内核。
内核对象的组成
类似CPP,类有基类父类。Windows也有oop的思想。oop的核心是多态。
windows用C语言也实现了类似多态的效果。
具体结构就是:
对象头就像是父类,里面有些特殊的位决定了对象体(子类)的不同。
而可变对象头也是根据对象头的信息确定的。用于辅助记录不同对象的不同属性。
比如对象名字等..(比如EPROCESS这个内核对象,他没有名字,也就没有这个可选头)
OBJECT_HEADER
这个结构位于对象体的前面
这就是主要的结构。当前这是x86.不过大差不差。
其中比较重要的便是TypeIndex和InfoMask 以及PointerCount和HandleCount
InfoMask
这个是用于确定可选头的。
如图,InfoMask靠位来确定可选头。这个在WRK中也进行定义了。
以进程对象为例观察可选头
0x80这个掩码就是OBJECT_HEADER_PADDING_INFO
PointerCount和HandleCount
这两个是位于Object_header的前两个8字节。一个是记录了内核对象指针引用的次数,一个 是记录了内核对象句柄引用的次数。
我们可以分析一些内核函数来看看他到底是如何变动的
PointerCount引用增加:
PointerCount引用减少:
可以看出,引用减少会进行一些判断,比如会判断是不是引用次数小于0。小于蓝屏。
或者判断指针引用为0,但是句柄引用不为0,也会蓝屏。
那么HandleCount什么时候减少呢?我们也不知道谁会调用。因此我们可以用调试技巧了。
ba w4 address设置一个访问断点,通过调用栈判断到底谁调用的他。
可以看出,HandleCount的增加是因为用户层的调用(OpenProcess)。
内核对象类型对象
这个词非常拗口,但是他表达的意思其实是我内核对象有一个叫做内核对象类型的对象。
方便管理。在Object_header中
有一个TypeIndex,稍加解密,获得,加上ObTypeIndexTable这个基地址。
指向的就是一个OBJECT_TYPE的内核对象。
OBJECT_TYPE内核对象结构
注意 这里面的Index和Object_Header的是完全不一样的(除了个别的) Object_Header的TypeIndex需要解密
才能够指向Object_Type这个结构
TypeIndex的加密
在ObGetObjectType这个内核函数 可以很清晰地看出来他是如何加密的
这便是TypeIndex和ObTypeIndexTable下标的关系了
内核对象管理
我们知道,windows一切皆对象,linux一切皆文件。
所以Windows如果想管理对象,那毫无疑问,管理内核对象的东西,也是一个内核对象。
这个内核对象是Directory。
可以通过Winobj这个GUI查看
其中\这个Directory内核对象是根目录。包含着所有其他的内核对象。当然其他内核对象也有可能是Directory。
windbg中查看"\"Directory内核对象
使用!object \(这个\是directory的名字)即可查看
可以看出,这些Directory对象的名称在Winobj里面也出现了。这便是Windows内核对象管理的大纲。
但是EPROCESS ETHREAD不会出现在这里面
了解Directory内核对象
这是Directory内核对象的结构,最重要的是这个37大小的OBJECT_DIRECTORY_ENTRY 这里面保存着他存放的内核对象。但是这不代表他就能存37个内核对象 我们来看_OBJECT_DIRECTORY_TABLE
有一个单链表,连接着下一个OBJECT_DIRECTORY_eNYRY对象
Object就是指向Entry管理的对象。