先从WinDBG中来看下PspCidTable.
lkd> dd pspcidtable
84196eb4 8ae011c8 00000000 80000018 00000101
84196ec4 800005e0 80000020 00000000 00000000
84196ed4 00000000 00000000 00000000 00000113
84196ee4 00000000 00000000 841484e4 00000000
84196ef4 00000000 00000000 00000000 00000008
84196f04 00000000 84196f08 84196f08 00000000
84196f14 00000000 00000000 00000000 00000000
84196f24 00000000 8d703d38 807fed38 00000000
8ae011c8 为PspCidTable指向的句柄表的指针.
用WinDBG中看下句柄表_HANDLE_TABLE的内容.
lkd> dt _handle_table 8ae011c8
nt!_HANDLE_TABLE
+0x000 TableCode : 0x9da23001
+0x004 QuotaProcess : (null)
+0x008 UniqueProcessId : (null)
+0x00c HandleLock : _EX_PUSH_LOCK
+0x010 HandleTableList : _LIST_ENTRY [ 0x8ae011d8 - 0x8ae011d8 ]
+0x018 HandleContentionEvent : _EX_PUSH_LOCK
+0x01c DebugInfo : (null)
+0x020 ExtraInfoPages : 0n0
+0x024 Flags : 1
+0x024 StrictFIFO : 0y1
+0x028 FirstFreeHandle : 0x874
+0x02c LastFreeHandleEntry : 0x8ae045a0 _HANDLE_TABLE_ENTRY
+0x030 HandleCount : 0x3aa
+0x034 NextHandleNeedingPool : 0x1800
+0x038 HandleCountHighWatermark : 0x413
TableCode去掉最后2位掩码后就是指向多层表的指针.
lkd> ? 0x9da23001 & FFFFFFFC
Evaluate expression: -1650315264 = 9da23000
lkd> dd 9da23000
9da23000 8ae04000 9da24000 c838f000 00000000
9da23010 00000000 00000000 00000000 00000000
9da23020 00000000 00000000 00000000 00000000
9da23030 00000000 00000000 00000000 00000000
9da23040 00000000 00000000 00000000 00000000
9da23050 00000000 00000000 00000000 00000000
9da23060 00000000 00000000 00000000 00000000
9da23070 00000000 00000000 00000000 00000000
lkd> dd 8ae04000 8ae04000 00000000 fffffffe 86226021 00000000 8ae04010 86226d49 00000000 86245d49 00000000 8ae04020 86241851 00000000 86245789 00000000 8ae04030 86249c81 00000000 86251639 00000000 8ae04040 86251d49 00000000 86251a71 00000000 8ae04050 86255021 00000000 86255b31 00000000 8ae04060 86255859 00000000 86255581 00000000 8ae04070 8624b021 00000000 8624bd49 00000000
TableCode的后2位指定表的层数,每层表都是由512个_HANDLE_TABLE_ENTRY结构体组成.
lkd> ? 0x9da23001 & 3
Evaluate expression: 1 = 00000001
lkd> dt _HANDLE_TABLE_ENTRY 8ae04000 + 8
nt!_HANDLE_TABLE_ENTRY
+0x000 Object : 0x86226021 Void
+0x000 ObAttributes : 0x86226021
+0x000 InfoTable : 0x86226021 _HANDLE_TABLE_ENTRY_INFO
+0x000 Value : 0x86226021
+0x004 GrantedAccess : 0
+0x004 GrantedAccessIndex : 0
+0x006 CreatorBackTraceIndex : 0
+0x004 NextFreeTableEntry : 0
lkd> ? 0x86226021 &FFFFFFF8
Evaluate expression: -2044567520 = 86226020
lkd> dt _EPROCESS -y Image* -y Flag* 86226020
nt!_EPROCESS
+0x16c ImageFileName : [15] "System"
+0x19c ImagePathHash : 0
+0x26c Flags2 : 0x202d800
+0x270 Flags : 0x14040800
+0x270 ImageNotifyDone : 0y0
如果要获取进程的全路径,可以在下面的偏移处获取.
lkd> dt _EPROCESS -r -y SeA*
nt!_EPROCESS
+0x1ec SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
lkd> dt _SE_AUDIT_PROCESS_CREATION_INFO -r
nt!_SE_AUDIT_PROCESS_CREATION_INFO
+0x000 ImageFileName : Ptr32 _OBJECT_NAME_INFORMATION
+0x000 Name : _UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32 Uint2B
lkd> dt _SE_AUDIT_PROCESS_CREATION_INFO 8898fd40+1ec -r
nt!_SE_AUDIT_PROCESS_CREATION_INFO
+0x000 ImageFileName : 0x88082af0 _OBJECT_NAME_INFORMATION
+0x000 Name : _UNICODE_STRING "\Device\HarddiskVolume2\Windows\System32\taskmgr.exe"
+0x000 Length : 0x68
+0x002 MaximumLength : 0x6a
+0x004 Buffer : 0x88082af8 "\Device\HarddiskVolume2\Windows\System32\taskmgr.exe"
最后贴上我写的遍历代码
NTSTATUS CPspCidTable::EnumPspCidTable()
{
NTSTATUS status = STATUS_SUCCESS;
ULONG ulPspCidTable = 0;
PHANDLE_TABLE pHandleTable = NULL; // 指向句柄表的指针
ulPspCidTable = GetPspCidTableValue();
if ( ulPspCidTable == 0 )
{
return STATUS_UNSUCCESSFUL;
}
pHandleTable = (PHANDLE_TABLE)(*(PULONG)ulPspCidTable);
KdPrint(( "pHandleTable->%p", pHandleTable ));
// 获取循环必须的初始值
ULONG uTableCode = 0;
ULONG uFlag = 0;
uTableCode = (pHandleTable->TableCode) & 0xFFFFFFFC;
uFlag = (pHandleTable->TableCode) & 0x03;
KdPrint(( "uTableCode->%08X", uTableCode ));
switch ( uFlag )
{
case 0:
{
EnumTable1(uTableCode);
break;
}
case 1:
{
EnumTable2(uTableCode);
break;
}
case 2:
{
EnumTable3(uTableCode);
break;
}
}
return status;
}
NTSTATUS CPspCidTable::EnumTable1( ULONG uTableCode )
{
PHANDLE_TABLE_ENTRY pHandleTableEntry = NULL;
pHandleTableEntry = (PHANDLE_TABLE_ENTRY)( (ULONG)(*(PULONG)uTableCode) + 8 );
// KdPrint(( "pHandleTableEntry->%p", pHandleTableEntry ));
// 循环遍历句柄表,循环必须从1开始,跳过第一个HANDLE_TABLE_ENTRY
for ( ULONG uIndex = 1; uIndex < 0x200; uIndex++ )
{
//pHandleTableEntry += uIndex;
if ( pHandleTableEntry->Object != NULL )
{
PEPROCESS pCurEProcess = (PEPROCESS)(((ULONG)pHandleTableEntry->Object) & 0xFFFFFFF8);
//KdPrint(( "pCurEProcess->%p", pCurEProcess ));
// 判断进程是否结束的标记
ULONG flag = (*(PULONG)( (PUCHAR)pCurEProcess + 0x270 ) ) & 0x0C;
// KdPrint(( "flag=%08X", flag ));
// 打印活动进程
if ( *(PUCHAR)(pCurEProcess) == 0x03 && flag != 0x0C )
{
// +0x16c ImageFileName : [15] UChar 进程映像名称,只有15个字节,如果进程名称太长,则被截断.
// +0x1ec SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO 这个结构体中包含进程路径字符串
KdPrint(( "pCurEProcess->%p----%s", pCurEProcess, (PUCHAR)pCurEProcess + 0x16C) );
}
}
pHandleTableEntry++;
//KdPrint(( "pHandleTableEntry->%p", pHandleTableEntry ));
}
return STATUS_SUCCESS;
}
NTSTATUS CPspCidTable::EnumTable2( ULONG uTableCode )
{
do
{
// KdPrint(( "uTableCode->%08X", uTableCode ));
EnumTable1(uTableCode);
uTableCode += 4;
} while ( *(PULONG)uTableCode != 0 );
return STATUS_SUCCESS;
}
NTSTATUS CPspCidTable::EnumTable3( ULONG uTableCode )
{
do
{
EnumTable2(uTableCode);
uTableCode += 4;
} while ( *(PULONG)uTableCode != 0 );
return STATUS_SUCCESS;
}
ULONG CPspCidTable::GetPspCidTableValue()
{
PVOID pPsLookupProcessByProcessIdAddress = NULL;
ULONG ulPspCidTableValue = 0;
UNICODE_STRING ustrFuncName;
// 获取PsLookupProcessByProcessId的函数地址
RtlInitUnicodeString( &ustrFuncName, L"PsLookupProcessByProcessId" );
pPsLookupProcessByProcessIdAddress = MmGetSystemRoutineAddress( &ustrFuncName );
if ( pPsLookupProcessByProcessIdAddress == NULL )
{
return ulPspCidTableValue;
}
KdPrint(( "PsLookupProcessByProcessId->%08X", pPsLookupProcessByProcessIdAddress ));
// 根据特征定位PspCidTable的值.
// Win7系统的定位代码如下:
// 842b5827 8b3db45e1884 mov edi,dword ptr [nt!PspCidTable (84185eb4)]
// 842b582d e8f96efdff call nt!ExMapHandleToPointer (8428c72b)
for ( ULONG uIndex = 0; uIndex < 0x1000; uIndex++ )
{
if ( *( (PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress+ uIndex) ) == 0x8B &&
*( (PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress+ uIndex + 1) ) == 0x3D &&
*( (PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress+ uIndex + 6) ) == 0xE8 )
{
KdPrint(("Found OK!!"));
ulPspCidTableValue = *( (PULONG)((ULONG)pPsLookupProcessByProcessIdAddress+ uIndex + 2) );
break;
}
}
return ulPspCidTableValue;
}