0239、Windows 逆向攻防:VTable、VEH 与断点类 Hook
返回:Windows 逆向攻防篇 · 网络安全学习主页
这一节对应 13.2 - 13.5。前面的 IAT Hook 和 Inline Hook 都比较容易从表项或代码字节中看到痕迹;这一组内容开始转向对象模型、异常分发和断点机制。复盘时重点看“调用路径被谁接管了”和“异常/断点为什么能改变控制流”。
1、内容范围
| 小节 | 主题 | 复盘重点 |
|---|---|---|
| 13.2 | VTable Hook | C++ 虚函数表、对象首部、虚函数调用路径和表项完整性 |
| 13.3 | VEH 异常注册处理拦截 | 向量化异常处理、异常分发顺序和回调链观察 |
| 13.4 | 硬件断点及无痕 Hook | 调试寄存器、执行断点、线程上下文和检测难点 |
| 13.5 | 无痕钩子实现及瞬时执行 | 临时修改、短窗口执行、恢复状态和行为关联 |
2、逐节复盘
13.2 VTable Hook
VTable Hook 建立在 C++ 多态对象模型上。对象中通常保存虚表指针,虚表里保存虚函数地址。如果虚表指针或虚表项被替换,原本的虚函数调用就可能被导向新的逻辑。
| 项目 | 复盘重点 |
|---|---|
| 对象模型 | 对象地址、虚表指针、虚函数表项之间的关系 |
| 表项来源 | 虚表项是否指向原模块 .rdata 或合法代码区域 |
| 修改位置 | 是替换对象里的虚表指针,还是替换虚表中的函数地址 |
| 检测方式 | 比较内存虚表与文件映像、检查表项所属模块 |
13.3 VEH 异常注册处理拦截
VEH 是 Windows 的向量化异常处理机制。它本来用于异常处理和调试辅助,但异常回调链也可能被用于观察或改变执行路径。复盘重点是异常触发点、异常类型、处理顺序和回调是否来自可信模块。
| 项目 | 说明 |
|---|---|
| 异常来源 | 断点、访问违规、单步、保护页等 |
| 分发顺序 | VEH 先于部分结构化异常处理流程被调用 |
| 回调地址 | 需要记录回调所在模块、内存属性和调用上下文 |
| 处理结果 | 异常被继续搜索、被处理,还是改变了执行状态 |
13.4 硬件断点及无痕 Hook
硬件断点依赖调试寄存器,不一定修改目标代码字节,所以从代码完整性角度可能看不出变化。防护复盘要转向线程上下文、调试寄存器和异常事件。
| 观察点 | 说明 |
|---|---|
| 调试寄存器 | DR0-DR3 记录断点地址,DR7 记录启用状态 |
| 线程粒度 | 硬件断点通常和线程上下文相关 |
| 异常类型 | 命中后会产生调试异常或单步相关事件 |
| 取证难点 | 代码字节不变,但控制流仍然可能被异常路径接管 |
13.5 无痕钩子实现及瞬时执行
所谓“无痕”更多是指常规静态检查不容易看见,不代表系统完全没有痕迹。短时间内的内存保护变化、异常链变化、线程上下文变化、调用栈异常都可能成为观察点。
| 风险点 | 复盘方式 |
|---|---|
| 时间窗口短 | 需要日志、事件和快照配合,而不是只做一次静态扫描 |
| 状态恢复 | 比较前后内存、寄存器、异常链和线程状态 |
| 语义异常 | 即使字节恢复,API 调用结果和行为链也可能异常 |
| 检测策略 | 结合事件流、调用栈、模块来源和内存属性 |
3、检测复盘表
| 技术 | 主要痕迹 | 复盘重点 |
|---|---|---|
| VTable Hook | 虚表指针、虚表项地址异常 | 对象模型与模块地址范围 |
| VEH Hook | 异常回调链、异常处理结果异常 | 回调地址、异常类型、分发顺序 |
| 硬件断点 | 调试寄存器、调试异常 | 线程上下文和异常事件 |
| 瞬时 Hook | 短时间状态变化 | 时间线、事件关联和前后快照 |
4、学习检查清单
| 检查项 | 状态 |
|---|---|
| 能解释 VTable Hook 为什么依赖 C++ 虚函数表 | 待复盘 |
| 能说明 VEH 与异常分发链的关系 | 待复盘 |
| 能知道硬件断点为什么不一定修改代码字节 | 待复盘 |
| 能从检测角度组合内存、异常、线程上下文和调用栈 | 待复盘 |
本节只做 Hook 机制理解和防护复盘,不整理可直接用于隐蔽拦截的实现步骤。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!






