关于SEH异常处理回调函数的设置的理解~~请大家指正~~
我在自己的空间里,写了个日记,是关于SEH异常处理回调函数的设置的问题~~我是用单链表的头插入法来理解的,很担心自己的理解并不正确。所以,现在贴到论坛来,希望大家给提下意见~~
原文:
==============================================================================================
在Win32汇编中,对于SEH异常处理回调函数的设置,只有3条简单的指令,但要真正理解起来,还真不容易.
指令如下:
push offset _Handler ;回调函数地址入栈
push fs:[0] ;原先的EXCEPTION_REGISTRATION 结构地址入栈
mov fs:[0],esp ;把当前栈顶地址赋予fs:[0]
如果只看这3条指令是无法理解的,必须结合单链表的头插入法来理解它.
首先,可以把fs:[0] 当作头指针来看待;(注意:fs:[0]就是NT_TIB结构中ExceptionList 的值!)
头指针fs:[0]指向一个SEH单链表! 且指向的是链表的第一个结点:第一个EXCEPTION_REGISTRATION 结构!
当从SEH链表的头部插入一个新的结点(即新的EXCEPTION_REGISTRATION结构)的时候,要修改两个指针!
即,把第一个结点的地址放入新的EXCEPTION_REGISTRATION结构的prev 字段中,把新的EXCEPTION_REGISTRATION结构的地址赋予头指针fs:[0].
而上面的3条指令正是这么做的,但最巧妙的是:竟然把新的结点放到了栈中!!!
push offset _Handler 结点的数据域入栈!
push fs:[0] 头指针值入栈!
这两条指令正好在栈中构造了一个新的结点,即新的EXCEPTION_REGISTRATION结构![esp + 4]是字段Handler;[esp]是字段prev,且prev的值就是原先第一个结点的地址!
再 mov fs:[0],esp 把当前栈顶地址放入fs:[0],这等于把新结点的地址赋予了头指针!(特别注意:是esp赋予了头指针,而不是[esp]的值赋予了头指针!)
真的很巧妙啊~~~
========================================================================