windows 异常处理

简单总结一下有关 Windows 处理异常方面的知识

SEH

SEH 简单说明

SEH是基于栈的异常处理,作用范围仅限当前线程,在程序产生异常时,如果程序正在被调试os 就会先把异常抛给调试器处理 ,调试器无法解决这一异常就会由进程处理,进程也无法处理就会交由 os 处理。

SEH 结构

TEB 结构体

TEB 结构体是操作系统为了保存线程私有数据而创建的,TIB 是保存线程基本信息的数据结构。

​ 在 x86 用户模式下可以由 FS 寄存器来访问当前线程 TEB数据,64位系统中则使用 gs 寄存器

SEH 的链式结构

SEH 以链的形式存在,即链表,结构如图所示:

SEH 会在链表的头部进行异常处理函数的安装与卸载

TEB.NtTib.ExceptionList = FS:[0]

ExceptionList 是 TIB 中与异常处理有关的项,指向 SEH 链

安装与卸载

安装

push @MyHandler ;异常处理程序
push FS:[0] ;SEH Linked List头
mov dword ptr fs:[0],esp ;添加链表

卸载

mov esp,dword ptr fs:[0]
pop dword ptr fs:[0]

​ 安装与卸载一般发生在函数开始与结束处

VEH

​ 当异常发生时,VEH 会在 SEH 之前执行,如果 VEH 无法处理这一异常,就会由 SEH 继续处理异常

​ 可通过 AddVectorExceptionHandler 这个 API 来注册回调函数,第一个参数可指定回调函数安装与卸载是在链表前端还是尾部

​ 作用范围为整个进程,可捕获所有线程的异常

​ 想要获取 VEH 异常的函数地址应该可以看程序中是否用到 AddVectorExceptionHandler 这个 API,第二个参数是异常处理函数

例子

​ minilctf re2

​ 这里存在两个触发异常的点,一个是访问到了不能访问的内存,另一个是除0异常

​ 在 main 函数的开头发现异常处理函数安装的汇编代码,但调试过程中在 __except_handler4 下断点程序并不会停下,这里的 __except_handler4 里的函数应该是编译器添加的

​ 在 TLS 函数中可以发现注册了 VEH 的异常处理程序,根据 VEH 会先于 SEH 执行,在 Handler 函数下断就能使指定的异常触发时停下

​ 当然有关 Windows 异常处理的知识还有很多,本文没有提到,待填

参考资料

作者

0wl

发布于

2021-05-23

更新于

2021-11-16

许可协议

评论