文章作者:grayfox
作者主页:http://nokyo.blogbus.com
原始出处:http://nokyo.blogbus.com/logs/33636725.html
此前我们曾经介绍过不少枚举进程的方法,现在我们来到了ring0这一层,肯定是想玩点与ring3不同的东西。 今天我们就介绍一种通过EPROCESS链表来枚举系统进程的方法。
但凡是系统编程玩的比较久的人,都应该听说过EPROCESS这个结构吧,传说中它是一个双向链表,其中存储着我们感兴趣的系统所有进程信息。我们既然已经来到了ring0,不妨尝试着直接读取这个链表,这是否可行呢?
事实证明,这是完全可行的,下面我就发一段看雪的北极星2003大哥写的程序,测试通过。下面再顺便测试一下“代码发芽网”的BLOG贴代码功能。
ULONG
GetPlantformDependentInfo(
ULONG dwFlag
)
{
ULONG current_build;
ULONG ans = 0;
PsGetVersion(NULL, NULL, ¤t_build, NULL);
switch ( dwFlag )
{
case EPROCESS_SIZE:
if (current_build == 2195) ans = 0 ; // 2000,当前不支持2000,下同
if (current_build == 2600) ans = 0x25C; // xp
if (current_build == 3790) ans = 0x270; // 2003
break;
case PEB_OFFSET:
if (current_build == 2195) ans = 0;
if (current_build == 2600) ans = 0x1b0;
if (current_build == 3790) ans = 0x1a0;
break;
case FILE_NAME_OFFSET:
if (current_build == 2195) ans = 0;
if (current_build == 2600) ans = 0x174;
if (current_build == 3790) ans = 0x164;
break;
case PROCESS_LINK_OFFSET:
if (current_build == 2195) ans = 0;
if (current_build == 2600) ans = 0x088;
if (current_build == 3790) ans = 0x098;
break;
case PROCESS_ID_OFFSET:
if (current_build == 2195) ans = 0;
if (current_build == 2600) ans = 0x084;
if (current_build == 3790) ans = 0x094;
break;
case EXIT_TIME_OFFSET:
if (current_build == 2195) ans = 0;
if (current_build == 2600) ans = 0x078;
if (current_build == 3790) ans = 0x088;
break;
}
return ans;
}
VOID
EnumProcessList()
{
PROCESS_INFO ProcessInfo = {0};
ULONG EProcess;
ULONG FirstProcess;
ULONG dwCount = 0;
LIST_ENTRY* ActiveProcessLinks;
ULONG dwPIdOffset = GetPlantformDependentInfo(PROCESS_ID_OFFSET);
ULONG dwPNameOffset = GetPlantformDependentInfo(FILE_NAME_OFFSET);
ULONG dwPLinkOffset = GetPlantformDependentInfo(PROCESS_LINK_OFFSET);
KdPrint(("We Use EPROCESS Links!"));
KdPrint(("PidOff=0x%X NameOff=0x%X LinkOff=0x%X", dwPIdOffset, dwPNameOffset, dwPLinkOffset));
// 获取当前进程的地址
FirstProcess = EProcess = (ULONG)PsGetCurrentProcess();
do
{
ProcessInfo.ProcessId = *((ULONG *)(EProcess + dwPIdOffset));
ProcessInfo.ImageFileName = (PUCHAR)(EProcess + dwPNameOffset);
dwCount++;
KdPrint(("[Pid=%6d] %s
", ProcessInfo.ProcessId, ProcessInfo.ImageFileName));
ActiveProcessLinks = (LIST_ENTRY *)(EProcess + dwPLinkOffset);
EProcess = (ULONG)ActiveProcessLinks->Flink - dwPLinkOffset;
if (EProcess == FirstProcess)
{
break;
}
}while (EProcess != 0);
KdPrint(("ProcessCount = %d", dwCount));
}