SEH的注册回调函数

我第一次知道SEH是在学习缓冲区溢出时,就知道这是windows的一个异常处理机制。SEH是基于线程的,使用SEH可以为每个线程设置不同的异常处理程序,而且可以为每个线程设置多个异常处理程序;SEH是硬件平台相关的,因为使用了与硬件平台相关的数据指针。 win32为每个线程定义了一个线程信息块(TIB),其中保存了线程的一些属性数据,TIB的格式被定义为NT_TIB结构: NT_TIB STRUCT ExceptionList dd ? ;SEH链入口 StackBase dd ? ;堆栈基址 StackLimit dd ? ;堆栈大小 SubSystemTib dd ? FiberData dd ? ArbitraryUserPointter dd ? Self dd ? ;本NT_TIB结构的自身的线性地址 NT_TIB ENDS 该结构的第一个字段ExceptionList指向一个EXCEPTION_REGISTRATION结构,SEH异常处理回调函数的入口地址由该结构指定,这个结构的定义如下: EXCEPTION_REGISTRATION STRUCT prev dd ? ;前一个EXCEPTION_REGISTRATION结构的地址 handler dd ? ;异常处理回调函数地址 EXCEPTION_REGISTRATION ENDS 当异常发生时,系统从TIB中取出ExceptionList字段,然后从该字段指定的EXCEPTION_REGISTRATION结构中取出hanlder字段,并根据其中的地址去调用回调函数。所以,如果要自定义一个异常处理程序的话,只要构建一个新的含有ExceptionList字段,将其指向这个结构就可以注册一个SEH异常处理回调函数了。而TIB永远都放在fs段选择器指定的数据段的0偏移处,fs:[0]的地方就是TIB结构的Exception字段。可以使用以下的代码在堆栈中构造一个EXCEPTION_REGISTRATION结构,设置新的异常处理回调函数。 assume fs:nothing push offset _Handler push fs:[0] mov fs:[0],esp 第一条语句将回调函数的地址入栈;第二条语句将原先使用的EXCEPTION_REGISTRATION结构入栈,现在esp指向的地方刚好是一个新的EXCEPTION_REGISTRATION结构---[esp]等于原结构地址,就是prev字段,而[esp+4]等于回调函数地址,就是handler字段,第三条指令将esp的值放入fs:[0]中,设置工作完成。由于MASM编译器默认将fs段寄存器定义为error,所有在使用前要使用assume fs:nothing伪指令来启用该寄存器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值