0%
毅种循环

模块 84 - NTDLL 取消挂钩 (Unhooking) - 来自磁盘

恶意软件开发课程 - NTDLL 取消挂钩 (Unhooking) - 来自磁盘


模块 84 - NTDLL 取消挂钩 (Unhooking) - 来自磁盘#

NTDLL 取消挂钩 (Unhooking) - 来自磁盘#

简介#

本模块演示了如何通过使用磁盘上的干净 NTDLL 映像覆盖进程中被挂钩的 NTDLL 的 .text 节来实现 NTDLL 取消挂钩。执行 NTDLL 取消挂钩的具体步骤如下:

  1. 通过读取或映射获取磁盘上干净版本的 NTDLL 句柄。
  2. 提取当前进程中已被挂钩的 NTDLL 句柄。
  3. 提取被挂钩 NTDLL 的 .text 节信息。
  4. 提取干净 NTDLL 的 .text 节信息。
  5. 用干净的 .text 节覆盖被挂钩的 .text 节。

1. 获取干净的 NTDLL#

我们可以通过以下两种方式从磁盘获取干净的 NTDLL:

方法 A:使用 ReadFile API#

使用常规的文件读取 API。需要注意的是,在这种情况下,.text 节的文件偏移量通常为 1024 (0x400)

方法 B:使用内存映射 (Mapping)#

使用 CreateFileMappingMapViewOfFile。这种方式更有优势,因为它利用了操作系统的内存管理机制,且此时 .text 节的对齐偏移量将是 4096 (0x1000)

💡 初学者提示:为什么要选择“映射”而不是“读取”?

类比理解

  • 读取 (ReadFile):就像你找图书馆复印了一整本书带回家。虽然内容一样,但排版页码可能和你桌上那本已打开的书不一致。
  • 映射 (Mapping):就像你向图书馆借了原书,并要求图书馆按你的阅读习惯重新排版映射。使用 SEC_IMAGE_NO_EXECUTE 标志时,它会自动处理好内存对齐,让你能更精准地进行“掉包”操作。

2. 执行核心取消挂钩:覆盖 .text 节#

我们实现了一个通用的函数 ReplaceNtdllTxtSection 来执行替换操作。

3. 处理对齐 Edge Cases(边缘情况)#

📚 知识扩展:处理“异常”对齐

有时即使是 ReadFile 读取,由于 Windows 的优化,其偏移也可能意外地在 4096 边界上。代码中通过检查 .text 节开头的特征操作码(如 0xCC)来动态校验并修正偏移量,确保拷贝的数据始终正确。

总结与风险提示#

从磁盘取消挂钩(Disk Unhooking)虽然强大且易于实现,但也面临以下挑战:

  1. 已知技术:安全厂商(AV/EDR)对这种技术非常熟悉,可能会对修改 ntdll.dll 内存属性的行为进行启发式拦截。
  2. 被监控的文件访问:读取 C:\Windows\System32\ntdll.dll 本身就是一个可疑行为。

在接下来的模块中,我们将探讨更隐蔽的获取方式,如从 KnownDlls挂起进程 中获取干净的映像。