SystemInformer:3 个文件定位 DLL 注入入口与内存监控链路
【免费下载链接】systeminformerA free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars & Solutions, Inc. @ https://windows-internals.com项目地址: https://gitcode.com/GitHub_Trending/sy/systeminformer
从 Process Hacker 升级到 SystemInformer 后,旧版熟悉的注入入口去哪了、内存监控能力落在哪些文件里?本文直接对着仓库源码梳理:协议、封装、驱动能力边界,看 3 个文件就能理清。
📍 能力版图速览:从界面到驱动的 4 层
进程调试与内存监控相关的能力,在 SystemInformer 中不再集中在单个文件里,而是分布在 GUI、封装、协议、内核四层。做内存监控或注入类操作前,不需要通读整个仓库,只需要看懂下面这张映射表:
| 层级 | 关键文件 | 职责 |
|---|---|---|
| GUI 层 | SystemInformer/memedit.c | 进程内存编辑器,内存监控的直接操作入口 |
| GUI 层 | SystemInformer/heapinfo.c | 堆显示与分析,残留早期远程线程代码的注释 |
| phlib 封装层 | phlib/kph.c | 组装并发送消息,按需加载驱动服务 |
| phlib 封装层 | phlib/include/kphcomms.h | ALPC 私有端口收发与回调注册 |
| kphlib 协议层 | kphlib/include/kphmsg.h | 消息 ID 枚举与消息结构体定义 |
| kphlib 协议层 | kphlib/kphmsg.c | 消息初始化与版本校验 |
| 内核驱动层 | KSystemInformer/ | Apc、WorkItem、Dpc 入队等内核原语 |
🔍 关键模块拆解
三个文件各代表一层,按从底到上的顺序看。
从 ksidll.def 导出表看驱动能力边界
.def 导出表是内核驱动最诚实的"功能清单"。
LIBRARY ksi.dll EXPORTS KsiInitialize KsiInsertQueueApc KsiQueueWorkItem KsiInitializeDpc ...KsiInsertQueueApc、KsiQueueWorkItem这类函数就是"向远程线程插入代码执行点"的原语,DLL 注入依赖的正是这一层能力。同时要注意:导出表里没有KsiSendMessage之类的名字,消息通道实际走的是 ALPC 私有端口,所以在仓库里搜这个名字找不到实现。
kphmsg.h 消息表:协议到底能做什么
用户态与内核共享的协议定义,是理解整个通道的钥匙。
typedef enum _KPH_MESSAGE_ID { // // PH -> KPH // KphMsgGetInformerSettings, KphMsgOpenProcess, KphMsgReadVirtualMemory, KphMsgOpenThread, KphMsgTerminateProcess, ... } KPH_MESSAGE_ID, *PKPH_MESSAGE_ID;枚举里每一项对应一种可发给驱动的请求:读写内存、打开进程线程句柄、取栈回溯、结束进程。KPH_MESSAGE结构体用固定头(版本、消息 ID、时间戳)加按方向划分的 union 组织,并用C_ASSERT把 64 位下的大小锁死在 0x4000,防止用户态与内核态两侧结构错位。
phlib/kph.c:把连接建立起来
负责"连得上"这一步,回答了一个常见困惑:功能不可用时先查驱动。
status = KphCommsStart(portName, Config->Callback, Config->RingBufferLength); if (NT_SUCCESS(status) || (status == STATUS_ALREADY_INITIALIZED)) return status; // Load the driver, and try again. if (Config->EnableNativeLoad || Config->EnableFilterLoad) { status = KsiLoadUnloadService(Config, TRUE); ...先尝试连接已在运行的驱动;失败且允许自动加载时,才通过服务机制加载 KSystemInformer 驱动再重试。所以内核相关功能失灵时,第一排查对象就是驱动服务是否驻留。
⚙️ 从源码到操作的调用链
以目前实际在用的内存监控为例,一次操作依次经过四个站点:
- GUI 层:在进程列表选中进程,右键打开内存编辑器,界面逻辑在 SystemInformer/memedit.c
- 封装层:调用 phlib/kph.c 中的
KphReadVirtualMemory(),把目标地址、缓冲区填入KphMsgReadVirtualMemory消息 - 通信层:
KphCommsSendMessage()(声明于 phlib/include/kphcomms.h)把消息经 ALPC 端口发出 - 驱动层:KSystemInformer 在内核态接收并处理,处理逻辑集中在 KSystemInformer/comms_handlers.c
注入侧则不同:ksidll.def已提供"代码插入点"原语,但当前版本的主界面没有现成的注入对话框。搜CreateRemoteThread只能命中 SystemInformer/heapinfo.c 第 1225 行附近的注释残片——早期用户态远程线程路线已被搁置,能力下沉到了驱动。
升级后快速定位入口的排查路径
- 先查驱动服务:所有内核功能以 KSystemInformer 服务驻留为前提。功能无响应时,先在服务管理器确认驱动状态,源码中可用
KphCommsIsConnected()对照判断 - 按函数名追链路:搜
KphMsgReadVirtualMemory(协议定义)→KphReadVirtualMemory(封装)→KphCommsSendMessage(发送)→comms_handlers.c(驱动端处理),换个函数名即可套用,快速摸清任意功能的完整链路 - 用导出表判边界:驱动实际暴露的内核能力以 KSystemInformer/ksidll.def 清单为准。听到的名字若不在表中,说明当前版本没有,不必花时间找入口
想基于 SystemInformer 自建监控或注入工具时,最快路径是先读 kphlib/include/kphmsg.h 吃透协议,再对照ksidll.def确认内核侧实际提供什么,避免在已不存在的入口上空耗。参与代码改进的规范见 CONTRIBUTING.md。
【免费下载链接】systeminformerA free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars & Solutions, Inc. @ https://windows-internals.com项目地址: https://gitcode.com/GitHub_Trending/sy/systeminformer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考