☰
Windows 驱动实例分析系列:injdrv 驱动分析 - src篇(四)
2026/10/11 1:37:55 网站建设 项目流程

子文档 4:高级注入技法(Thunkless + Reparse)

1. Thunkless 方法(InjpInjectX64NoThunk)

此方法仅当InjMethodThunkless且编译为 x64 时启用。代码位于injlib.c中。

它不再分配可执行 shellcode,而是将用户 APC 的NormalRoutine直接设定为InjectionInfo->LdrLoadDllRoutineAddress(即 x64ntdll.dll中的LdrLoadDll地址)。参数传递:

  • NormalContext = NULL
  • SystemArgument1 = NULL
  • SystemArgument2 = DllPath(指向在用户空间分配的UNICODE_STRING)

关键设计是利用 x64 的KiUserApcDispatcher行为:

  • 该函数在调用NormalRoutine前,会将RSP(指向CONTEXT结构)放入R9。
  • 在 x64 调用约定中,R9是第 4 个参数寄存器。
  • 因此LdrLoadDll被调用时,隐含的第 4 个参数BaseAddress指向了CONTEXT结构。
  • LdrLoadDll写入BaseAddress时,会覆写CONTEXT.P1Home,而该字段在 APC 分发后续流程(调用ZwContinue前)不再被使用,因此安全。

这种方法的精妙之处在于零可执行内存分配,完美绕过 CFG 针对低 4GB 地址的执行限制。

2. Reparse 微过滤器(src/injlib/reparse.c)

该文件约 400 行,实现了基于 Minifilter 的文件路径重解析。其入口为SimRepInitialize,但此函数并非由DriverEntry直接调用,而是在InjInitialize中判断InjMethod == InjMethodWow64LogReparse时调用。

SimRepInitialize做了两件重要的事:

  1. 注册表注入:通过SimRepInitializeRegistry在驱动服务项下创建Instances\Reparse键,写入Altitude = "370040"和Flags = 0。这使得fltmgr能加载该过滤器。
  2. FltRegisterFilter:注册FLT_REGISTRATION,其中InstanceSetup、InstanceQueryTeardown被简单实现(直接返回成功),而OperationRegistration仅针对IRP_MJ_CREATE注册了预处理回调SimRepPreCreate。

3. SimRepPreCreate 的重解析逻辑

每次文件打开时,此回调会获取FLT_FILE_NAME_INFORMATION。它调用SimRepCompareMapping检查路径是否以\Windows\System32\wow64log.dll结尾。若是,则调用SimRepMungeName构造新路径。

SimRepMungeName会分配新缓冲区,将旧路径中的wow64log.dll替换为NewName(即injdll的路径)。注意,NewName在SimRepInitialize中被初始化为InjDllPath[InjArchitectureNative].Buffer + 2,加 2 是为了跳过盘符前缀(如C:),保留\Windows\...部分。

最后,调用IoReplaceFileObjectName直接替换FILE_OBJECT中的名称,并返回STATUS_REPARSE给 I/O 管理器。I/O 管理器收到STATUS_REPARSE后会重新发起打开请求,此时路径已被替换,从而加载了 injdll。

4. 为什么不直接用符号链接?

符号链接作用于命名空间层级,而此处需要精确拦截特定 DLL 的加载路径。使用 Minifilter 可以做到进程级别的精准拦截,且不污染全局命名空间。此外,IoReplaceFileObjectName直接修改FILE_OBJECT是内核态特有的“偷梁换柱”手段,用户态无法实现。


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

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

立即咨询