本帖最后由 xiaoly99 于 2014-7-10 20:41 编辑
VB小子玩转驱动程序(5):用PspCidTable枚举进程
作者:0.0
1.获取PspCidTable地址
可以根据ntoskrnl.exe导出函数PsLookupProcessByProcessId获得
lkd> u PsLookupProcessByProcessId l 10
nt!PsLookupProcessByProcessId:
805ca448 8bff mov edi,edi
805ca44a 55 push ebp
805ca44b 8bec mov ebp,esp
805ca44d 53 push ebx
805ca44e 56 push esi
805ca44f 64a124010000 mov eax,dword ptr fs:[00000124h]
805ca455 ff7508 push dword ptr [ebp+8]
805ca458 8bf0 mov esi,eax
805ca45a ff8ed4000000 dec dword ptr [esi+0D4h]
805ca460 ff35e0b25580 push dword ptr [nt!PspCidTable (8055b2e0)]
805ca466 e869b50300 call nt!ExMapHandleToPointer (806059d4)
805ca46b 8bd8 mov ebx,eax
805ca46d 85db test ebx,ebx
805ca46f c745080d0000c0 mov dword ptr [ebp+8],0C000000Dh
805ca476 7432 je nt!PsLookupProcessByProcessId+0x62 (805ca4aa)
805ca478 57 push edi
特征码是FF35########
小知识:为什么是8个#呢?因为一个Long占8个字节,而指针只占4个字节,我用RtlCopyMemory(&目标Long,源Long,4),其中的4是指针长度4个字节,而Long实际占用8个字节
2.PspCidTable简介
PspCidTable是特殊的句柄表,它的地址指向一个_HANDLE_TABLE的结构:
lkd> dt _HANDLE_TABLE
nt!_HANDLE_TABLE
+0x000 TableCode : Uint4B 小提示
+0x004 QuotaProcess : Ptr32 _EPROCESS
+0x008 UniqueProcessId : Ptr32 Void
+0x00c HandleTableLock : [4] _EX_PUSH_LOCK
+0x01c HandleTableList : _LIST_ENTRY
+0x024 HandleContentionEvent : _EX_PUSH_LOCK
+0x028 DebugInfo : Ptr32 _HANDLE_TRACE_DEBUG_INFO
+0x02c ExtraInfoPages : Int4B
+0x030 FirstFree : Uint4B
+0x034 LastFree : Uint4B
+0x038 NextHandleNeedingPool : Uint4B
+0x03c HandleCount : Int4B
+0x040 Flags : Uint4B
+0x040 StrictFIFO : Pos 0, 1 Bit
小提示
取TableCode后两位,获得有几层表,VB代码
Public Function GetTable(Byval gPspCidTable As Long) As Long
Dim TableCode As String
TableCode = Hex(GetTableCode(gPspCidTable)) '硬类型转换
TableCode = Right(TableCode,2) '取后两位
Select TableCode
Case "00"
GetTable = 1
Case "01"
GetTable = 2
Case "10"
GetTable = 3
End Select
End Sub
3.PspCidTable应用
获取EProcess
对于 PID<2048 的查其一层表: ReadMemory(Table1Base + 2 * PID) Or &H80000000 And &HFFFFFFF8
对于 PID>=2048 的查其二层表: ReadMemory(Table2Base + 2 * (PID - 2048)) Or &H80000000 And &HFFFFFFF8
VB源代码
Private Table1Base As Long,Table2Base As Long
Public Function GetEProcessByProcess(Byval ProcessID As Long) As Long
Table1Base = ReadMemory(ReadMemory(ReadMemory(GetPspCidTable)) - 1)
Table2Base = ReadMemory(ReadMemory(ReadMemory(GetPspCidTable)) - 1 + 4)
If ProcessID < 2048 Then
GetEProcessByProcess = ReadMemory(Table1Base + 2 * ProcessID) Or &H80000000 And &HFFFFFFF8
Else
GetEProcessByProcess = ReadMemory(Table2Base + 2 * (ProcessID - 2048)) Or &H80000000 And &HFFFFFFF8
End If
End Function
Public Function GetPspCidTable() As Long
GetPspCidTable = ReadMemory(ReadMemory(&HFFDFF034) + 128)
End Function
Public Sub PspEnumProcess() '枚举进程
Dim tEProcess As Long
For a = 1 to 5120
tEProcess = GetEProcessByProcess(a)
if tEProcess <> 0 Then
frmMain.lstProcess.Add tEProcess & "/" & a'添加列表
Next
End Sub
|