内核态下如何检测EPROCESS结构体与PsLoadedModuleList的篡改?
内核态检测EPROCESS结构体与PsLoadedModuleList篡改的可行方案
核心结论
完全可以在内核态实现针对EPROCESS结构体和PsLoadedModuleList的篡改检测,针对你担心的「首次检测前进程已被隐藏导致初始校验值遗漏」的问题,可通过以下思路解决:
具体实现思路
多源交叉校验,摆脱单一链表依赖
不要仅依赖PsActiveProcessList或PsLoadedModuleList这类易被篡改的链表。比如:- 检测进程时,同时枚举
ObTypeObjectTypes中的进程对象列表、遍历系统句柄表查找进程句柄对应的EPROCESS,或直接调用系统服务表中的NtQuerySystemInformation函数获取进程信息,将多来源结果交叉比对,找出缺失或多余的异常条目。 - 检测内核模块时,对比模块在PEB中的
InLoadOrderModuleList、通过MmGetSystemRoutineAddress反查模块基址,或扫描内核内存中具有PAGE_EXECUTE_READ属性的合法模块页,交叉验证模块的存在性与完整性。
- 检测进程时,同时枚举
动态基准更新,替代静态快照
放弃「一次性生成初始校验值永久比对」的思路,改为动态维护合法基准:- 首次启动检测逻辑时,先通过多源校验确认当前所有进程/模块的合法性——比如验证进程的父进程链、镜像文件签名,模块的数字签名、加载地址是否在合法内核内存范围内。
- 将验证通过的条目加入基准列表,记录其关键哈希值(如EPROCESS核心字段哈希、模块文件SHA256)。
- 后续每次检测时,除了对比基准,还要对新增/消失的条目重新做合法性校验:合法则更新基准,非法则标记为篡改行为。
直接解析物理内存绕过链表篡改
针对高级链表篡改(如直接修改EPROCESS的ActiveProcessLinks指针),可通过解析物理内存直接定位EPROCESS结构体:- 利用内核页表转换机制,将虚拟地址转为物理地址,直接扫描物理内存中的EPROCESS特征(如
ImageFileName固定长度、UniqueProcessId范围),重建完整进程列表后与PsActiveProcessList对比找出差异。
该方法实现难度较高,需适配不同Windows版本的内存布局,但能有效绕过链表层面的篡改。
- 利用内核页表转换机制,将虚拟地址转为物理地址,直接扫描物理内存中的EPROCESS特征(如
结构体完整性与链表一致性检测
- 针对EPROCESS:检查
ActiveProcessLinks双向链表的闭环性,确保每个节点的Flink和Blink指向合法EPROCESS,同时校验UniqueProcessId、ImageFileName、ExitStatus等关键字段的合理性。 - 针对PsLoadedModuleList:检查每个
LDR_DATA_TABLE_ENTRY的链表指针一致性,同时计算模块文件哈希值,与预先存储的合法内核模块哈希库比对,检测篡改或注入的恶意模块。
- 针对EPROCESS:检查
额外注意事项
- 检测逻辑自身需具备反hook能力:比如将检测代码放置在非可写内存区域,定期校验自身代码段哈希,避免被恶意代码hook篡改。
- 需适配不同Windows版本的内核结构差异:EPROCESS和
LDR_DATA_TABLE_ENTRY的字段偏移随系统版本变化,可通过动态获取偏移(如导出符号、特征扫描)保证兼容性。
内容的提问来源于stack exchange,提问作者OssieFromDK
相关产品推荐
相关产品推荐

