原文发表于百度空间,2010-08-09
==========================================================================

在Windows系统的对象管理中,为了能够从对象头获取对象类型指针,在Win7以前的系统里直接在OBJECT_HEADER里保存了POBJECT_TYPE指针,而这一点在Win7系统里发生了改变。Win7中把所有的对象类型放在了一个表里,这个表叫做ObTypeIndexTable。这个表可以这么定义:
POBJECT_TYPE ObTypeIndexTable[0x100];
Win7的对象头中不再保存ObjectType指针,而是保存了TypeIndex,也就是对象类型在该表中的索引,并且提供了一个函数ObGetObjectType。需要取得对象类型时直接使用导出函数ObGetObjectType就可以得到对应的对象类型了,反而比以前方便。
该函数非常简单,还原成代码如下:

POBJECT_TYPE
ObGetObjectType(
IN PVOID Object)
{
POBJECT_HEADER ObjectHeader=OBJECT_TO_OBJECT_HEADER(Object);
return ObTypeIndexTable[ObjectHeader->TypeIndex];
}

代码很简单,传入一个对象,取对象头中的TypeIndex作为索引,然后返回ObTypeIndexTable中对应的值。

一个简单的获取所有对象类型指针的方法就是:从ObGetObjectType中取ObTypeIndexTable遍历即可,比较简单~
ObTypeIndexTable这个表是在ObInitSystem中被初始化的,这时的初始化并没有实际填充其内容。ObInitSystem中部分代码如下:

83df4420 6a50             push     50h
83df4422 8d8558feffff lea eax,[ebp-1A8h]
83df4428 push ebx
83df4429 push eax
83df442a c705c478b983b0b0d0ba mov dword ptr [nt!ObTypeIndexTable+0x4 (83b978c4)],0BAD0B0B0h
83df4434 e807fac9ff call nt!memset (83a93e40)

也就是说令ObTypeIndexTable[1]=0xBAD0B0B0,这个常数在Windows中表示一个无效的对象类型指针,从Win2000至Win7都是如此,有效的对象类型则从索引2开始,具体细节可参考这里。(感谢炉子提供信息)

创建对象类型的函数是ObCreateObjectType,不过这家伙啥也不干,直接调用ObCreateObjectTypeEx去了。
创建一个对象类型时具体干了哪些事,完全可以参考Wrk中的ObCreateObjectType,说简单了就是申请一块内存然后根据传入的参数进行填充一下,需要注意的还是这个Index的值。ObCreateObjectTypeEx每创建一个对象类型都要申请一个索引,用来保存创建的对象类型到ObTypeIndexTable表中的相应位置。不论哪个系统,创建的第一个对象类型就是“对象类型”。听起来确实比较别扭,它的名字是ObpTypeObjectType,正如设备对象的类型叫做IoDeviceObjectType一样。不过不同的是,Win7中ObpTypeObjectType对应的Index是2,而在此以前的系统中,该类型对应的Index总是1.
在ObCreateObjectTypeEx中申请该Index时有如下代码:

BYTE newIndex;
NTSTATUS status;
if ( theObjectType == ObpTypeObjectType )
{
newIndex = ;
}
else
{
status = ObpAllocateTypeIndex(&newIndex);
//省略...
}

可以看到,系统对ObpTypeObjectType有特殊处理,当创建该对象类型时,指定了其TypeIndex为2。否则就调用ObpAllocateTypeIndex申请一个有效的索引。
ObpAllocateTypeIndex实际上是从ObTypeIndexTable[2]这个位置(也就是存放ObpTypeObjectType的位置)开始,依次判断内容是否为0,若不为0,则继续判断下一个
若为0,表明这个Index所在的位置尚未被人使用,就返回这个Index就可以了。
在系统启动的过程中,各种类型的对象类型依次创建并被填充到这个表里。系统启动完成后,ObjectType都创建完毕,完整的ObTypeIndexTable如下:

kd> dd ObTypeIndexTable
83b588c0 bad0b0b0 84dafd80 84dafcb8
83b588d0 84dafbf0 84daf9a8 84daf868 84daf7a0
83b588e0 84daf6d8 84daf610 84daf548 84e35ca0
83b588f0 84e53d20 84e4f780 84e57e38 84e572b8
83b58900 84e4f1e0 84e48418 84e48350 84e49418
83b58910 84e49350 84e53868 84e537a0 84e536d8
83b58920 84e4a9b8 84e4a8f0 84e4a828 84e4a760
83b58930 84e4a698 84e50f78 84e50eb0 84e50de8
83b58940 84e50d20 84e50b50 84e507b0 84e521f8
83b58950 84e4ca98 84e26f50 84e2aa80 84e55548
83b58960 84e55480 85aae850 85ab18e0 85b17680
83b58970
83b58980

索引为2处(偏移为8),即为ObpTypeObjectType,细看一下:

kd> dt _OBJECT_TYPE 84dafd80
nt!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY [ 0x84dafd58 - 0x85b17658 ]
+0x008 Name : _UNICODE_STRING "Type"
+0x010 DefaultObject : 0x83b57ba0
+0x014 Index : 0x2 ''
+0x018 TotalNumberOfObjects : 0x2a
+0x01c TotalNumberOfHandles :
+0x020 HighWaterNumberOfObjects : 0x2a
+0x024 HighWaterNumberOfHandles :
+0x028 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x078 TypeLock : _EX_PUSH_LOCK
+0x07c Key : 0x546a624f
+0x080 CallbackList : _LIST_ENTRY [ 0x84dafe00 - 0x84dafe00 ]

可以看到TotalNumberOfObjects为0x2a,即42,这与上面的结果是一致的。

同以前的系统一样在,_OBJECT_TYPE->TotalNumberOfObjects指明了某种类型的对象共有多少个,而ObpTypeObjectType作为对象类型的类型,它的TotalNumberOfObjects实际上便是系统中所有ObjectType的个数。要想获取所有的ObjectType,你可以简单地直接遍历这个表来实现。至于表的地址,可以反汇编导出函数ObGetObjectType来得到,有过从PsLookupProcessByProcessId中取PspCidTable地址经历的人搞这个会很容易。由于ObpTypeObjectType的索引固定为2,所以可以使用_ObTypeIndexTable[2]->TotalNumberOfObjects获取到所有对象类型的个数,然后遍历即可。或者,使用TypeIndex从2开始一直遍历到ObTypeIndexTable[TypeIndex]为零止。

另外,要进行上述观察,注意使用新版的Windbg,我一直使用的6.9版Windbg无法识别Win7下的对象~~
下一篇说说Win7的可变对象头的变化,即InfoMask的作用~~

【旧文章搬运】Win7 OBJECT_HEADER之TypeIndex解析的更多相关文章

  1. Win7 Object_Header之TypeIndex解析

    在暴力搜索内存进程对象反隐藏进程这篇文章中,我们提到: Object Header偏移0×008处Type成员为对象类型值,相同类型的对象具有相同的值.  自Window  7开始, _OBJECT_ ...

  2. 【旧文章搬运】Win7可变对象头结构之InfoMask解析

    原文发表于百度空间,2010-08-11========================================================================== 对Wind ...

  3. 【旧文章搬运】从XP到Win7看Windows对象管理的变化(概述)

    原文发表于百度空间,2010-08-01========================================================================== 今天花了一 ...

  4. 【旧文章搬运】深入分析Win7的对象引用跟踪机制

    原文发表于百度空间及看雪论坛,2010-09-12 看雪论坛地址:https://bbs.pediy.com/thread-120296.htm============================ ...

  5. 【旧文章搬运】PsVoid中IrpCreateFile函数在Win7下蓝屏BUG分析及解决

    原文发表于百度空间,2010-04-05========================================================================== 这也许是我 ...

  6. 【旧文章搬运】Windbg+Vmware驱动调试入门(四)---VirtualKD内核调试加速工具

    原文发表于百度空间,2009-01-09========================================================================== 今天又想起 ...

  7. 【旧文章搬运】分析了一下360安全卫士的HOOK(二)——架构与实现

    原文发表于百度空间及看雪论坛,2009-10-14 看雪论坛地址:https://bbs.pediy.com/thread-99460.htm 刚发这篇文章的时候,因为内容涉及360的核心产品,文章被 ...

  8. 【旧文章搬运】Windbg+Vmware驱动调试入门(二)---Vmware及GuestOS的设置

    原文发表于百度空间,2009-01-08========================================================================== 这一篇是主 ...

  9. 【旧文章搬运】关于windbg搜索符号文件的一点说明

    原文发表于百度空间,2010-09-07========================================================================== 本来只是打 ...

随机推荐

  1. 使用Golang利用ectd实现一个分布式锁

    http://blog.codeg.cn/post/blog/2016-02-24-distrubute-lock-over-etcd/ By zieckey · 2016年02月24日 · 1205 ...

  2. Hadoop 50090端口的页面, Replication的数字是真实的文件备份数吗? (不是)

    红色方框的部分,代表Hadoop系统,人工设定的文件备份数,但不是实际的备份数.文件备份数 不会大于集群机器的总数目(因为备份文件不会同时存在一台机器上,这样就没有意义),所以如果总集群数目是2,即使 ...

  3. Struts2使用POI创建Excel并下载

    本文将讲解在Struts2框架下如何使用POI创建Office Excel文档并实现下载功能. Apache POI ,操作微软文档的Java API,简单来说就是可以用来操作Office文档的API ...

  4. VMware Workstation 11 安装MAC OS X 10.10 Yosemite(14B25)图解 2015-01-13 12:26:01|

    VMware Workstation 11 安装MAC OS X 10.10 Yosemite(14B25)图解 2015-01-13 12:26:01|  分类: 网络互联 |  标签:10.10  ...

  5. C#实现网段扫描

    目录1.使用的类2.获取本地主机IP地址3.远程查询4.实现网段的扫描 ---------------------------------------------------------------- ...

  6. 5分钟快速入门Markdown

    Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. Markdown的语法简洁明了.学习容易,而且功能比纯文本更强,因此有很多人用它写 ...

  7. swift3.0系列完整demo代码库

    https://github.com/soapyigu/Swift30Projects 感谢作者

  8. 《MySQL必知必会学习笔记》:子查询

    子查询 在開始了解子查询之前,首先做下准备工作,建立3个表, 一个是customers表,当中包含:客户名字.客户ID.客户Tel等. 一个是orders表,当中包含:订单号.客户ID.订单时间等. ...

  9. easyui Combotree 怎么加载数据 支持多选

    1.开发环境vs2012 mvc4  c# 2.HTML前端代码 <%@ Page Language="C#" AutoEventWireup="true" ...

  10. 2018-11-13-常用模块1 (time random os sys)

    1.时间模块 time 2.随机数模块 random 3.与操作系统交互模块 os 4.系统模块 sys 在我们真正开始学习之前我们先解决下面几个问题,打好学习模块的小基础,以便更好的学习模块. (1 ...