探索黑客技术攻防,实战研究与安全创新

导航菜单

基于EPROCESS结构中双向链表的进程检测方法

本文介绍Windows下进程的EPROCESS结构,并针对该结构中的两个双向链表,给出一种检测隐藏进程的方法。

FPROCFSS结构中的双向链表对于VVindows下的每一个进程,系统都会给它分配个excutive process(EPROCESS) block。该结构包含和指向一系列其他相关的数据结构,比如每个进程的所有线程信息。EPROCESS及其所有相关数据结构都位于系统空间。只有Process environmentblock(peb}是位于进程地址空间,因为它包含由用户模式代码所决定的信息。如图1所示。

1.jpg

在Windbg下,我们可以通过dt命令获取EPROCESS的具体格式。



在这个结构中有我们关心的两个数据一个是偏移Ox088处的ActivaProcessLfnks,另一个是偏移OxOc4处的ObjectTable。

顾名思义。ActiveProcessLinks是活动进程链表,从图1中我们可以看出,它的作用就是把一个个的EPROCESS结构链接在一起,它是一个_LIST_ENTRY的结构类型:


FIlink是指向当前节点之后的指针.Blink是指向当前节点之前的指针.LIST_ENTRY是一个双向链表。活动进程可以通过这个链表来遍历,如图2所示。与Act/veProcessLinks不同的是ObjectTable并不是一个双向链表,它指向的是进程的句柄表。而系统内所有这些句柄表结构都是通过'LIST_ENTHY类型的双向链表链接起来的,类似于AetivaProcessLinks将进程链接起来的方式。Obi ectTable是一个_HANDLE_TABLE结构.具体如下。


偏移OxOlc处就是一个类型为_LIST_EixlTRY的HandleTableList.即句柄表链。活动进程也可以通过这个链表遍历,如图3所示。


需要注意的是ObjectTable结构体内偏移Ox008处的UniqueProcessld就是当前EPRoCESS对应进程的ID号。同时,ObjectTable结构体内偏移Ox004处有一个指针OuotaProcess.指向了当前进程的EPROCESS结构(Sytem进程比较特殊,对应的指针为空)。因而,我们不仅能够得到进程的ID号,而且可以获得进程的其他信息。

编写进程检测的驱动程序

上面我们已经弄清楚了EPROCESS结构中的双向链表,接下来看如何编写驱动程序。对于偏移Ox088处的ActiveProcessLinks,我们先通过函数PsGetCurrentProcess获得任意进程的EPflOCESS的地址,该结构偏移Ox084处存放进程lD的指针。读取该指针处的ID作为循环的终止判断条件。到EPROCESS的偏移Ox088处AcfiveProcessLinks中读取当前进程之后的进程的ActiveProcessLinks指针,通过该指针计算其EPROCESS地址。如此循环.即可获得所有活动进程的信息。


对于偏移OxOc4处的ObjectTable,依然是先通过函数PsGetCurrentProcess获得任意进程的EPROCESS地址,进而计算得到ObjectTable的地址。记录当前的ObjectTable地址作为循环终止判断条件。到ObjeczTable中偏移Ox008处获得进程∞,偏移Ox004处CluotaProcess读取EPROCESS地址。经过循环,即可获得所有进程的信息。


由于在Windows XP下System的ObjectTable偏移Ox004处Ou0taProcess为null,是一个异常值.不可读,因而我将其直接置零。另外,通过这个方法无法读取System Process Idle的地址,运行时显示为0。

小结

Windows系统中的EPROCESS结构是一个非常重要的结构,与系统进程、线程管理密切相关。本文为了便于说明,只给出了Windows XP SP2下的具体实现。在Windows 2000和VVindows2003下这个方法也是可行的,但我们‘需要在驱动中判断系统版本,然后给出不同的系统偏移量即可。同时,在EPRCCESS结构中还存在着其他重要的进程特征,通过分析该结构可以找到其他进程检测的方法。