异常处理¶
REVERSE · 知识域。异常机制被用作控制流/反调试。标签:VEH、SEH、UEF、VCH、其他异常处理。
触发特征¶
- 程序频繁"崩溃又继续";反编译看不到关键逻辑(在异常回调里)。
- 反调试:调试器吞掉异常导致回调不执行。
VEH(Vectored Exception Handler)¶
AddVectoredExceptionHandler:进程级异常链,先于 SEH。- 逆向用途:异常做隐藏控制流(int3/除零/访问违例跳转);注册回调处下断。
- 混淆:RtlInstallFunctionTableCallback 干扰展开;VEH + MBA 多线程诱饵(ApoorvCTF 2026)。
SEH(Structured Exception Handling)¶
- 栈帧异常链(fs:[0]);
try/except编译产物;__except_handler4。 - 逆向:关键逻辑常在 filter/except 块;SEH 链遍历(x64dbg 命令)。
- 反调试经典:
int 3/除零触发,正常程序走 except 继续,被调试则调试器先接管 → 检测调试存在。 - pwn 联动:SEH 覆写(老 32 位 exploit,→ Pwn);SafeSEH/SEHOP 校验。
UEF(Unhandled Exception Filter)¶
SetUnhandledExceptionFilter:无人处理的异常最后兜底;藏最终解密/退出逻辑。- 逆向:ExitProcess 前的异常流;filter 回调内解密 key。
VCH(Vectored Continue Handler)¶
AddVectoredContinueHandler:继续执行时触发,常与 VH 配对做"两段式"控制流。- 逆向:VH 里改上下文 → VCH 收尾;跟踪 CONTEXT 结构变化。
其他异常处理¶
- C++ 异常:throw/catch 逆 ABI(
__cxa_throw/__cxa_catch、MSVC__CxxFrameHandler);异常对象携带数据。 - 信号(Linux):SIGFPE handler 当除零分支(PlaidCTF 2017 strace 计数侧信道)、SIGILL 模式切换(Hack.lu 2015)、SIGSEGV 当跳板、SIGFPE + mprotect 代码自变异(Hack.lu 2018)。
- nanomites:父进程 debug 子进程,子进程 int3 由父进程代填结果(Linux 信号版/Windows 调试事件版)。
- 长跳转:
setjmp/longjmp跨函数跳转控制流。 - 展开与恢复:x64 SEH 基于表(RtlAddFunctionTable),逆向看 RUNTIME_FUNCTION。
处理流程¶
- 异常触发点定位:崩溃地址、
RaiseException/int 3/div 0调用。 - 找注册:
AddVectoredExceptionHandler/__try作用域/signal()。 - 回调内分析;调试器设置"异常传递给程序"(
_ignore配置)让流程正常走。 - 需要时伪造上下文:修改 EXCEPTION_RECORD/CONTEXT 绕校验。
工具速查¶
# x64dbg: 选项→异常→让程序处理指定异常
# gdb: handle SIGFPE nostop noprint pass
# IDA: 搜索 AddVectoredExceptionHandler/SetUnhandledExceptionFilter 交叉引用