SystemInformer DLL注入全链路拆解:从菜单入口到内核消息的三层实现
2026/9/11 23:29:28 网站建设 项目流程

SystemInformer 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

右键菜单里那个熟悉的"注入DLL"选项,升级之后找不到了?你不是一个人。SystemInformer 的 DLL注入能力一直在代码库里挪窝,翻旧教程只会越看越晕。这篇不讲故事,直接把整条链路拆成三层——入口、通信、内核——看完你在任何版本里都能顺着文件路径快速定位。

入口找不到了?先把链路拆开

先说结论:SystemInformer 的 DLL注入主体活在用户态,它只是把"把路径搬进对方内存、借对方的 LoadLibraryW 跑起来"这套活编排好;真正需要内核出手的,是操作受保护进程时的特权内存读写。把这件事按"谁动手"分成三层,你就不会迷路。📌

SystemInformer DLL注入三层架构全景

下面这张图是全文地图,后文按层展开,每个节点对应一个具体文件。

三层职责一句话讲清:入口层负责"发起注入",通信层负责"把普通 API 变成特权操作",内核驱动负责"替你在受保护进程里动内存"。三者是串联关系,不是并列。

逐层拆解注入链路

界面层——你点的那一下到底调了什么

入口就在 phlib/nativethread.c 的PhLoadDllProcess(远程线程版)和PhLoadDllProcessApcThread(APC 版)。你点的那一下,最终落到这两个函数。核心三步如下:

// 解析目标进程自己 kernel32 的 LoadLibraryW 地址 PhGetProcedureAddressRemote(ProcessHandle, &kernel32, "LoadLibraryW", &loadLibraryW, NULL); // 把 DLL 路径(宽字符)写进目标进程内存 PhWriteVirtualMemory(ProcessHandle, fileNameBaseAddress, FileName->Buffer, len, NULL); // 以 LoadLibraryW 为入口、路径为参数,远程拉起一个线程 PhCreateUserThread(ProcessHandle, NULL, THREAD_ALL_ACCESS, 0,0,0,0, loadLibraryW, fileNameBaseAddress, &threadHandle, NULL);

说白了就是经典 LoadLibraryW 远程线程套路:地址、路径、线程一个不少;APC 版则把"拉线程"换成"往对方线程队列塞 APC",更不易被察觉。旧版CreateRemoteThread的痕迹还躺在 SystemInformer/heapinfo.c(已注释),仅供对照。界面层只负责把参数打包传下去,真正的活是下一层干的。

通信层——用户态和内核之间怎么传话

别被一堆 KPH 缩写吓到,这层其实就干一件事:把一次系统调用封装成结构体,走命名端口发给驱动。发送逻辑在 phlib/kph.c(KphSendMessage+KPH_PORT_NAME),报文结构在 kphlib/include/kphmsgdefs.h。以内存读为例:

typedef struct _KPHM_READ_VIRTUAL_MEMORY { NTSTATUS Status; // 返回码, 调用方据此判断成败 HANDLE ProcessHandle; // 操作哪个进程 PVOID BaseAddress; // 读哪段地址 PVOID Buffer; // 结果落到哪 SIZE_T BufferSize; // 读多少 PSIZE_T NumberOfBytesRead;// 实际读到多少 } KPHM_READ_VIRTUAL_MEMORY, *PKPHM_READ_VIRTUAL_MEMORY;

这个结构体本质上就是个"消息头+参数",写内存版KPHM_WRITE_VIRTUAL_MEMORY字段同理。普通进程走系统自带 API 就够;一旦目标是受保护进程,PhWriteVirtualMemory会自动改走这条端口,把活转给内核。消息打包好了,但谁来执行?看内核层。

内核层——驱动里真正动手的地方

内核侧是 KSystemInformer/ 驱动;它调用 KSystemInformer/ksidll.c 提供的特权原语(安全卸载 APC、工作项、DPC、最小系统进程)。ksidll.def 的导出表就是这层的"手":

LIBRARY ksi.dll EXPORTS KsiInitialize KsiInitializeApc KsiInsertQueueApc KsiInitializeWorkItem KsiQueueWorkItem KsiInitializeDpc KsiInitializeSystemProcess

这些导出不是注入 API 本身,而是让驱动能"安全地在系统里动手"的底层积木:比如保证驱动卸载时未完成的 APC 仍能收尾。注入时受保护进程的内存读写,就是由这一层代为执行。🔍

功能点文件位置速查表

功能点所在模块关键文件备注
注入入口(远程线程/APC)用户态 phlibphlib/nativethread.cPhLoadDllProcess / ApcThread
端口消息发送用户态 phlibphlib/kph.cKphSendMessage、KPH_PORT_NAME
消息结构体定义kphlibkphlib/include/kphmsgdefs.hKPHM_READ/WRITE_VIRTUAL_MEMORY
特权内存/进程操作内核驱动KSystemInformer/驱动内处理 KPH 消息
内核原语(APC/DPC/工作项)内核驱动KSystemInformer/ksidll.c见 ksidll.def 导出表
旧版 CreateRemoteThread 痕迹主程序SystemInformer/heapinfo.c已注释,仅供对照

找不到入口先查这张表,比翻代码快。

动手跑一遍注入

  1. 启动 SystemInformer,在进程列表里选中目标进程。
  2. 打开该进程的操作入口(上下文菜单/动作),选择 DLL 注入。
  3. 选中要注入的 .dll 文件并确认。
  4. 触发后走PhLoadDllProcess:解析地址 → 写路径 → 拉远程线程 → 等待返回。
  5. 若目标受保护,内存读写会自动改走 KPH 端口到内核驱动执行。

如果界面和文中对不上,回到第四节查表。

边界与坑

主要面向现代 Windows(x64/x86);操作受保护进程需要管理员/提升权限。最常见的坑:目标 32/64 位或运行时库地址不匹配导致 LoadLibraryW 解析失败,或注入线程等待超时卡住。要动手改的话,先看 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询