這塊算是基本搞明白了
...常用命令
查看所有進(jìn)程基本信息:
!process 0 0
查看進(jìn)程eprocess:
dt _eprocess fffffa801aaae060 含有_handle_table
typedef struct _HANDLE_TABLE // 15 elements, 0x68 bytes (sizeof)
{
/*0x000*/ UINT64 TableCode; //關(guān)鍵一項(xiàng)
/*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;
假如只有一項(xiàng),TableCode指向的內(nèi)容是HANDLE_TABLE_ENTRY數(shù)組,低3位表示是否是2,3級(jí)表:
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;
一個(gè)進(jìn)程的句柄值handle/4=index, handle_table[index].object=目標(biāo)對(duì)象的對(duì)象頭
對(duì)象頭:
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; //類(lèi)型對(duì)象索引 在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) 對(duì)象體
}OBJECT_HEADER, *POBJECT_HEADER;
類(lèi)型對(duì)象
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) 類(lèi)型名字
/*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) 該類(lèi)型對(duì)象的回調(diào)函數(shù)鏈表
}OBJECT_TYPE, *POBJECT_TYPE;
每個(gè)類(lèi)型對(duì)象存在一個(gè)全局變量指針POBJECT_TYPE
而且所有類(lèi)型對(duì)象處于一個(gè)全局?jǐn)?shù)組中:dq ObTypeIndexTable
Windows內(nèi)核原理與實(shí)現(xiàn)的書(shū)講到dq obpobjecttypes東西,這個(gè)和ObTypeIndexTable[2:]內(nèi)容相同
windbg !object命令查看OBJECT_TYPE.
類(lèi)型信息
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; //訪(fǎng)問(wèn)掩碼
/*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;
全局內(nèi)核句柄表, 進(jìn)程pid,線(xiàn)程tid的本質(zhì)
全局變量:PspCidTable,這個(gè)表是系統(tǒng)上所有進(jìn)程和線(xiàn)程對(duì)象所在的表,而且只含有進(jìn)程和線(xiàn)程
所有pid和tid是它的索引,所有pid和tid的集合沒(méi)有重復(fù),就是說(shuō)不會(huì)有一個(gè)pid和tid的值相同,即便跨進(jìn)程
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 說(shuō)明是二級(jí)表
+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進(jìn)程的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
對(duì)象體作為ObGetObjectType的參數(shù),返回對(duì)象類(lèi)型.
一級(jí)表遍歷方法: 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 ........./......
二級(jí)表遍歷方法: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 ................
每個(gè)表最大的句柄值為0x400,超過(guò)的為(pid-0x400)/4
一些操作:
//根據(jù)調(diào)試對(duì)象類(lèi)型名字,獲取調(diào)試對(duì)象類(lèi)型指針, L"name"
PVOID MyGetObjectType(PWCHAR ObjectTypeName)
{
//
//需要聲明下函數(shù) ->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))) //遍歷循環(huán)對(duì)象類(lèi)型數(shù)組
{
pObjectType = ObGetObjectType(&i + 0x18); //獲取對(duì)象類(lèi)型結(jié)構(gòu)的指針
i++;
//返回真表示,字符串相等,則找到了對(duì)應(yīng)的名字的對(duì)象類(lèi)型了
if (RtlEqualUnicodeString((PVOID)((ULONG_PTR)pObjectType + 0x10), &name, TRUE))
{
return pObjectType;//返回對(duì)象類(lèi)型地址
}
}
return 0; //否則沒(méi)有找到則返回0;
}
//調(diào)用方法
PVOID gDebugObjectType = 0;
gDebugObjectType = MyGetObjectType(L"DebugObject");
進(jìn)程句柄表遍歷:
#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) 類(lèi)型名字
/*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) 該類(lèi)型對(duì)象的回調(diào)函數(shù)鏈表
}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級(jí)表
{
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級(jí)表
{
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級(jí)表
{
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;
}
根據(jù)進(jìn)程id查找目標(biāo)句柄屬性:
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級(jí)表
{
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級(jí)表
{
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級(jí)表
{
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;
}
系統(tǒng)句柄表遍歷
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;
//在系統(tǒng)句柄表中,pObjh直接就是對(duì)象體,而不是對(duì)象頭
if (level == 0)//1級(jí)表
{
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級(jí)表
{
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級(jí)表
{
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++;
}
}
}