D041-遍历指进程句柄权限+修改权限
2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115
学习目标
windbg调试技巧
逆向分析
windbg访问断点
dt查看结构指令
windbg使用帮助
参考 https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/commands
https://www.jianshu.com/p/1dcf0b246667?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry (
IN PHANDLE_TABLE HandleTable,//参数1是句柄表的地址,即 TableCode,注意,这里 TableCode 的低位不能清零,函数里要判断句柄表结构的。
IN EXHANDLE Handle//参数2是句柄值,PID 的值就是一个句柄值,调用 OpenProcess 打开一个进程得到的也是句柄值,前者用来索引全局句柄表,后者用来索引进程的句柄表。
)
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=目标对象的对象头
kd> dt _handle_table fffff8a0`00004880
nt!_HANDLE_TABLE
+0x000 TableCode : 0xfffff8a0`01201001 低4个bit非0说明是2-4级表
+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
一级表遍历方法: 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
PHANDLE_TABLE_ENTRY
ExpLookupHandleTableEntry (
IN PHANDLE_TABLE HandleTable,
IN EXHANDLE Handle
)
/*++
Routine Description:
This routine looks up and returns the table entry for the
specified handle value.
Arguments:
HandleTable - Supplies the handle table being queried
Handle - Supplies the handle value being queried
Return Value:
Returns a pointer to the corresponding table entry for the input
handle. Or NULL if the handle value is invalid (i.e., too large
for the tables current allocation.
--*/
{
ULONG_PTR i,j,k;
ULONG_PTR CapturedTable;
ULONG TableLevel;
PHANDLE_TABLE_ENTRY Entry;
typedef HANDLE_TABLE_ENTRY *L1P;
typedef volatile L1P *L2P;
typedef volatile L2P *L3P;
L1P TableLevel1;
L2P TableLevel2;
L3P TableLevel3;
ULONG_PTR RemainingIndex;
ULONG_PTR MaxHandle;
ULONG_PTR Index;
PAGED_CODE();
//
// Extract the handle index
//
Handle.TagBits = 0; // 低2位清零
Index = Handle.Index; // 取31-2位作为句柄表下标
MaxHandle = *(volatile ULONG *) &HandleTable->NextHandleNeedingPool;
//
// See if this can be a valid handle given the table levels.
//
if (Handle.Value >= MaxHandle) {