![]() |
|
||||||||||||||
| | 网站首页 | 数据库教程 | web编程 | 服务器 | 程序设计 | | ||
|
||
|
||||||
| 我理解的windows异常处理 | ||||||
作者:佚名 文章来源:不详 点击数: 更新时间:2007-9-12 ![]() |
||||||
|
申明:
1.本文大部份内容参考《A Crash Course on the Depths of Win32 Structured Exception Handling》,我只是对顺序进行了一些调整,同时加入了一些我的理解,所以不敢自称原创。
2.结构定义位置中的X:指的是VC6.0的安装盘符。 首先,当线程发生异常时,操作系统会将这个异常通知给用户使用户能够得知它的发生。更特别的是,当线程发生异常时,操作系统会调用用户定义的回调函数。 回调函数的定义如下: /* * 结构名称:except_handler * 定义位置:X:\Program Files\Microsoft Visual Studio\VC98\Include\EXCPT.H */ EXCEPTION_DISPOSITION __cdecl _except_handler ( struct _EXCEPTION_RECORD *ExceptionRecord, //指向 EXCEPTION_RECORD结构的指针 void * EstablisherFrame, //指向 establisher frame 结构体的指针 struct _CONTEXT *ContextRecord, //指向 CONTEXT 结构体的指针,它保存着某一线程的寄存器的值,定义在WINNT.H中 void * DispatcherContext ); except_handler结构的第一个成员,即EXCEPTION_RECORD结构如下: /* * 结构名称:EXCEPTION_RECORD * 定义位置:X:\Program Files\Microsoft Visual Studio\VC98\Include\WINNT.H */ typedef struct _EXCEPTION_RECORD { DWORD ExceptionCode; //操作系统分配给异常的号("STATUS_"开头的宏),如:STATUS_ILLEGAL_VLM_REFERENCE DWORD ExceptionFlags; struct _EXCEPTION_RECORD *ExceptionRecord; PVOID ExceptionAddress; //异常发生处的地址 DWORD NumberParameters; UINT_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD; 异常发生时操作系统是如何知道在那里调用回调函数呢?答案在 EXCEPTION_REGISTRATION 结构体中(简称ERR结构)。 /* * 结构名称:EXCEPTION_REGISTRATION(或称ERR结构) * 定义位置:X:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\EXSUP.INC */ _EXCEPTION_REGISTRATION struc divv dd ? handler dd ? //指向 _except_ handler 回调函数的指针 _EXCEPTION_REGISTRATION ends 在 WINNT.H 的 NT_TIB 结构体定义中,这个结构体被称为 _EXCEPTION_REGISTRATION_RECORD。然而 _EXCEPTION_REGISTRATION_RECORD 的定义是没有公开的,因此只能用上面(EXSUP.INC)的汇编语言的 struc 来表示EXCEPTION_REGISTRATION结构。 /* * 结构名称:NT_TIB(其第一个成员为ERR结构) * 定义位置:X:\Program Files\Microsoft Visual Studio\VC98\Include\WINNT.H */ typedef struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; //这里就是ERR结构,即上面的EXCEPTION_REGISTRATION结构 PVOID StackBase; PVOID StackLimit; PVOID SubSystemTib; union { PVOID FiberData; DWORD Version; }; PVOID ArbitraryUserPointer; struct _NT_TIB *Self; } NT_TIB; OS 从哪里能找到这个 EXCEPTION_REGISTRATION 结构体呢? 结构化异常处理是以线程为基础的。也就是说,每一个线程都有自己的异常处理回调函数、线程信息块(TEB 或 TIB)。这个结构体中有一个域对于 Windows NT, Windows 95, Win32s 和 OS/2 都是相同的,就是TIB 中的第一个指针指向线程的ERR结构体。在 Intel 的 Win32 平台上,FS 寄存器永远指向当前的 TIB结构,因此,FS:[0] 指向当前的 ERR 结构体。答案出来了!当异常发生时,系统察看出错线程的 TIB 结构,并取回一个指向ERR结构(EXCEPTION_REGISTRATION)结构体的指针,从而得到一个指向 _except_handler 回调函数的指针(ERR结构地址+4)。 总结: 1. FS->当前线程信息块TIB 2. FS:[0]->ERR结构(即EXCEPTION_REGISTRATION) 借用czy文章的说法,就是: fs:[0]-> _EXCEPTION_REGISTRATION struc divv dd ? ;前一个_EXCEPTION_REGISTRATION结构 handler dd ? ;异常处理函数地址 _EXCEPTION_REGISTRATION ends 3. [ERR+4]->异常处理函数(即_except_handler) 参考: 1.A Crash Course on the Depths of Win32 Structured Exception Handling http://www.xfocus.net/articles/200503/785.html 2.利用SEH执行shellcode http://elfhack.whitecell.org/chinesedocs/seh1.txt 本文来源:http://blog.csdn.net/wishfly/archive/2007/08/26/1759972.aspx
|
||||||
| 文章录入:admin 责任编辑:admin | ||||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | ||||||
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 网站地图 | 管理登录 | | |||
|