子文档 6:用户态加载器与 ETW 控制台(src/injldr/main.c + install.c)
injldr.exe是用户态控制进程,兼顾驱动安装/卸载和 ETW 日志消费。
1. 服务安装与卸载(install.c)
ManageDriver封装了对 SCM(服务控制管理器)的操作。
DRIVER_FUNC_INSTALL:调用CreateService创建SERVICE_KERNEL_DRIVER,类型为SERVICE_DEMAND_START(手动启动)。随后调用StartService启动驱动。DRIVER_FUNC_REMOVE:先调用ControlService发送SERVICE_CONTROL_STOP停止驱动,再调用DeleteService标记删除。
SetupDriverName通过GetCurrentDirectory获取当前路径,并拼接DRIVER_NAME ".sys",确保安装时指向正确的驱动文件。
2. ETW 实时会话管理(main.c)
TraceStart函数构建EVENT_TRACE_PROPERTIES,设置LogFileMode = PROCESS_TRACE_MODE_REAL_TIME,调用StartTrace创建名为"InjSession"的跟踪会话。随后调用EnableTrace(TRUE, 0, 0, &ProviderGuid, TraceSessionHandle)启用我们自定义的 Provider。
然后初始化EVENT_TRACE_LOGFILE,指定LoggerName = SessionName,ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_REAL_TIME,回调函数为TraceEventCallback。调用OpenTrace打开句柄,最后调用ProcessTrace进入事件循环。该调用会阻塞当前线程,直到Ctrl+C中断或CloseTrace被调用。
3. 事件回调与命令行交互
TraceEventCallback简单地检查EventRecord->UserData,将其视为宽字符串并用wprintf输出进程 ID、线程 ID 和消息。
main函数首先注册SetConsoleCtrlHandler捕获CTRL_C_EVENT。当按下Ctrl+C时,CtrlCHandlerRoutine调用TraceStop(内部调用StopTrace)清理会话,随后进程退出。
4. 命令行参数解析
- 无参数:直接进入 ETW 监听(假设驱动已由其他方式加载)。
-i:调用DoInstallUninstall(TRUE)安装并启动驱动,然后进入监听。-u:调用DoInstallUninstall(FALSE)停止并卸载驱动,直接返回。
5. 运行时的注意事项
由于驱动需要测试签名,README中提示需开启bcdedit /set testsigning on。injldr在启动驱动前不会检查签名状态,若未开启,StartService会返回错误码0xC0000428(无法验证数字签名),此时应提示用户开启测试模式。
总结
通过对 6 个子文档的逐步展开,我们完整覆盖了 injdrv 从内核态驱动入口、状态机管理、APC 编排、高级注入技巧,到用户态载荷的自隐藏与 ETW 通信,再到用户态控制器的安装与日志消费的全部源码链路。整个项目代码风格干净利落,宏与条件编译运用恰当,抽象层次分明,是学习 Windows 底层进程注入与内核交互不可多得的范本。希望本“src 篇”能帮助读者建立起从代码到运行的完整心智模型。