看Windows内核情景分析的时候看到讲PspCidTable中会保存每个进程和线程的CID,就在想可以通过这个表来获取到每个进程的PID及相关信息,然后网上一搜,已经有N多人通过这种方法来获取进程列表了,Iceword也是有这种方法来枚举进程的。Anyway,还是自己实现一遍吧。当然也借鉴了别人的代码。
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
HANDLE h;
DbgPrint("DriverEntry/n");
DriverObject->DriverUnload = DrvUnload;
ExEnumHandleTable = (EXENUMHANDLETABLE)GetFunctionAddr(L"ExEnumHandleTable");
if(ExEnumHandleTable == NULL )
{
DbgPrint("Get ExEnumHandleTable Address Error/n");
return STATUS_SUCCESS;
}
DbgPrint("Address of ExEnumHandleTable:%x/n", ExEnumHandleTable);
GetPspCidTable();
DbgPrint("CidTable:%x/n", pPspCidTable);
ExEnumHandleTable(pPspCidTable, ExEnumHandleCallBack, NULL, &h);
return STATUS_SUCCESS;
}void GetPspCidTable( )
{
PUCHAR cPtr;
DWORD PsAddr = GetFunctionAddr(L"PsLookupProcessByProcessId");
for(cPtr = (PUCHAR)PsAddr;
cPtr < (PUCHAR)PsAddr + PAGE_SIZE; cPtr++)
{
if(*(PUSHORT)cPtr == 0x35FF)
{
pPspCidTable = **(PVOID**)(cPtr+2);
break;
}
}
}BOOLEAN ExEnumHandleCallBack(PHANDLE_TABLE_ENTRY HandleTableEntry, HANDLE Handle, PVOID EnumParameter)
{
NTSTATUS ntStatus;
HANDLE Cid;
PEPROCESS Process;
ULONG uTableCount;
ULONG uTablePage = 0;
if(EnumParameter == HandleTableEntry)
{
return TRUE;
}
else
{
for(uTableCount = 0; uTableCount < 0x1000; uTableCount++)
{
if(HandleTableEntry->Object)
{
Cid = (HANDLE)((1024*uTablePage)+(uTableCount<<2));
if(Cid > (PVOID)4)
{
ntStatus = PsLookupProcessByProcessId(Cid, &Process);
if(NT_SUCCESS(ntStatus))
{
DbgPrint("PID:%4d/tProcess Name:%-16s/n",
Cid, ((PUCHAR)Process+EPROC_NAME_OFFSET));
ObDereferenceObject(Process);
}
}
else
{
if(Cid == 0)
{
DbgPrint("PID:%4d/tProcess Name:Idle/n", 0);
}
else
{
DbgPrint("PID:%4d/tProcess Name:System/n", 4);
}
}
}
}
uTablePage++;
return TRUE;
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/strongxu/archive/2009/12/07/4959757.aspx