|
“正规”的枚举方法应该是ExEnumHandleTable,虽然这货是导出函数,但是在xp~win7和win8+上有很大不同,比如:函数原型:
- NTKERNELAPI BOOLEAN ExEnumHandleTable(
- IN PVOID HandleTable,
- IN PVOID EnumHandleProcedure,
- IN PVOID EnumParameter,
- OUT PHANDLE Handle
- );
复制代码
xp~win7 :
- BOOLEAN (*EnumHandleProcedure)(
- IN PHANDLE_TABLE_ENTRY HandleTableEntry,
- IN HANDLE Handle,
- IN PVOID EnumParameter
- )
复制代码
win8+:
- BOOLEAN (*EnumHandleProcedure)(
- IN PVOID HandleTable,
- IN PHANDLE_TABLE_ENTRY HandleTableEntry,
- IN HANDLE Handle,
- IN PVOID EnumParameter
- )
复制代码
下面坑爹来了:
在ExEnumHandleTable之前需要PsAcquireProcessExitSynchronization,之后需要PsReleaseProcessExitSynchronization,看过wrk大家都知道,demo...
xp下PsAcquireProcessExitSynchronization并不导出,需要你自己实现PsAcquireProcessExitSynchronization,这个函数很简单,里面只有一个ExAcquireRundownProtection(&Process->RundownProtection)
这时候就要强行弄一个RundownProtection的偏移了(xp是0x80,别的系统不知道)。
而vista以上就很舒服了,有一个导出函数叫ObReferenceProcessHandleTable,你懂的,可以直接代替自己用恶心的(Process + HandleTableOffset)偏移定位句柄表的过程(然而processhacker2还是用偏移定位了)。
下面更坑爹的来了:
你以为只要在EnumHandleProcedure回调里面随便写写就够了?错了!WIN8以上的EnumHandleProcedure的HandleTableEntry是加了锁的!
你需要在对entry干完活之后ObpUnlockHandleTableEntry,这个ObpUnlockHandleTableEntry也得你自己实现(因为ntos里的都被inline了),总的来说就是:
InterlockedExchangeAdd(&HandleTableEntry->u1.VolatileLowValue, 1);
ExfUnblockPushLock(&handleTable->HandleContentionEvent, NULL);(其实IDA一下你就知道了)
但是。。这俩结构也是不公开的,也得你自己根据系统来写offset。
processhacker2的做法是直接每个系统写死offset,win64ast据说不是用ExEnumHandleTable枚举的句柄所以不是很清楚。
下面更更更更坑爹的来了:
WIN8+的HandleTableEntry里有个ObjectPointerBits(结构见http://www.m5home.com/bbs/thread-8847-1-1.html),这货解压之后其实并不是Object,而是ObjectHeader(也就是Object - 12 or -24)
好了,三个坑说完了,剩下的实现就是体力活了,完整代码见https://github.com/processhacker2/processhacker/blob/f525b448d9289b5c64173326c142611651d386dc/KProcessHacker/object.c
(逃 |
|