文章总结: 本文阐述内存取证前需掌握的Windows进程核心概念,重点解析EPROCESS与PEB结构。文章揭示了Volatility插件如pslist依赖ActiveProcessLinks双向链表遍历进程的原理,并通过内核调试器演示了具体的链表遍历步骤。掌握这些底层机制有助于分析人员深入理解内存转储数据,提升取证分析能力。 综合评分: 88 文章分类: 应急响应,逆向分析,二进制安全
Windows 进程内部原理:内存取证前必须掌握的几个核心概念
imp hash imp hash
securitainment
2026年3月26日 13:37 中国香港
| 原文链接 | 作者 | | — | — | | https://imphash.medium.com/windows-process-internals-a-few-concepts-to-know-before-jumping-on-memory-forensics-823d72d4d7b8 | imp hash |
最近在复习内存取证时,我意识到有一些 Windows 内部机制中的重要概念,必须从内存取证的视角加以理解,这样才能真正消化相关知识,而不是仅仅对内存转储跑一遍工具了事。尽管 Windows 内部机制方面的资料已经非常丰富,本文仍着重提供在内存取证语境下理解 Windows 进程内部机制所需的核心概念。
Volatility 中的 pslist、pstree、psxview、dlllist、ldrmodules、hollowfind、getsids、handles 等插件,都依赖于几个关键的进程相关数据结构,例如 EPROCESS、进程环境块 (PEB)、虚拟地址描述符 (VAD) 等。这些模块会解析这些结构及其内部的子结构,最终为我们呈现出清晰的表格视图以供分析。
下表展示了部分 Volatility 模块与数据结构之间的对应关系。该列表并不全面,仅用于说明 Volatility 插件与数据结构之间的映射。
表 1. Volatility 插件与操作系统数据结构的映射
今天我们将重点讨论 EPROCESS和 Process Environment Block (PEB),因为许多模块的功能都依赖于这两个关键数据结构中存储的信息。
什么是 EPROCESS 和进程环境块?
每个 Windows 进程都由一个名为 _EPROCESS的执行体进程结构来表示。_EPROCESS包含大量与进程相关的属性,同时还指向若干其他相关的数据结构。
进程环境块 (PEB)是 EPROCESS 所指向的结构之一。PEB 中保存了许多与进程相关的信息,包括映像名称、已加载的模块 (DLL)、映像文件路径、进程启动时传入的命令行参数等。
EPROCESS 数据结构中有一个重要字段 ActiveProcessLinks,它是一个指向循环双向链表的指针,用于跟踪系统中所有活动进程。pslist等模块正是利用这个指针,沿着链表逐一遍历,从而获取所有活动进程的列表。
下面通过 Windows 内核调试器 (kd) 来查看 _EPROCESS数据结构。dt命令用于查看组成结构的各个字段,而这些字段又会指向其他数据结构。要查看 _EPROCESS的结构定义,可在内核调试器中输入以下命令:
dt nt!_EPROCESS
该命令将显示 _EPROCESS数据结构的完整定义,包括其中所有字段。
请参见下方截图。可以看到,其中许多字段又指向了另一个数据结构。例如,pcb(进程控制块) 对应的是 _KPROCESS结构,可以在调试器中输入 dt nt!_KPROCESS来查看。
我们将重点关注 ActiveProcessLinks字段。请查看下方显示该字段的截图——它是一个 LIST_ENTRY结构。请注意该字段相对于 _EPROCESS结构起始位置的偏移量 (0x2f0),后文将会用到这个偏移量。
内核使用双向链表来跟踪进程。每个进程的 EPROCESS 中都包含这样一个双向链表节点,由前一个进程的 ActiveProcessLinks 字段指向。所有 EPROCESS 块通过双向链表以循环方式相互连接。因此,遍历这条链表即可获取系统中所有活动进程。
ActiveProcessLinks 是一个 LIST_ENTRY 结构,作为循环双向链表的一个节点,指向下一个进程对应的 EPROCESS 结构。
图 1. _EPROCESS 结构与 ActiveProcessLinks 字段
EPROCESS 结构中还有其他字段值得关注。在内存取证的语境下,PEB 和 VAD 也是非常重要的结构。请参见以下截图。
图 2. _EPROCESS 中 PEB 相关的重要字段
图 3. _EPROCESS 中 VAD 相关的字段
pslist 是如何获取所有当前进程列表的?
其核心原理是通过遍历双向链表来获取所有活动进程。
方法 1:
!PsActiveProcessHead是指向 System 进程 (即系统中第一个进程) 的 EPROCESS 中 ActiveProcessLinks 双向链表的指针。只要获取到双向链表中任意一个节点的指针,就可以沿着链表遍历所有活动进程。
具体步骤如下:
步骤 1.使用 nt!PsActiveProcessHead获取双向链表的指针
步骤 2.列出该指针所指向进程的 ActiveProcessLinks 实例
图 4. 步骤 1 和 2:nt!PsActiveProcessHead
步骤 3.该指针的 Flink条目指向下一个进程 _EPROCESS结构中的 ActiveProcessLinks字段。如果要访问该 _EPROCESS结构中的其他字段,需要定位到 _EPROCESS的起始位置,而非 ActiveProcessLinks所在位置。因此,需要将指针减去偏移量 (0x2f0),才能得到 _EPROCESS的起始地址。
图 5. 步骤 3:定位到下一个 _EPROCESS 并读取字段
步骤 4.到达 _EPROCESS起始位置后,就可以访问该结构中的任意字段。这里我们选择读取 ImageFileName。可以看到,System进程指向的下一个进程是 Registry。
图 6. 遍历到下一个节点
步骤 5.接下来,利用调试器的列表遍历功能来遍历整个链表。所用地址为指针减去偏移量 (?0xffff858a'3f6db5f0-0x2f0),以定位到 _EPROCESS的起始地址。
图 7. 遍历链表并获取所有当前进程
方法 2:
遍历进程列表的另一种方式是选取任意一个进程,找到它在循环双向链表中的指针,然后沿着链表遍历。
步骤 1:列出所有进程,任意选取一个以获取其双向链表节点的指针。该进程 EPROCESS结构中的 ActiveProcessLinks字段即为我们所需的链表指针。请参见下方截图。
图 8. 列出当前进程并任意选取一个
步骤 2:列出所选进程 _EPROCESS结构中 ActiveProcessLinks字段的 Flink值。
图 9. 查看所选进程 ActiveProcessLinks 的 Flink
步骤 3.Flink指向下一个进程的 ActiveProcessLinks。因此需要减去偏移量 (与前面相同的操作),即可定位到下一个进程 EPROCESS块的起始位置。
利用列表遍历功能,可以遍历所有进程,如下所示。
图 10. 遍历链表并获取所有当前进程
还有一些其他重要的字段和结构,如 !peb、lpeb_ldr_data、!ldr_data_table_entry、!vad 等,也值得深入理解。我将在后续文章中介绍这些结构。
如果你希望了解其余重要数据结构的详解,请告诉我。
今天就到这里,各位!祝狩猎愉快!
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:securitainment imp hash imp hash《Windows 进程内部原理:内存取证前必须掌握的几个核心概念》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论