小菜在学习用ExEnumHandleTable遍历PspCidTable,但是遇到问题,我的MyEnumerateHandleRoutine没有被调用过。
http://bbs.pediy.com/showthread.php?p=757603#poststop的朋友也遇到了同样的问题,但是没有得到答案。
完整代码如下(Driver.cpp):
#include<ntddk.h>
typedef struct _HANDLE_TABLE {
PVOID p_hTable;
PEPROCESS QuotaProcess;
PVOID UniqueProcessId;
//EX_PUSH_LOCK HandleTableLock [4];
LIST_ENTRY HandleTableList;
//EX_PUSH_LOCK HandleContentionEvent;
//PHANDLE_TRACE_DEBUG_INFO DebugInfo;
DWORD64 ExtraInfoPages;
DWORD64 FirstFree;
DWORD64 LastFree;
DWORD64 NextHandleNeedingPool;
DWORD64 HandleCount;
DWORD64 Flags;
}HANDLE_TABLE, *PHANDLE_TABLE;
typedef struct _HANDLE_TABLE_ENTRY {
//
// The pointer to the object overloaded with three ob attributes bits in
// the lower order and the high bit to denote locked or unlocked entries
//
union {
PVOID Object;
ULONG ObAttributes;
//PHANDLE_TABLE_ENTRY_INFO InfoTable;
ULONG_PTR Value;
};
//
// This field either contains the granted access mask for the handle or an
// ob variation that also stores the same information. Or in the case of
// a free entry the field stores the index for the next free entry in the
// free list. This is like a FAT chain, and is used instead of pointers
// to make table duplication easier, because the entries can just be
// copied without needing to modify pointers.
//
union {
union {
ACCESS_MASK GrantedAccess;
struct {
USHORT GrantedAccessIndex;
USHORT CreatorBackTraceIndex;
};
};
LONG NextFreeTableEntry;
};
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef BOOLEAN (*EX_ENUMERATE_HANDLE_ROUTINE)(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
);
extern "C" PUCHAR PsGetProcessImageFileName(PEPROCESS EProcess);
extern "C"
NTKERNELAPI BOOLEAN
ExEnumHandleTable (
PHANDLE_TABLE HandleTable,
EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
PVOID EnumParameter,
PHANDLE Handle
);
BOOLEAN MyEnumerateHandleRoutine(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
)
{
DbgPrint("MyEnumerateHandleRoutine\n");
return( true );
//BOOLEAN Result=FALSE;
//ULONG ProcessObject;
//ULONG ObjectType;
// ProcessObject=(HandleTableEntry->Value)&~7; //掩去低三位
//
// ObjectType=*(ULONG*)(ProcessObject-0x10);//取对象类型
//if(ObjectType==(ULONG)PsProcessType)//判断是否为Process
// {
// (*(ULONG*)EnumParameter)++;
// //注意PID其实就是Handle,而 不是从EPROCESS中取,可以对付伪pid
// DbgPrint("PID=%4d\t EPROCESS=0x%08X %s\n",Handle,ProcessObject,PsGetProcessImageFileName((PEPROCESS)ProcessObject));
// }
//return Result;//返回FALSE继续
}
VOID Unload(PDRIVER_OBJECT DriverObject){
DbgPrint("Unload!\n");
}
extern "C"
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload=Unload;
DbgPrint("Load!!\n");
DbgPrint("Address of ExEnumHandleTable:%p MyEnumerateHandleRoutine:%p\n",ExEnumHandleTable,MyEnumerateHandleRoutine);
HANDLE handle;
if(ExEnumHandleTable((PHANDLE_TABLE)0xfffff80004689408,MyEnumerateHandleRoutine,NULL,&handle))
{
DbgPrint("Succeed\n");
}
DbgPrint("Called\n");
return STATUS_SUCCESS;
}
其中PspCidTable的地址是通过Windbg查看符号nt!PspCidTable得到的,在nt!PsLookupProcessByProcessId中也得到了验证。
lkd> uf PsLookupProcessByProcessId
nt!PsLookupProcessByProcessId:
fffff800`047acb7c 48895c2408 mov qword ptr [rsp+8],rbx
fffff800`047acb81 48896c2410 mov qword ptr [rsp+10h],rbp
fffff800`047acb86 4889742418 mov qword ptr [rsp+18h],rsi
fffff800`047acb8b 57 push rdi
fffff800`047acb8c 4154 push r12
fffff800`047acb8e 4155 push r13
fffff800`047acb90 4883ec20 sub rsp,20h
fffff800`047acb94 65488b3c2588010000 mov rdi,qword ptr gs:[188h]
fffff800`047acb9d 4533e4 xor r12d,r12d
fffff800`047acba0 488bea mov rbp,rdx
fffff800`047acba3 66ff8fc4010000 dec word ptr [rdi+1C4h]
fffff800`047acbaa 498bdc mov rbx,r12
fffff800`047acbad 488bd1 mov rdx,rcx
fffff800`047acbb0 488b0d51c8edff mov rcx,qword ptr [nt!PspCidTable (fffff800`04689408)]
我试过其他地址,如果不是一个有效的句柄表就蓝屏了。我虽然没有动态获取它,但每次重启后都会手动修改,运行后没有蓝屏,所以应该没有问题。
编译运行以后输出如下:
00000001 0.00000000 Load!!
00000002 0.00001337 Address of ExEnumHandleTable:FFFFF80004773D74 MyEnumerateHandleRoutine:FFFFF88009964010
00000003 0.00001904 Called
00000004 2.03032207 Unload!
这些地址都是有效的。但是就是我的MyEnumerateHandleRoutine没有内调用。(MyEnumerateHandleRoutine调用DbgPrint打印信息)
我在Win7x64和x86上都遇到同样的问题,所以应该是代码中有问题,不过看网上的代码除了自己遍历的,都是这个样子,还请高人指点,谢谢!
另附一个输出,是查看PspCidTable的,我不太明白UniqueProcessId 为什么是这个样子,难道是一个EPROCESS?但我直接dt _EPROCESS有发现不对:
lkd> dt _HANDLE_TABLE fffff800`04689408
nt!_HANDLE_TABLE
+0x000 TableCode : 0xfffff8a0`000049b0
+0x008 QuotaProcess : 0xffffffff`80000550 _EPROCESS
+0x010 UniqueProcessId : 0xffffffff`80000020 Void
+0x018 HandleLock : _EX_PUSH_LOCK
+0x020 HandleTableList : _LIST_ENTRY [ 0xffffffff`800005e8 - 0xffffffff`80000024 ]
+0x030 HandleContentionEvent : _EX_PUSH_LOCK
+0x038 DebugInfo : 0x00000000`00000113 _HANDLE_TRACE_DEBUG_INFO
+0x040 ExtraInfoPages : 0n0
+0x044 Flags : 0
+0x044 StrictFIFO : 0y0
+0x048 FirstFreeHandle : 0
+0x050 LastFreeHandleEntry : 0xfffff800`045e57c0 _HANDLE_TABLE_ENTRY
+0x058 HandleCount : 0
+0x05c NextHandleNeedingPool : 0
+0x060 HandleCountHighWatermark : 0
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法