遍歷系統的所有ObjectType和TypeIndex


Windows內部有很多的對象類型,比如PROCESS類型,THREAD類型,FILE類型,LPC PORT類型,DEVICE類型等等,我們可以使用sysinternal提供的winobj工具來查看(win7 x86 sp1)

Win7 ObjectTypes

在編程的過程中我們有時候需要用到類型的索引(TypeIndex),由於在不同的操作系統版本中TypeIndex會發生改變,本文將教大家一種方法來遍歷這些類型還有其相應的TypeIndex

 

首先要知道類型也是一種對象,同樣它也有OBJECT HEADER,OBJECT BODY等信息,是通過OBJECT MANAGER對象管理器來管理的

在這些類型對象當中有一個非常重要的對象,叫做Type對象,這是系統中第一個被初始化的類型對象(可稱之為“元類型”),系統中其他的類型對象都是通過這個特殊的“元類型”對象來創建的

那么這些類型對象是放在什么地方又是通過什么樣的關系組織起來的呢?

 

我們之前說過類型也是一種對象,它的OBJECT BODY其實是nt!_object_type,用windbg dt查看一下(win7 x86 sp1)

win7 Object Type

其中的第一個數據成員是TypeList,對象是不是就是通過這個TypeList連接起來的呢?

通過查閱ReactOS中的ObCreateObjectType中的實現,發下了如下的代碼

ObCreateObjectType

原來正是通過CreateInfo中的TypeList來鏈接起所有的類型對象,而這個鏈表的頭結點就是ObpTypeObjectType,其實就是“元類型”對象

CreateInfo的數據結構是nt!_OBJECT_HEADER_CREATOR_INFO,里面果真有個TypeList

CreatorInfo

因此如果要遍歷所有的類型對象的話只要找到這個表的表頭即可,那么表頭ObpTypeObjectType怎么找呢?這里介紹兩種方法

  • 通過前面<<獲取操作系統的內核基地址>>文章中提到的KdVersionBlock--〉_KDDEBUGGER_DATA64—>ObpTypeObjectType,這是最省心的辦法了
  • 通過特征碼來搜索ObCreateObjectType函數找到ObpTypeObjectType,XPSP3下搜索35ff,53,win7 x86 sp1下搜索a1和bb

第一種方法不需要特征碼比較的簡單這里就不再介紹了,下面着重介紹第二種方法,經常看到有文章介紹如何通過特征碼來搜索未導出的函數或者變量,初學者都會感到困惑,今天我就來為大家解惑解惑~

 

首先我們需要的ObpTypeObjectType在ObCreateObjectType中被調用到,我們反匯編一下這個函數,uf ObCreateObjectType(下面如果未特別說明,就表示是win7 x86 sp1的環境)

kd> uf ObCreateObjectType
nt!ObCreateObjectType:
829aff6a 8bff            mov     edi,edi
829aff6c 55              push    ebp
829aff6d 8bec            mov     ebp,esp
829aff6f ff7514          push    dword ptr [ebp+14h]
829aff72 6a00            push    0
829aff74 ff750c          push    dword ptr [ebp+0Ch]
829aff77 ff7508          push    dword ptr [ebp+8]
829aff7a e809000000      call    nt!ObCreateObjectTypeEx (829aff88)
829aff7f 5d              pop     ebp
829aff80 c21000          ret     10h

里面還調用了nt!ObCreateObjectTypeEx,我們再反匯編一下這個函數,uf ObCreateObjectTypeEx,這個函數反匯編后的結果比較長,我們在反匯編窗口中Ctrl+F搜索一下ObpTypeObjectType,定位到下面片段

nt!ObCreateObjectTypeEx+0x277:
829b01ff 668b4302        mov     ax,word ptr [ebx+2]
829b0203 668944242e      mov     word ptr [esp+2Eh],ax
829b0208 53              push    ebx
829b0209 8d442430        lea     eax,[esp+30h]
829b020d 50              push    eax
829b020e e8fd01f3ff      call    nt!RtlCopyUnicodeString (828e0410)
829b0213 a154a79782      mov     eax,dword ptr [nt!ObpTypeObjectType (8297a754)]
829b0218 bb88000000 mov ebx,88h
829b021d 85c0 test eax,eax
829b021f 7404 je nt!ObCreateObjectTypeEx+0x29d (829b0225)

看到沒,在地址829b0213中的機器碼為a154a79782,后面四個字節的機器碼就是ObpTypeObjectType的地址(小端機器所以順序是倒着過來的),因此我們通過搜索函數中a1和bb特征碼來唯一的定位到這個地址即可~

搜索的起始位置就是ObCreateObjectType,這個函數的地址可以通過MmGetSystemRoutineAddress來得到,下面截圖一下代碼,為的是讓大家自己敲代碼來尋找,加深理解

GetObpTypeObjectType_WIN7

會了的話再去試着找XP下的地址,看結果對不對就去比較上面方法1中KdVersionBlock--〉_KDDEBUGGER_DATA64—>ObpTypeObjectType得到的地址

 

同樣的有很多人想去解析PspCidTable句柄表,這個地址的獲取也可以利用上面的兩種方法

 

好了,轉入正題,現在我們知道了ObpTypeObjectType的地址,那么TypeObjectType(“元類型”)的地址就是

*(PULONG_PTR)ObpTypeObjectType

我們利用dt一下這個地址

kd> dd ObpTypeObjectType
8297a754  84f48f58 00000000 00000000 84f48f58
8297a764  84f48e90 84f48dc8 84f48b80 84f48a40
8297a774  84f48978 84f488b0 84f43c18 84f43b50
8297a784  84f434d0 84ff4b60 84ff4890 84ff0300
8297a794  84ff0140 84ff07b0 84ff4380 84fe5408
8297a7a4  84fe5340 84fe2418 84fe2350 84fe3418
8297a7b4  84fe3350 84fe6040 84fe6f78 84fe6eb0
8297a7c4  84fe6de8 84fe6d20 84fe6858 84fe6790
kd> dt _object_type 84f48f58 
ntdll!_OBJECT_TYPE
   +0x000 TypeList         : _LIST_ENTRY [ 0x84f48f30 - 0x85676310 ]
   +0x008 Name_UNICODE_STRING "Type"
+0x010 DefaultObject : 0x8297a860 Void
+0x014
Index: 0x2''
   +0x018 TotalNumberOfObjects : 0x2a
   +0x01c TotalNumberOfHandles : 0
   +0x020 HighWaterNumberOfObjects : 0x2a
   +0x024 HighWaterNumberOfHandles : 0
   +0x028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x078 TypeLock         : _EX_PUSH_LOCK
   +0x07c Key              : 0x546a624f
   +0x080 CallbackList     : _LIST_ENTRY [ 0x84f48fd8 - 0x84f48fd8 ]

發現它的名字為Type,Index為2

然后再尋找它的OBJECT_HEADER_CREATOR_INFO結構,這個結構在BODY的上方,winxp & win7下這個偏移量都是0x28

-----------------------------------------------high address

object body

-----------------------------------------------

object header

----------------------------------------------

object_header_creator_info

----------------------------------------------low address

因為有些對象不一定有CreatorInfo,NameInfo,HandleInfo等可選附加信息,看了一下windows internals里面說到object type是肯定有CreatorInfo結構,這下就放心了~

 

下面放出遍歷整個系統類型對象和TypeIndex的代碼(win7 x86 sp1 & winxp sp3,如果不是這兩種系統的話請慎重)

#include <ntddk.h>

DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;

ULONG OffsetObjectTypeName;
ULONG OffsetCreatorInfoObject;
ULONG OffsetObjectIndexObjectType;
POBJECT_TYPE ObpTypeObjectType;

VOID DriverUnload(PDRIVER_OBJECT Driver)
{
    DbgPrint("Driver Unload!\n");
}

POBJECT_TYPE GetObpTypeObjectType_WinXP()
{
    PUCHAR addr,p;
    UNICODE_STRING usObCreateObjectType;
    POBJECT_TYPE _ObpTypeObjectType=NULL;
    RtlInitUnicodeString(&usObCreateObjectType,L"ObCreateObjectType");
    addr=MmGetSystemRoutineAddress(&usObCreateObjectType);
    ASSERT(addr!=NULL);
    DbgPrint("ObCreateObjectType=0x%08x\n",addr);
    for (p=addr;p<addr+PAGE_SIZE;p++)
    {
        if ((*(PUSHORT)p==0x35ff) && (*(PUCHAR)(p+6)==0x53))
        {
            ObpTypeObjectType=(POBJECT_TYPE)(*(PULONG)(p+2));
            DbgPrint("ObpTypeObjectType=0x%08x\n",_ObpTypeObjectType);
            return _ObpTypeObjectType;
        }
    }
    if (p==addr+PAGE_SIZE)
        DbgPrint("Cannot find ObpTypeObjectType!\n");
    return NULL;
}

POBJECT_TYPE GetObpTypeObjectType_Win7()
{
    PUCHAR addr,p;
    UNICODE_STRING usObCreateObjectType;
    POBJECT_TYPE _ObpTypeObjectType=NULL;
    RtlInitUnicodeString(&usObCreateObjectType,L"ObCreateObjectType");
    addr=MmGetSystemRoutineAddress(&usObCreateObjectType);
    ASSERT(addr!=NULL);
    DbgPrint("ObCreateObjectType=0x%08x\n",addr);
    for (p=addr;p<addr+PAGE_SIZE;p++)
    {
        if ((*(PUCHAR)p==0xa1) && (*(PUCHAR)(p+5)==0xbb))
        {
            _ObpTypeObjectType=(POBJECT_TYPE)(*(PULONG)(p+1));
            DbgPrint("ObpTypeObjectType=0x%08x\n",_ObpTypeObjectType);
            return _ObpTypeObjectType;
        }
    }
    if (p==addr+PAGE_SIZE)
        DbgPrint("Cannot find ObpTypeObjectType!\n");
    return NULL;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT Driver,PUNICODE_STRING RegPath)
{
    NTSTATUS status=STATUS_SUCCESS;
    ULONG_PTR TypeObjectAddr;
    PLIST_ENTRY TypeObjectCreatorInfo;
    PLIST_ENTRY NextEntry;
    RTL_OSVERSIONINFOW VersionInformation;

    status=RtlGetVersion(&VersionInformation);
    if(!NT_SUCCESS(status))
    {
        DbgPrint("PsGetVersion failed,error=0x%08x\n",status);
        return STATUS_UNSUCCESSFUL;
    }
    if (VersionInformation.dwMajorVersion==6)//win7
    {
        OffsetObjectTypeName=0x08;
        OffsetCreatorInfoObject=0x28;
        OffsetObjectIndexObjectType=0x14;
        ObpTypeObjectType=GetObpTypeObjectType_Win7();
    }
    else{//winxp
        OffsetObjectTypeName=0x40;
        OffsetCreatorInfoObject=0x28;
        OffsetObjectIndexObjectType=0x4c;
        ObpTypeObjectType=GetObpTypeObjectType_WinXP();
    }
    TypeObjectAddr=*(PULONG_PTR)ObpTypeObjectType;
    TypeObjectCreatorInfo=(PLIST_ENTRY)(TypeObjectAddr-OffsetCreatorInfoObject);
    NextEntry=TypeObjectCreatorInfo;
    while (NextEntry->Flink!=TypeObjectCreatorInfo)
    {
        DbgPrint("TypeAddr=0x%08x,TypeName=%wZ,TypeIndex=%d\n",
            (ULONG_PTR)NextEntry+OffsetCreatorInfoObject,
            (PUNICODE_STRING)((ULONG_PTR)NextEntry+OffsetCreatorInfoObject+OffsetObjectTypeName),
            *(PUCHAR)((ULONG_PTR)NextEntry+OffsetCreatorInfoObject+OffsetObjectIndexObjectType));
        NextEntry=NextEntry->Flink;
    }
    Driver->DriverUnload=DriverUnload;
    return status;    
}

win7 x86 sp1的結果如下

ObCreateObjectType=0x829aff6a
ObpTypeObjectType=0x8297a754  
TypeAddr=0x84f48f58,TypeName=Type,TypeIndex=2
TypeAddr=0x84f48e90,TypeName=Directory,TypeIndex=3
TypeAddr=0x84f48dc8,TypeName=SymbolicLink,TypeIndex=4
TypeAddr=0x84f48b80,TypeName=Token,TypeIndex=5
TypeAddr=0x84f48a40,TypeName=Job,TypeIndex=6
TypeAddr=0x84f48978,TypeName=Process,TypeIndex=7
TypeAddr=0x84f488b0,TypeName=Thread,TypeIndex=8
TypeAddr=0x84f43c18,TypeName=UserApcReserve,TypeIndex=9
TypeAddr=0x84f43b50,TypeName=IoCompletionReserve,TypeIndex=10
TypeAddr=0x84f434d0,TypeName=DebugObject,TypeIndex=11
TypeAddr=0x84ff4b60,TypeName=Event,TypeIndex=12
TypeAddr=0x84ff4890,TypeName=EventPair,TypeIndex=13
TypeAddr=0x84ff0300,TypeName=Mutant,TypeIndex=14
TypeAddr=0x84ff0140,TypeName=Callback,TypeIndex=15
TypeAddr=0x84ff07b0,TypeName=Semaphore,TypeIndex=16
TypeAddr=0x84ff4380,TypeName=Timer,TypeIndex=17
TypeAddr=0x84fe5408,TypeName=Profile,TypeIndex=18
TypeAddr=0x84fe5340,TypeName=KeyedEvent,TypeIndex=19
TypeAddr=0x84fe2418,TypeName=WindowStation,TypeIndex=20
TypeAddr=0x84fe2350,TypeName=Desktop,TypeIndex=21
TypeAddr=0x84fe3418,TypeName=TpWorkerFactory,TypeIndex=22
TypeAddr=0x84fe3350,TypeName=Adapter,TypeIndex=23
TypeAddr=0x84fe6040,TypeName=Controller,TypeIndex=24
TypeAddr=0x84fe6f78,TypeName=Device,TypeIndex=25
TypeAddr=0x84fe6eb0,TypeName=Driver,TypeIndex=26
TypeAddr=0x84fe6de8,TypeName=IoCompletion,TypeIndex=27
TypeAddr=0x84fe6d20,TypeName=File,TypeIndex=28
TypeAddr=0x84fe6858,TypeName=TmTm,TypeIndex=29
TypeAddr=0x84fe6790,TypeName=TmTx,TypeIndex=30
TypeAddr=0x84fe66c8,TypeName=TmRm,TypeIndex=31
TypeAddr=0x84fe6600,TypeName=TmEn,TypeIndex=32
TypeAddr=0x84fe6430,TypeName=Section,TypeIndex=33
TypeAddr=0x84feef78,TypeName=Session,TypeIndex=34
TypeAddr=0x84feb8b8,TypeName=Key,TypeIndex=35
TypeAddr=0x84fe7ee0,TypeName=ALPC Port,TypeIndex=36
TypeAddr=0x84fe7630,TypeName=PowerRequest,TypeIndex=37
TypeAddr=0x84ff1e18,TypeName=WmiGuid,TypeIndex=38
TypeAddr=0x84ff1360,TypeName=EtwRegistration,TypeIndex=39
TypeAddr=0x84ff1298,TypeName=EtwConsumer,TypeIndex=40
TypeAddr=0x85dff150,TypeName=FilterConnectionPort,TypeIndex=41
TypeAddr=0x851424d0,TypeName=FilterCommunicationPort,TypeIndex=42
TypeAddr=0x85676338,TypeName=PcwObject,TypeIndex=43

winxp sp3的結果如下

ObCreateObjectType=0x805c5ea6
ObpTypeObjectType=0x80568c70
TypeAddr=0x867e9580,TypeName=Type,TypeIndex=1
TypeAddr=0x867e93b0,TypeName=Directory,TypeIndex=2
TypeAddr=0x867e91e0,TypeName=SymbolicLink,TypeIndex=3
TypeAddr=0x867b5040,TypeName=Token,TypeIndex=4
TypeAddr=0x867b5e70,TypeName=Process,TypeIndex=5
TypeAddr=0x867b5ca0,TypeName=Thread,TypeIndex=6
TypeAddr=0x867b5ad0,TypeName=Job,TypeIndex=7
TypeAddr=0x867b5408,TypeName=DebugObject,TypeIndex=8
TypeAddr=0x867b2980,TypeName=Event,TypeIndex=9
TypeAddr=0x867b27b0,TypeName=EventPair,TypeIndex=10
TypeAddr=0x867b25e0,TypeName=Mutant,TypeIndex=11
TypeAddr=0x867b2410,TypeName=Callback,TypeIndex=12
TypeAddr=0x867b1040,TypeName=Semaphore,TypeIndex=13
TypeAddr=0x867b1e70,TypeName=Timer,TypeIndex=14
TypeAddr=0x867b1ca0,TypeName=Profile,TypeIndex=15
TypeAddr=0x867b1ad0,TypeName=KeyedEvent,TypeIndex=16
TypeAddr=0x867b1900,TypeName=WindowStation,TypeIndex=17
TypeAddr=0x867b1730,TypeName=Desktop,TypeIndex=18
TypeAddr=0x867b1418,TypeName=Section,TypeIndex=19
TypeAddr=0x867ab5f8,TypeName=Key,TypeIndex=20
TypeAddr=0x867e8078,TypeName=Port,TypeIndex=21
TypeAddr=0x8679e040,TypeName=WaitablePort,TypeIndex=22
TypeAddr=0x8679e6c8,TypeName=Adapter,TypeIndex=23
TypeAddr=0x8679e4f8,TypeName=Controller,TypeIndex=24
TypeAddr=0x8679e328,TypeName=Device,TypeIndex=25
TypeAddr=0x867e7040,TypeName=Driver,TypeIndex=26
TypeAddr=0x867e7e70,TypeName=IoCompletion,TypeIndex=27
TypeAddr=0x867e7ca0,TypeName=File,TypeIndex=28
TypeAddr=0x86799250,TypeName=WmiGuid,TypeIndex=29
TypeAddr=0x864082d8,TypeName=FilterConnectionPort,TypeIndex=30
TypeAddr=0x8626e040,TypeName=FilterCommunicationPort,TypeIndex=31

學會了這種方法,以后就不怕系統的變化導致獲取不到相應的TypeIndex

 

BTW:系統內部還有個ObpObjectTypes的數組,存放的時所有類型對象的地址,不過沒有導出,請問這個要怎么去獲取?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM