从最容易被检测的用户态 Hook,到理论上无法被静态发现的 Hypervisor 级 Hook,按隐蔽性从低到高排列。每种技术均提供完整可编译的实现代码。
用户态 Hook 是最基础的拦截手段,所有代码运行在应用层,任何反作弊/安全软件只要扫描进程内存就能发现。隐蔽性最低,但开发成本也最低。
PE 文件加载时,Loader 会填充 IAT(Import Address Table),记录每个导入函数的实际地址。IAT Hook 直接修改这张表里的函数指针,让程序调用时跳到你的函数。
遍历 IAT,对比每个条目是否指向对应 DLL 的地址范围内即可发现。CRC 校验 IAT 区域也能立即暴露。
修改 DLL 的 EAT(Export Address Table),让后续模块通过 GetProcAddress 获取到的地址是 Hook 函数。
和 IAT Hook 一样,对比 EAT 条目与磁盘原始文件即可发现。
直接修改目标函数的头部字节,写入一条 jmp 指令跳转到你的 Hook 函数。执行完自定义逻辑后,跳回被覆盖的原始指令继续执行(Trampoline)。
读取函数头几字节,对比磁盘上的原始 DLL 即可发现。大部分反作弊都会做完整性校验。
利用 Windows 向量化异常处理机制(VEH),通过设置硬件断点或内存保护异常,在目标函数执行时触发异常,在异常处理器中劫持执行流。
利用 PAGE_GUARD 内存保护属性。对目标函数所在页设置 PAGE_GUARD,首次访问时触发 STATUS_GUARD_PAGE_VIOLATION 异常,在 VEH 处理器中进行拦截。
TLS(Thread Local Storage)Callback 是 PE 文件中注册的回调函数,在进程/线程创建和终止时被调用,且在 DLL_PROCESS_ATTACH 之前执行。利用这个时机可以在程序的 main 函数之前就完成 Hook 安装。
微软为了支持热补丁,很多系统函数头部保留 mov edi, edi(2字节 NOP)和预留空间,前面还有 5 字节的 nop 填充。利用这些空间写入短跳转 + 近跳转,实现不覆盖任何有效指令的 Hook。
虽然利用了合法的热补丁机制,但 mov edi, edi 被改写一样可以被检测到。
Windows 提供了 NtSetInformationProcess + ProcessInstrumentationCallback 机制。设置后每次从内核返回用户态时,都会跳转到指定的回调函数,相当于 Hook 了所有系统调用的返回路径。
现代反作弊会直接从 ntdll.dll 中读取 syscall 编号(SSN),绕过所有用户态 Hook 直接执行 syscall 指令。对抗方式是修改 ntdll 的 syscall stub 中的 SSN 或 syscall 指令本身。
直接读取 ntdll 的 .text 段对比磁盘文件即可发现修改。
现代反作弊(如 EAC、BattlEye)的做法:
Windows 消息机制提供了全局钩子接口 SetWindowsHookEx,可以拦截系统范围内的键盘、鼠标、窗口消息等事件。设置全局钩子时,系统会将指定的 DLL 注入到所有拥有消息循环的进程中,这使它成为最经典的 DLL 注入 + 行为监控手段。
钩子类型包括:WH_KEYBOARD_LL(低级键盘)、WH_MOUSE_LL(低级鼠标)、WH_CBT(窗口创建/销毁/激活)、WH_GETMESSAGE(消息队列)、WH_CALLWNDPROC(窗口过程调用)等。
Windows 在加载 user32.dll 时会检查注册表 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs,如果该键非空,则将指定的 DLL 加载到每个使用 user32.dll 的进程中。这是最古老的全局注入手段之一。
Win8+ 需要额外设置 LoadAppInit_DLLs = 1,Win10 Secure Boot 模式下被彻底禁用(RequireSignedAppInit_DLLs)。
Image File Execution Options(映像文件执行选项)是 Windows 提供的调试辅助功能。通过在注册表 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options<exe> 下设置 Debugger 值,可以让系统在启动指定程序时自动启动另一个程序(原程序路径作为参数传入)。
高级用法还包括 GlobalFlag(启用页堆等调试功能)和 VerifierDlls(Application Verifier 注入自定义 DLL)。
Windows 输入法(IME)通过注册表 HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layouts 注册,每个输入法对应一个 DLL。当用户切换到该输入法时,系统会将对应的 IME DLL 加载到当前焦点进程中。通过注册一个伪造的输入法 DLL,可以实现对任意 GUI 进程的 DLL 注入。
更高级的方式是使用 Text Services Framework(TSF),通过 COM 接口注册 Text Input Processor,实现更隐蔽的注入。
Windows Application Compatibility Framework 允许通过 SDB 文件对应用程序做内存补丁。可重定向 API 调用、修改内存代码(InMemoryPatch)、注入 DLL(InjectDll shim)。系统在进程创建时由 ntdll!LdrpInitShimEngine 自动应用匹配的 Shim。
Windows COM 通过注册表 CLSID 查找组件 DLL 路径。HKCU 优先于 HKLM,因此无需管理员权限即可劫持。系统中存在大量 Abandoned COM 对象(DLL 已删除但注册表未清理),可直接植入 DLL 利用。
Winsock Layered Service Provider 在 Winsock API 和底层传输协议间插入自定义层。LSP DLL 被自动加载到所有使用网络的进程中(浏览器、游戏、IM 等),可拦截 connect/send/recv 等所有网络操作。通过 WSCInstallProvider API 安装,注册表位于 Protocol_Catalog9。
Win10+ 虽已弃用 LSP(推荐 WFP),但为向后兼容仍然支持加载。
Windows 加载 DLL 时按照固定顺序搜索:
在高优先级目录中植入与目标 DLL 同名的文件,即可劫持加载。核心系统 DLL 受 KnownDlls 注册表保护(始终从 System32 加载),但第三方依赖和非 KnownDll 的系统 DLL 仍可被劫持。
进入内核态后,Hook 的威力和隐蔽性都大幅提升,但同时要面对 PatchGuard 这个「巡逻兵」。以下这些传统内核 Hook 技术在 Windows XP/7 时代是主流,但在 Win10+ 环境下大部分已经被 PatchGuard 监控。
SSDT(System Service Descriptor Table)是内核中的一张函数指针表,syscall 进入内核后通过 SSN 索引到这张表找到对应的内核函数。修改表项即可拦截所有系统调用。
PatchGuard 直接监控 SSDT,定期对比校验和。一旦发现修改 → 延迟蓝屏(故意随机延迟使调试困难)。
IDT(Interrupt Descriptor Table)存储着中断/异常处理器的入口。修改 IDT 条目可以拦截特定中断,比如 int 0x2E(旧版系统调用入口)、int 0x03(断点)、int 0x0E(缺页异常)。
PatchGuard 同样监控 IDT。而且 IDT 是每个 CPU 核心独立的,要 Hook 必须修改所有核心的 IDT,增加了暴露面。
Windows 驱动使用 IRP(I/O Request Packet)进行通信。每个驱动对象(DRIVER_OBJECT)有一个 MajorFunction 数组,存放了 28 种 IRP 处理函数的指针。替换这些指针即可拦截所有发往该驱动的 I/O 操作。
DKOM 不是传统意义上的"Hook",而是通过直接修改内核数据结构来隐藏进程、驱动、端口等。把目标进程从 ActiveProcessLinks 双向链表中摘除,进程管理器就看不见了。
x64 Windows 执行 syscall 指令时,CPU 从 IA32_LSTAR(MSR 0xC0000082)读取内核入口地址(KiSystemCall64)。修改这个 MSR 值,所有系统调用都会先经过你的函数。
通过在 GDT(全局描述符表)中创建 Call Gate,用户态程序可以通过 call far 指令直接跳转到内核态指定地址,绕过 syscall 路径。也可以修改现有 GDT 条目来劫持段切换。
PatchGuard 监控 GDT。而且现代 Windows 几乎不使用 Call Gate,出现一个就极其可疑。
这一层的技术大多利用了 Windows 合法的内核回调机制或巧妙的绕过策略,不直接修改被 PatchGuard 监控的关键结构,因此在现代 Windows 上仍有生存空间。
Windows 内核提供了大量官方回调注册 API,用于监控系统事件。这不算真正的"Hook",但效果类似——你能在关键事件发生时执行自定义代码。
利用 Windows 内核的 ETW(Event Tracing for Windows)日志机制。内核在执行系统调用时可能会调用 syscall ETW provider 发送一条日志回调。通过替换该回调的函数指针,可以在每次 syscall 时获得控制权,而不需要修改 SSDT 或 MSR。
仍然使用 Inline Hook,但配合 PatchGuard 绕过技术。PatchGuard 的检查有固定的定时和 DPC 机制,可以通过多种方式使其失效或规避。
Windows Filtering Platform(WFP)允许驱动注册 Callout 来处理网络数据包。这是微软官方推荐的网络过滤方式,替代了旧的 TDI/NDIS Hook。
修改页表(PTE)中的页帧号(PFN),让目标虚拟地址映射到另外准备好的包含 Hook 代码的物理页帧。读取时看到原始代码页,执行时走到我们的页。
这是 Windows 平台上隐蔽性最强的一层。Hypervisor 运行在所有软件的下面(包括 Windows 内核),拥有对物理内存、CPU 状态、I/O 的完全控制权。在这个层面实施的 Hook,操作系统本身看到的所有信息都可以被伪造。
EPT(Extended Page Table)是 Intel VT-x 提供的第二层地址翻译。Guest 的物理地址(GPA)通过 EPT 映射到实际的主机物理地址(HPA)。EPT 的每个条目都有独立的 Read/Write/Execute 权限位。
核心思想:对同一个 GPA,让读写操作映射到干净原始页,让执行操作映射到包含 Hook 代码的页。
VMFUNC 是 Intel 在 Haswell+ 处理器上引入的指令,允许 Guest 在不触发 VM-Exit 的情况下切换 EPTP(EPT Pointer),即瞬间切换到不同的物理内存视图。
VMX 的 MSR Bitmap 可以选择性地让某些 MSR 的读写触发 VM-Exit。配合 EPT Hook,可以拦截任何通过 MSR 实现的功能(性能计数器、电源控制、安
...(内容过长,已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291370.htm
[原创]整理Windows 全架构 Hook 技术图谱:从 Ring3 到固件层 34 种实现
1 浏览
0 回复
暂无回复,快来抢沙发吧!