对象查看器的核心代码(无意中找到的)

记得以前我的一位大哥做出了山寨版Winobj,当时不知怎么实现的,以为是有什么接口函数,现在终于知道是怎么做的了.

其实跟SSDT的原理差不多,也是有一个全局变量,通过它沿着复杂的路径找到一张树状结构.

 

    kd> !object /
    Object: 8148e210  Type: (814c5820) Directory
        ObjectHeader: 8148e1f8
        HandleCount: 0  PointerCount: 39
        Directory Object: 00000000  Name: /
        99 symbolic links snapped through this directory
        HashBucket[ 00 ]: 8148a350 Directory 'ArcName'
                          814a8f10 Device 'Ntfs'
        HashBucket[ 01 ]: e2390040 Port 'SeLsaCommandPort'
        HashBucket[ 03 ]: e1012030 Key '/REGISTRY'
        HashBucket[ 06 ]: e1394560 Port 'XactSrvLpcPort'
        HashBucket[ 07 ]: e13682e0 Port 'DbgUiApiPort'
        HashBucket[ 09 ]: 84305760 Directory 'NLS'
                        .
                        .
                        .

    kd> !object 814a8f10
    Object: 814a8f10  Type: (814b5ac0) Device
        ObjectHeader: 814a8ef8
        HandleCount: 0  PointerCount: 2
        Directory Object: 8148e210  Name: Ntfs

    实现代码如下:

    //-----------------------------------------------
    //
    // Dump Windows 2000 Kernel Object
    // Only test on Windows 2000 Server Chinese Edition
    // Build 2195(Free)!Programmed By WebCrazy
    // (tsu00@263.net ) on 11-04-2000!
    // Welcome to http://webcrazy.yeah.net !
    //
    //-----------------------------------------------

    ULONG ObpRootDirectoryObject=0x8148e210;  //fetch from symbol file

    void DumpDirectoryObject(PVOID DirectoryObject)
    {
       ULONG HashBucket;
       ULONG *Hash;

       for(HashBucket=0;HashBucket<=0x24;HashBucket++)
       {
          Hash=(ULONG *)((ULONG)DirectoryObject+HashBucket*4);
          if(*Hash==0) continue;

          DbgPrint("/n    HashBucket[%02X]/n",HashBucket);
          do
          {
              PUNICODE_STRING ObName,ObTypeName;
              PVOID Object,ObPreHeader,ObStandardHeader;

              Hash=(ULONG *)(*Hash);
              Object=(PVOID)(*(ULONG *)((ULONG)Hash+4));
              ObPreHeader=(PVOID)((ULONG)Object-0x28);
              ObStandardHeader=(PVOID)((ULONG)Object-0x18);

              ObName=(PUNICODE_STRING)((ULONG)ObPreHeader+4);
              DbgPrint("/tDump Object:%08X/n",(ULONG)Object);
              DbgPrint("/t  Name:%S",ObName->Buffer);

              ObTypeName=(PUNICODE_STRING)((ULONG)(*(ULONG *)((ULONG)ObStandardHeader+8))+0x40);
              DbgPrint("/t  Type:%S(%08X)/n",ObTypeName->Buffer,
                            *(ULONG *)((ULONG)ObStandardHeader+8));

              DbgPrint("/t  PointerCount:%d  HandleCount:%d/n",*(ULONG *)ObStandardHeader,
                            *(ULONG *)((ULONG)ObStandardHeader+4));

          }while(*Hash!=0);
       }
    }

    void DumpObject(PVOID Object)
    {

       PUNICODE_STRING ObName,ObTypeName;
       UNICODE_STRING temp;
       PVOID ObPreHeader=(PVOID)((ULONG)Object-0x28),
            ObStandardHeader=(PVOID)((ULONG)Object-0x18);

       if(((USHORT)NtBuildNumber)!=2195){
           DbgPrint("Only test on Windows 2000 Server Build 2195!/n");
           return;
       }

       ObName=(PUNICODE_STRING)((ULONG)ObPreHeader+4);
       DbgPrint("  Dump Object:%08X/n    Name:%S",(ULONG)Object,ObName->Buffer);

       ObTypeName=(PUNICODE_STRING)((ULONG)(*(ULONG *)((ULONG)ObStandardHeader+8))+0x40);
       DbgPrint("    Type:%S(%08X)/n",ObTypeName->Buffer,*(ULONG *)((ULONG)ObStandardHeader+8));

       DbgPrint("    PointerCount:%d  HandleCount:%d/n",*(ULONG *)ObStandardHeader,
                     *(ULONG *)((ULONG)ObStandardHeader+4));

       RtlInitUnicodeString(&temp,L"Directory");
       if(!RtlCompareUnicodeString(&temp,ObTypeName,FALSE))
          DumpDirectoryObject(Object);
    }

    void DumpRootDirectoryObject()
    {
       DumpObject((PVOID)ObpRootDirectoryObject);
    }

 

这样就能将Winobj.exe中的对象名和类型全部显示出来了.

代码没有调试过,但是在Windbg中验证过.若是将/Ntfs输入找到的对象名真的是L"Ntfs",类型名真的是L"Device"

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值