• Win7 Object_Header之TypeIndex解析


    暴力搜索内存进程对象反隐藏进程这篇文章中,我们提到:

    Object Header偏移0×008处Type成员为对象类型值,相同类型的对象具有相同的值.  自Window  7开始, _OBJECT_HEADER及其之前的一些结构发生了变化. 

    lkd> dt _object_header

    nt!_OBJECT_HEADER

    +0×000 PointerCount      : Int4B

    +0×004 HandleCount       :Int4B

    +0×004 NextToFree        : Ptr32 Void

    +0×008 Lock             : _EX_PUSH_LOCK

    +0x00c TypeIndex          : UChar

    ……

    可以看到, 0×008处的指向_OBJECT_TYPE的指针已经没有了,  取而代之的是在0x00c 处的类型索引值. 但Windows7中添加了一个函数ObGetObjectType, 返回Object_type对象指针. 

    看过黑月教主文章也大概知道是怎么回事了,这里我再来扯一扯。。。

    首先我们来对ObGetObjectType进行反汇编:

    image

    把参数object的地址赋给eax。

    82a8f3fb 8b4508          mov     eax,dword ptr [ebp+8]

    获取TypeIndex的值,解释一下为什么是减去0Ch。正常的计算应该是:

    object地址-Object_header的大小+TypeIndex的偏移,所以有:

    eax-0x18h+0x0Ch 即为 eax – 0x0Ch

    82a8f3fe 0fb640f4        movzx   eax,byte ptr [eax-0Ch]

    根据索引值在ObTypeIndexTable数组中找到对应的ObjectType。

    82a8f402 8b0485c0b89882  mov     eax,dword ptr nt!ObTypeIndexTable (8298b8c0)[eax*4]

    验证下ObTypeIndexTable 是不是一个数组。

    image

    我们随便找个进程,然后查看它的TypeIndex,发现是0x7h,那来看看索引为7的ObjectType对象是不是进程的ObjectType。

    image

    事实证明确实是的。

    在ObInitSystem函数中,可以找到创建对象类型的函数:

    image

    不论哪个系统,创建的第一个对象类型就是“对象类型”。听起来确实比较别扭,它的名字是ObpTypeObjectType,正如设备对象的类型叫做IoDeviceObjectType一样。不过不同的是,Win7中ObpTypeObjectType对应的Index是2,而在此以前的系统中,该类型对应的Index总是1.

    在ObCreateObjectTypeEx中申请该Index时有如下代码:
    BYTE newIndex;
    NTSTATUS status;
    if ( theObjectType ==   ObpTypeObjectType )
    {
         newIndex = 2;
    }
    else
    {
         status = ObpAllocateTypeIndex(&newIndex);
        //省略…
    }
    可以看到,系统对ObpTypeObjectType有特殊处理,当创建该对象类型时,指定了其TypeIndex为2。否则就调用ObpAllocateTypeIndex申请一个有效的索引。
    ObpAllocateTypeIndex实际上是从ObTypeIndexTable[2]这个位置(也就是存放ObpTypeObjectType的位置)开始,依次判断内容是否为0,若不为0,则继续判断下一个。若为0,表明这个Index所在的位置尚未被人使用,就返回这个Index就可以了。(引用自黑月教主)

    反汇编也可以看到。

    image

    在ObTypeIndexTable 中来查看,地址为84133c98 。

    image

    可以看到TotalNumberOfObjects为0x2a,即42,和dd ObTypeIndexTable 看到的结果是一样的。

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

    本文链接:http://www.blogfshare.com/win7-obtypeindextable.html

     jpg 改 rar

  • 相关阅读:
    关于dva前后端分离的跨域问题
    十大经典排序算法
    Java并发编程核心概念一览
    StringBuilder线程为什么不安全
    Java序列化的10个问题
    10 个最难回答的 Java 问题
    lombok @EqualsAndHashCode 注解讲解
    内存泄漏和内存溢出的区别和联系
    RabbitMQ
    RabbitMQ原理图
  • 原文地址:https://www.cnblogs.com/kuangke/p/5818839.html
Copyright © 2020-2023  润新知