美文网首页
Windows内核对象,句柄表

Windows内核对象,句柄表

作者: fIappy | 来源:发表于2019-06-10 09:57 被阅读0次

    这块算是基本搞明白了
    ...常用命令
    查看所有进程基本信息:
    !process 0 0

    查看进程eprocess:
    dt _eprocess fffffa801aaae060 含有_handle_table

    typedef struct _HANDLE_TABLE                         // 15 elements, 0x68 bytes (sizeof) 
    {
        /*0x000*/     UINT64       TableCode;  //关键一项
        /*0x008*/     struct _EPROCESS* QuotaProcess;
        /*0x010*/     VOID*        UniqueProcessId;
        /*0x018*/     UINT64 HandleLock;                 // 7 elements, 0x8 bytes (sizeof)   
        /*0x020*/     struct _LIST_ENTRY HandleTableList;              // 2 elements, 0x10 bytes (sizeof)  
        /*0x030*/     UINT64 HandleContentionEvent;      // 7 elements, 0x8 bytes (sizeof)   
        /*0x038*/     PVOID DebugInfo;
        /*0x040*/     LONG32       ExtraInfoPages;
        union                                            // 2 elements, 0x4 bytes (sizeof)   
        {
            /*0x044*/         ULONG32      Flags;
            /*0x044*/         UINT8        StrictFIFO : 1;                 // 0 BitPosition                    
        };
        /*0x048*/     ULONG32      FirstFreeHandle;
        /*0x04C*/     UINT8        _PADDING0_[0x4];
        /*0x050*/     struct _HANDLE_TABLE_ENTRY* LastFreeHandleEntry;
        /*0x058*/     ULONG32      HandleCount;
        /*0x05C*/     ULONG32      NextHandleNeedingPool;
        /*0x060*/     ULONG32      HandleCountHighWatermark;
        /*0x064*/     UINT8        _PADDING1_[0x4];
    }HANDLE_TABLE, *PHANDLE_TABLE;
    
    

    假如只有一项,TableCode指向的内容是HANDLE_TABLE_ENTRY数组,低3位表示是否是2,3级表:

    typedef struct _HANDLE_TABLE_ENTRY                  // 8 elements, 0x10 bytes (sizeof) 
    {
        union                                           // 4 elements, 0x8 bytes (sizeof)  
        {
            /*0x000*/         VOID*        Object;//这里去掉最低3位指向_object_header
            /*0x000*/         ULONG32      ObAttributes;
            /*0x000*/         PVOID* InfoTable;
            /*0x000*/         UINT64       Value;
        };
        union                                           // 3 elements, 0x8 bytes (sizeof)  
        {
            /*0x008*/         ULONG32      GrantedAccess;
            struct                                      // 2 elements, 0x8 bytes (sizeof)  
            {
                /*0x008*/             UINT16       GrantedAccessIndex;
                /*0x00A*/             UINT16       CreatorBackTraceIndex;
                /*0x00C*/             UINT8        _PADDING0_[0x4];
            };
            /*0x008*/         ULONG32      NextFreeTableEntry;
        };
    }HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
    

    一个进程的句柄值handle/4=index, handle_table[index].object=目标对象的对象头

    对象头:

    typedef struct _OBJECT_HEADER                                // 12 elements, 0x38 bytes (sizeof) 
              {                                                                                                
    /*0x000*/     INT64        PointerCount;                                                                   
                  union                                                    // 2 elements, 0x8 bytes (sizeof)   
                  {                                                                                            
    /*0x008*/         INT64        HandleCount;                                                                
    /*0x008*/         VOID*        NextToFree;                                                                 
                  };                                                                                           
    /*0x010*/     struct _EX_PUSH_LOCK Lock;                               // 7 elements, 0x8 bytes (sizeof)   
    /*0x018*/     UINT8        TypeIndex;    //类型对象索引 在ObTypeIndexTable中的索引                                                                                         
    /*0x019*/     UINT8        TraceFlags;                                                                     
    /*0x01A*/     UINT8        InfoMask;                                                                       
    /*0x01B*/     UINT8        Flags;                                                                          
    /*0x01C*/     UINT8        _PADDING0_[0x4];                                                                
                  union                                                    // 2 elements, 0x8 bytes (sizeof)   
                  {                                                                                            
    /*0x020*/         struct _OBJECT_CREATE_INFORMATION* ObjectCreateInfo;                                     
    /*0x020*/         VOID*        QuotaBlockCharged;                                                          
                  };                                                                                           
    /*0x028*/     VOID*        SecurityDescriptor;                                                             
    /*0x030*/     struct _QUAD Body;                                       // 2 elements, 0x8 bytes (sizeof)   对象体
              }OBJECT_HEADER, *POBJECT_HEADER;        
    

    类型对象

     typedef struct _OBJECT_TYPE                   // 12 elements, 0xD0 bytes (sizeof) 
              {                                                                                 
    /*0x000*/     struct _LIST_ENTRY TypeList;              // 2 elements, 0x10 bytes (sizeof)  
    /*0x010*/     struct _UNICODE_STRING Name;              // 3 elements, 0x10 bytes (sizeof)  类型名字
    /*0x020*/     VOID*        DefaultObject;                                                   
    /*0x028*/     UINT8        Index;                               //在ObTypeIndexTable中的索引                         
    /*0x029*/     UINT8        _PADDING0_[0x3];                                                 
    /*0x02C*/     ULONG32      TotalNumberOfObjects;                                            
    /*0x030*/     ULONG32      TotalNumberOfHandles;                                            
    /*0x034*/     ULONG32      HighWaterNumberOfObjects;                                        
    /*0x038*/     ULONG32      HighWaterNumberOfHandles;                                        
    /*0x03C*/     UINT8        _PADDING1_[0x4];                                                 
    /*0x040*/     struct _OBJECT_TYPE_INITIALIZER TypeInfo; // 25 elements, 0x70 bytes (sizeof) 
    /*0x0B0*/     struct _EX_PUSH_LOCK TypeLock;            // 7 elements, 0x8 bytes (sizeof)   
    /*0x0B8*/     ULONG32      Key;                                                             
    /*0x0BC*/     UINT8        _PADDING2_[0x4];                                                 
    /*0x0C0*/     struct _LIST_ENTRY CallbackList;          // 2 elements, 0x10 bytes (sizeof)  该类型对象的回调函数链表
              }OBJECT_TYPE, *POBJECT_TYPE;          
    

    每个类型对象存在一个全局变量指针POBJECT_TYPE
    而且所有类型对象处于一个全局数组中:dq ObTypeIndexTable
    Windows内核原理与实现的书讲到dq obpobjecttypes东西,这个和ObTypeIndexTable[2:]内容相同
    windbg !object命令查看OBJECT_TYPE.
    类型信息

              typedef struct _OBJECT_TYPE_INITIALIZER                                                                                                                                         // 25 elements, 0x70 bytes (sizeof) 
              {                                                                                                                                                                                                                   
    /*0x000*/     UINT16       Length;                                                                                                                                                                                            
                  union                                                                                                                                                                       // 2 elements, 0x1 bytes (sizeof)   
                  {                                                                                                                                                                                                               
    /*0x002*/         UINT8        ObjectTypeFlags;                                                                                                                                                                               
                      struct                                                                                                                                                                  // 7 elements, 0x1 bytes (sizeof)   
                      {                                                                                                                                                                                                           
    /*0x002*/             UINT8        CaseInsensitive : 1;                                                                                                                                   // 0 BitPosition                    
    /*0x002*/             UINT8        UnnamedObjectsOnly : 1;                                                                                                                                // 1 BitPosition                    
    /*0x002*/             UINT8        UseDefaultObject : 1;                                                                                                                                  // 2 BitPosition                    
    /*0x002*/             UINT8        SecurityRequired : 1;                                                                                                                                  // 3 BitPosition                    
    /*0x002*/             UINT8        MaintainHandleCount : 1;                                                                                                                               // 4 BitPosition                    
    /*0x002*/             UINT8        MaintainTypeList : 1;                                                                                                                                  // 5 BitPosition                    
    /*0x002*/             UINT8        SupportsObjectCallbacks : 1;                                                                                                                           // 6 BitPosition                    
                      };                                                                                                                                                                                                          
                  };                                                                                                                                                                                                              
    /*0x004*/     ULONG32      ObjectTypeCode;                                                                                                                                                                                    
    /*0x008*/     ULONG32      InvalidAttributes;                                                                                                                                                                                 
    /*0x00C*/     struct _GENERIC_MAPPING GenericMapping;                                                                                                                                     // 4 elements, 0x10 bytes (sizeof)  
    /*0x01C*/     ULONG32      ValidAccessMask;        //访问掩码                                                                                                                                                                           
    /*0x020*/     ULONG32      RetainAccess;                                                                                                                                                                                      
    /*0x024*/     enum _POOL_TYPE PoolType;                                                                                                                                                                                       
    /*0x028*/     ULONG32      DefaultPagedPoolCharge;                                                                                                                                                                            
    /*0x02C*/     ULONG32      DefaultNonPagedPoolCharge;                                                                                                                                                                         
    /*0x030*/     FUNCT_00A3_0FB4_DumpProcedure* DumpProcedure;                                                                                                                                                                   
    /*0x038*/     FUNCT_005B_0FBC_OpenProcedure* OpenProcedure;                                                                                                                                                                   
    /*0x040*/     FUNCT_00A3_0FCA_CloseProcedure* CloseProcedure;                                                                                                                                                                 
    /*0x048*/     FUNCT_00A3_072C_Free_IdleHandler_InterfaceReference_InterfaceDereference_DeleteProcedure_WorkerRoutine_Callback_ReleaseFromLazyWrite_ReleaseFromReadAhead* DeleteProcedure;                                     
    /*0x050*/     FUNCT_005B_0FD0_ParseProcedure* ParseProcedure;                                                                                                                                                                 
    /*0x058*/     FUNCT_005B_0FDC_SecurityProcedure* SecurityProcedure;                                                                                                                                                           
    /*0x060*/     FUNCT_005B_0FED_QueryNameProcedure* QueryNameProcedure;                                                                                                                                                         
    /*0x068*/     FUNCT_0065_0FF5_OkayToCloseProcedure* OkayToCloseProcedure;                                                                                                                                                     
              }OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;  
    

    全局内核句柄表, 进程pid,线程tid的本质
    全局变量:PspCidTable,这个表是系统上所有进程和线程对象所在的表,而且只含有进程和线程
    所有pid和tid是它的索引,所有pid和tid的集合没有重复,就是说不会有一个pid和tid的值相同,即便跨进程

    kd> dq PspCidTable
    fffff800`04072bc8  fffff8a0`00004880 00000000`00000000
    fffff800`04072bd8  ffffffff`80000020 00000000`00000101
    fffff800`04072be8  ffffffff`800002dc ffffffff`80000024
    
    

    fffff8a0`00004880为handle_table

    kd> dt _handle_table fffff8a0`00004880
    nt!_HANDLE_TABLE
       +0x000 TableCode        : 0xfffff8a0`01201001  说明是二级表
       +0x008 QuotaProcess     : (null) 
       +0x010 UniqueProcessId  : (null) 
       +0x018 HandleLock       : _EX_PUSH_LOCK
       +0x020 HandleTableList  : _LIST_ENTRY [ 0xfffff8a0`000048a0 - 0xfffff8a0`000048a0 ]
       +0x030 HandleContentionEvent : _EX_PUSH_LOCK
       +0x038 DebugInfo        : (null) 
       +0x040 ExtraInfoPages   : 0n0
       +0x044 Flags            : 1
       +0x044 StrictFIFO       : 0y1
       +0x048 FirstFreeHandle  : 0x3b0
       +0x050 LastFreeHandleEntry : 0xfffff8a0`01202e70 _HANDLE_TABLE_ENTRY
       +0x058 HandleCount      : 0x228
       +0x05c NextHandleNeedingPool : 0xc00
    
    kd> dq 0xfffff8a0`01201000
    fffff8a0`01201000  fffff8a0`00005000 fffff8a0`01202000
    fffff8a0`01201010  fffff8a0`01831000 00000000`00000000
    fffff8a0`01201020  00000000`00000000 00000000`00000000
    
    
    kd> dt _handle_table_entry fffff8a0`00005010
    nt!_HANDLE_TABLE_ENTRY
       +0x000 Object           : 0xfffffa80`18dc5741 Void system进程的eprocess
       +0x000 ObAttributes     : 0x18dc5741
       +0x000 InfoTable        : 0xfffffa80`18dc5741 _HANDLE_TABLE_ENTRY_INFO
       +0x000 Value            : 0xfffffa80`18dc5741
       +0x008 GrantedAccess    : 0
       +0x008 GrantedAccessIndex : 0
       +0x00a CreatorBackTraceIndex : 0
       +0x008 NextFreeTableEntry : 0
    
    kd> !process 0 0 system
    PROCESS fffffa8018dc5740
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 00187000  ObjectTable: fffff8a000001780  HandleCount: 507.
        Image: System
    
    

    对象体作为ObGetObjectType的参数,返回对象类型.

    一级表遍历方法: pid=0x110

    kd> db poi(fffff8a0`00005000+0x10*(110/4))-1+0x2e0
    fffffa80`1ad37e10  73 76 63 68 6f 73 74 2e-65 78 65 00 00 00 00 02  svchost.exe.....
    fffffa80`1ad37e20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    fffffa80`1ad37e30  00 00 00 00 00 00 00 00-c0 9d d3 1a 80 fa ff ff  ................
    fffffa80`1ad37e40  80 6f da 1a 80 fa ff ff-00 00 00 00 00 00 00 00  .o..............
    fffffa80`1ad37e50  00 00 00 00 00 00 00 00-0e 00 00 00 c5 ef db f5  ................
    fffffa80`1ad37e60  00 00 00 00 00 00 00 00-00 e0 fd ff ff 07 00 00  ................
    fffffa80`1ad37e70  00 00 00 00 00 00 00 00-3c 08 00 00 00 00 00 00  ........<.......
    fffffa80`1ad37e80  06 00 00 00 00 00 00 00-c1 2f 00 00 00 00 00 00  ........./......
    

    二级表遍历方法:pid=0x460

    kd> db poi(poi(fffff8a0`01201000+8)+0x10*((460-0x400)/4))-1+0x2e0
    fffffa80`1ad48340  73 70 6f 6f 6c 73 76 2e-65 78 65 00 00 00 00 02  spoolsv.exe.....
    fffffa80`1ad48350  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    fffffa80`1ad48360  00 00 00 00 00 00 00 00-80 24 d4 1a 80 fa ff ff  .........$......
    fffffa80`1ad48370  70 1d 15 1b 80 fa ff ff-00 00 00 00 00 00 00 00  p...............
    fffffa80`1ad48380  00 00 00 00 00 00 00 00-0c 00 00 00 39 ff d0 e4  ............9...
    fffffa80`1ad48390  00 00 00 00 00 00 00 00-00 40 fd ff ff 07 00 00  .........@......
    fffffa80`1ad483a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    fffffa80`1ad483b0  00 00 00 00 00 00 00 00-c4 02 00 00 00 00 00 00  ................
    

    每个表最大的句柄值为0x400,超过的为(pid-0x400)/4

    一些操作:

    //根据调试对象类型名字,获取调试对象类型指针, L"name" 
    PVOID MyGetObjectType(PWCHAR ObjectTypeName)
    {
            //
            //需要声明下函数 ->NTKERNELAPI PVOID ObGetObjectType(HANDLE ObjectAdd);
            //
            UNICODE_STRING name;
            BOOLEAN i = 2;
            PVOID pObjectType;
    
            if (ObjectTypeName == NULL)
            {
                    return 0;
            }
            RtlInitUnicodeString(&name, ObjectTypeName); //初始化
    
            while (ObGetObjectType((PVOID)(&i + 0x18))) //遍历循环对象类型数组
            {
                    pObjectType = ObGetObjectType(&i + 0x18); //获取对象类型结构的指针
                    i++;
    
                    //返回真表示,字符串相等,则找到了对应的名字的对象类型了
                    if (RtlEqualUnicodeString((PVOID)((ULONG_PTR)pObjectType + 0x10), &name, TRUE))
                    {
                            return pObjectType;//返回对象类型地址
                    }
    
            }
    
            return 0;  //否则没有找到则返回0;
    }
    //调用方法
    PVOID        gDebugObjectType = 0;
    gDebugObjectType = MyGetObjectType(L"DebugObject");
    

    进程句柄表遍历:

    #ifndef F_HANDLE
    #define F_HANDLE
    #include <ntddk.h>
    
    #define HANDLE_TABLE_OFFSET7 0x200
    #define IMAGE_FILE_NAME_OFFSET7 0x2E0
    
    
    
    typedef struct _HANDLE_TABLE_ENTRY                  // 8 elements, 0x10 bytes (sizeof) 
    {
        union                                           // 4 elements, 0x8 bytes (sizeof)  
        {
            /*0x000*/         VOID*        Object;
            /*0x000*/         ULONG32      ObAttributes;
            /*0x000*/         PVOID* InfoTable;
            /*0x000*/         UINT64       Value;
        };
        union                                           // 3 elements, 0x8 bytes (sizeof)  
        {
            /*0x008*/         ULONG32      GrantedAccess;
            struct                                      // 2 elements, 0x8 bytes (sizeof)  
            {
                /*0x008*/             UINT16       GrantedAccessIndex;
                /*0x00A*/             UINT16       CreatorBackTraceIndex;
                /*0x00C*/             UINT8        _PADDING0_[0x4];
            };
            /*0x008*/         ULONG32      NextFreeTableEntry;
        };
    }HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
    
    typedef struct _HANDLE_TABLE                         // 15 elements, 0x68 bytes (sizeof) 
    {
        /*0x000*/     UINT64       TableCode;
        /*0x008*/     struct _EPROCESS* QuotaProcess;
        /*0x010*/     VOID*        UniqueProcessId;
        /*0x018*/     UINT64 HandleLock;                 // 7 elements, 0x8 bytes (sizeof)   
        /*0x020*/     struct _LIST_ENTRY HandleTableList;              // 2 elements, 0x10 bytes (sizeof)  
        /*0x030*/     UINT64 HandleContentionEvent;      // 7 elements, 0x8 bytes (sizeof)   
        /*0x038*/     PVOID DebugInfo;
        /*0x040*/     LONG32       ExtraInfoPages;
        union                                            // 2 elements, 0x4 bytes (sizeof)   
        {
            /*0x044*/         ULONG32      Flags;
            /*0x044*/         UINT8        StrictFIFO : 1;                 // 0 BitPosition                    
        };
        /*0x048*/     ULONG32      FirstFreeHandle;
        /*0x04C*/     UINT8        _PADDING0_[0x4];
        /*0x050*/     struct _HANDLE_TABLE_ENTRY* LastFreeHandleEntry;
        /*0x058*/     ULONG32      HandleCount;
        /*0x05C*/     ULONG32      NextHandleNeedingPool;
        /*0x060*/     ULONG32      HandleCountHighWatermark;
        /*0x064*/     UINT8        _PADDING1_[0x4];
    }HANDLE_TABLE, *PHANDLE_TABLE;
    
    
    typedef struct _OBJECT_HEADER                                // 12 elements, 0x38 bytes (sizeof) 
    {
        /*0x000*/     INT64        PointerCount;
        union                                                    // 2 elements, 0x8 bytes (sizeof)   
        {
            /*0x008*/         INT64        HandleCount;
            /*0x008*/         VOID*        NextToFree;
        };
        /*0x010*/     INT64 Lock;                               // 7 elements, 0x8 bytes (sizeof)   
        /*0x018*/     UINT8        TypeIndex;
        /*0x019*/     UINT8        TraceFlags;
        /*0x01A*/     UINT8        InfoMask;
        /*0x01B*/     UINT8        Flags;
        /*0x01C*/     UINT8        _PADDING0_[0x4];
        union                                                    // 2 elements, 0x8 bytes (sizeof)   
        {
            /*0x020*/         PVOID ObjectCreateInfo;
            /*0x020*/         VOID*        QuotaBlockCharged;
        };
        /*0x028*/     VOID*        SecurityDescriptor;
        /*0x030*/     struct _QUAD Body;                                       // 2 elements, 0x8 bytes (sizeof)   
    }OBJECT_HEADER, *POBJECT_HEADER;
    
    
    typedef struct _OBJECT_TYPE_INITIALIZER                                                                                                                                         // 25 elements, 0x70 bytes (sizeof) 
    {
        /*0x000*/     UINT16       Length;
        union                                                                                                                                                                       // 2 elements, 0x1 bytes (sizeof)   
        {
            /*0x002*/         UINT8        ObjectTypeFlags;
            struct                                                                                                                                                                  // 7 elements, 0x1 bytes (sizeof)   
            {
                /*0x002*/             UINT8        CaseInsensitive : 1;                                                                                                                                   // 0 BitPosition                    
                /*0x002*/             UINT8        UnnamedObjectsOnly : 1;                                                                                                                                // 1 BitPosition                    
                /*0x002*/             UINT8        UseDefaultObject : 1;                                                                                                                                  // 2 BitPosition                    
                /*0x002*/             UINT8        SecurityRequired : 1;                                                                                                                                  // 3 BitPosition                    
                /*0x002*/             UINT8        MaintainHandleCount : 1;                                                                                                                               // 4 BitPosition                    
                /*0x002*/             UINT8        MaintainTypeList : 1;                                                                                                                                  // 5 BitPosition                    
                /*0x002*/             UINT8        SupportsObjectCallbacks : 1;                                                                                                                           // 6 BitPosition                    
            };
        };
        /*0x004*/     ULONG32      ObjectTypeCode;
        /*0x008*/     ULONG32      InvalidAttributes;
        /*0x00C*/     struct _GENERIC_MAPPING GenericMapping;                                                                                                                                     // 4 elements, 0x10 bytes (sizeof)  
        /*0x01C*/     ULONG32      ValidAccessMask;
        /*0x020*/     ULONG32      RetainAccess;
        /*0x024*/     enum _POOL_TYPE PoolType;
        /*0x028*/     ULONG32      DefaultPagedPoolCharge;
        /*0x02C*/     ULONG32      DefaultNonPagedPoolCharge;
        /*0x030*/     PVOID DumpProcedure;
        /*0x038*/     VOID* OpenProcedure;
        /*0x040*/     VOID* CloseProcedure;
        /*0x048*/     VOID* DeleteProcedure;
        /*0x050*/     VOID* ParseProcedure;
        /*0x058*/     VOID* SecurityProcedure;
        /*0x060*/     VOID* QueryNameProcedure;
        /*0x068*/     VOID* OkayToCloseProcedure;
    }OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
    
    
    typedef struct _OBJECT_TYPE7                   // 12 elements, 0xD0 bytes (sizeof) 
    {
        /*0x000*/     struct _LIST_ENTRY TypeList;              // 2 elements, 0x10 bytes (sizeof)  
        /*0x010*/     struct _UNICODE_STRING Name;              // 3 elements, 0x10 bytes (sizeof)  类型名字
        /*0x020*/     VOID*        DefaultObject;
        /*0x028*/     UINT8        Index;                               //在ObTypeIndexTable中的索引                         
        /*0x029*/     UINT8        _PADDING0_[0x3];
        /*0x02C*/     ULONG32      TotalNumberOfObjects;
        /*0x030*/     ULONG32      TotalNumberOfHandles;
        /*0x034*/     ULONG32      HighWaterNumberOfObjects;
        /*0x038*/     ULONG32      HighWaterNumberOfHandles;
        /*0x03C*/     UINT8        _PADDING1_[0x4];
        /*0x040*/     struct _OBJECT_TYPE_INITIALIZER TypeInfo; // 25 elements, 0x70 bytes (sizeof) 
        /*0x0B0*/     ULONG64 TypeLock;            // 7 elements, 0x8 bytes (sizeof)   
        /*0x0B8*/     ULONG32      Key;
        /*0x0BC*/     UINT8        _PADDING2_[0x4];
        /*0x0C0*/     struct _LIST_ENTRY CallbackList;          // 2 elements, 0x10 bytes (sizeof)  该类型对象的回调函数链表
    }OBJECT_TYPE7, *POBJECT_TYPE7;
    NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE Id, PEPROCESS *Process);
    NTKERNELAPI POBJECT_TYPE ObGetObjectType(PVOID Object);
    
    
    NTSTATUS EnumProcessHandles(ULONG pid)
    {
        PEPROCESS eproc;
        NTSTATUS ret;
        ret = PsLookupProcessByProcessId(pid, &eproc);
        
        if (!NT_SUCCESS(ret))
        {
            return ret;
        }
        ObDereferenceObject(eproc);
        PHANDLE_TABLE ht = *(PULONG64)((ULONG64)eproc + HANDLE_TABLE_OFFSET7);
    
        ULONG64 tablecode = ht->TableCode;
        UINT8 level = tablecode & (0x3);
        PHANDLE_TABLE_ENTRY pTable;
        ULONG64* pTable2;
        ULONG64* pTable3;
        PHANDLE_TABLE_ENTRY pEntry;
        ULONG64* pEntry2;
        ULONG64* pEntry3;
        POBJECT_HEADER pObjh;
        POBJECT_TYPE7 obt;
        ULONG32 handle_value=0;
        ULONG count = 0;
        if (level == 0)//1级表
        {
            pTable = tablecode & (0xfffffffffffffffc);
            pEntry = pTable;
            while (pEntry&&count<(PAGE_SIZE/sizeof(HANDLE_TABLE_ENTRY)))
            {
                pObjh = (ULONG64)(pEntry->Object)&(0xfffffffffffffff8);
                if (pObjh)
                {
                    obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                    if (obt)
                    {
                        DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                    }
                }
                handle_value += 4;
                pEntry++;
                count++;
                
            }
    
        }
        else if (level == 1)//2级表
        {
            pTable2 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry2 = pTable2;
    
            while (*pEntry2)
            {
                pEntry = *pEntry2;
                while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                {
                    pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                    if (pObjh)
                    {
                        obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                        if (obt)
                        {
                            DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                        }
    
                    }
                    handle_value += 4;
                    pEntry++;
                    count++;
                }
                
                count = 0;
                pEntry2++;
            }
        }
        else if (level == 2)//3级表
        {
    
            pTable3 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry3 = pTable3;
            while (*pEntry3)
            {
                DbgBreakPoint();
                pEntry2 = *pEntry3;
                while (*pEntry2)
                {
                    pEntry = *pEntry2;
                    while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                    {
                        pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                        if (pObjh)
                        {
                            obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                            if (obt)
                            {
                                DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                            }
                        }
                        handle_value += 4;
                        pEntry++;
                        count++;
                    }
    
                    count = 0;
                    pEntry2++;
                }
                
                pEntry3++;
            }
        }
    
    
        return ret;
    }
    
    
    

    根据进程id查找目标句柄属性:

    
    NTSTATUS GetProcessHandle(ULONG pid, ULONG tarpid, PHANDLE_TABLE_ENTRY* buffer)
    {
        PEPROCESS eproc;
        NTSTATUS ret;
        ret = PsLookupProcessByProcessId(pid, &eproc);
    
        if (!NT_SUCCESS(ret))
        {
            return ret;
        }
        ObDereferenceObject(eproc);
        PHANDLE_TABLE ht = *(PULONG64)((ULONG64)eproc + HANDLE_TABLE_OFFSET7);
    
        ULONG64 tablecode = ht->TableCode;
        UINT8 level = tablecode & (0x3);
        PHANDLE_TABLE_ENTRY pTable;
        ULONG64* pTable2;
        ULONG64* pTable3;
        PHANDLE_TABLE_ENTRY pEntry;
        ULONG64* pEntry2;
        ULONG64* pEntry3;
        POBJECT_HEADER pObjh;
        POBJECT_TYPE7 obt;
        ULONG32 handle_value = 0;
        ULONG count = 0;
        ULONG64 PID;
        if (level == 0)//1级表
        {
            pTable = tablecode & (0xfffffffffffffffc);
            pEntry = pTable;
            while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
            {
                pObjh = (ULONG64)(pEntry->Object)&(0xfffffffffffffff8);
                if (pObjh)
                {
                    obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                    if (obt)
                    {
                        //DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                        if (obt->Index == 0x7)
                        {
                            PID = *(ULONG64*)(UniqueProcessId_OFFSET7 + (ULONG64)(&pObjh->Body));
                            if (PID == tarpid)
                            {
                                *buffer = pEntry;
                                DbgPrint("handle:%d\n", handle_value);
                                return ret;
                            }
                        }
                    }
                }
                handle_value += 4;
                pEntry++;
                count++;
    
            }
    
        }
        else if (level == 1)//2级表
        {
            pTable2 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry2 = pTable2;
    
            while (*pEntry2)
            {
                pEntry = *pEntry2;
                while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                {
                    pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                    if (pObjh)
                    {
                        obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                        if (obt)
                        {
                            //DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                            if (obt->Index == 0x7)
                            {
                                PID = *(ULONG64*)(UniqueProcessId_OFFSET7 + (ULONG64)(&pObjh->Body));
                                if (PID == tarpid)
                                {
                                    *buffer = pEntry;
                                    return ret;
                                }
                            }
                        }
    
                    }
                    handle_value += 4;
                    pEntry++;
                    count++;
                }
    
                count = 0;
                pEntry2++;
            }
        }
        else if (level == 2)//3级表
        {
    
            pTable3 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry3 = pTable3;
            while (*pEntry3)
            {
                DbgBreakPoint();
                pEntry2 = *pEntry3;
                while (*pEntry2)
                {
                    pEntry = *pEntry2;
                    while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                    {
                        pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                        if (pObjh)
                        {
                            obt = (POBJECT_TYPE7)ObGetObjectType(&pObjh->Body);
                            if (obt)
                            {
                                //DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, &pObjh->Body);
                                if (obt->Index == 0x7)
                                {
                                    PID = *(ULONG64*)(UniqueProcessId_OFFSET7 + (ULONG64)(&pObjh->Body));
                                    if (PID == tarpid)
                                    {
                                        *buffer = pEntry;
                                        return ret;
                                    }
                                }
                            }
                        }
                        handle_value += 4;
                        pEntry++;
                        count++;
                    }
    
                    count = 0;
                    pEntry2++;
                }
    
                pEntry3++;
            }
        }
    
    
        return ret;
    }
    
    

    系统句柄表遍历

    
    void EnumSystemHandles(ULONG64* PspCidTable)
    {
        PEPROCESS eproc;
        NTSTATUS ret;
    
        PHANDLE_TABLE ht = *PspCidTable;
    
        ULONG64 tablecode = ht->TableCode;
        UINT8 level = tablecode & (0x3);
        PHANDLE_TABLE_ENTRY pTable;
        ULONG64* pTable2;
        ULONG64* pTable3;
        PHANDLE_TABLE_ENTRY pEntry;
        ULONG64* pEntry2;
        ULONG64* pEntry3;
        POBJECT_HEADER pObjh;
        POBJECT_TYPE7 obt;
        ULONG32 handle_value = 0;
        ULONG count = 0;
        //在系统句柄表中,pObjh直接就是对象体,而不是对象头
        if (level == 0)//1级表
        {
            pTable = tablecode & (0xfffffffffffffffc);
            pEntry = pTable;
            while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
            {
                pObjh = (ULONG64)(pEntry->Object)&(0xfffffffffffffff8);
                if (pObjh)
                {
                    obt = (POBJECT_TYPE7)ObGetObjectType(pObjh);
                    if (obt)
                    {
                        DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, pObjh);
                    }
                }
                
                handle_value += 4;
                pEntry++;
                count++;
            }
    
        }
        else if (level == 1)//2级表
        {
            pTable2 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry2 = pTable2;
    
            while (*pEntry2)
            {
                pEntry = *pEntry2;
                while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                {
                    pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                    if (pObjh)
                    {
                        obt = (POBJECT_TYPE7)ObGetObjectType(pObjh);
                        if (obt)
                        {
                            DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, pObjh);
                        }
                    }
    
                    handle_value += 4;
                    pEntry++;
                    count++;
                }
    
                count = 0;
                pEntry2++;
            }
        }
        else if (level == 2)//3级表
        {
    
            pTable3 = (ULONG64*)(tablecode & (0xfffffffffffffffc));
            pEntry3 = pTable3;
            while (*pEntry3)
            {
                DbgBreakPoint();
                pEntry2 = *pEntry3;
                while (*pEntry2)
                {
                    pEntry = *pEntry2;
                    while (pEntry&&count < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)))
                    {
                        pObjh = (ULONG64)(pEntry->Object) & 0xfffffffffffffff8;
                        if (pObjh)
                        {
                            obt = (POBJECT_TYPE7)ObGetObjectType(pObjh);
                            if (obt)
                            {
                                DbgPrint("handle_value:%d, handle_type:%wZ, handle_type_index:%x, object_body:%p\n", handle_value, &obt->Name, obt->Index, pObjh);
                            }
                        }
                        handle_value += 4;
                        pEntry++;
                        count++;
                    }
    
                    count = 0;
                    pEntry2++;
                }
    
                pEntry3++;
            }
        }
    
    
        
    }
    
    
    

    相关文章

      网友评论

          本文标题:Windows内核对象,句柄表

          本文链接:https://www.haomeiwen.com/subject/qvbkxctx.html