异常的分发和处理时在线程范围内进行的,异常处理器的注册也是相对线程而言的。Windows系统中的每个用户态线程都拥有一个线程环境块(Thread Environment Block),TEB结构的具体定义。
TEB结构的起始处总有一个被称为线程信息块(Thread information Block)的结构,简称TIB.TIB的第一字段ExceptionList记录的就是用来登记结构化异常处理链表的表头地址,在x86系统中,段寄存器FS总是指向线程的TEB/TIB结构,FS:[0] 总是指向结构化异常处理链表的表头,所以将这个链表称为FS:[0]链条。可以把结构化异常处理看作是操作系统与用户代码软硬件异常的一种模型,而FS:[0]链条便是这两者间协作的接口。当有异常需要处理时,操作系统通过FS:[0]链条来寻找异常处理器,给用户代码异常情况的机会。
可以手工编写代码来登记和注销异常处理器。首先需要编写一个异常处理器函数,它应该具有标准的sehHandler原型,然后在栈上建立一个EXCEPTION_REGISTRATION_RECORD结构,并把这个结构的地址注册到FS:[0]链表中。
注册FS:[0]的代码如下所示:
#include "stdafx.h"
#include <windows.h>
// 定义一个符合sehHandler原型的异常处理函数,如果该函数检测发生的是
// 除零异常,然后将上下文结构中的ECX寄存器的值改为10,让其继续执行
// 导致异常的代码,第二次执行时由于除数不再为0所以可以顺利执行了
EXCEPTION_DISPOSITION __cdecl _raw_seh_handler( struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT * ContexRecord,
void * DispacherContext
)
{
printf("_raw_seh_handler: code-0x%x, flags-0x%x\n",
ExceptionRecord->ExceptionCode,
ExceptionRecord->ExceptionFlags);
if(ExceptionRecord->ExceptionCode == STATUS_INTEGER_DIVIDE_BY_ZERO)
{
ContexRecord->Ecx = 10;
return ExceptionContinueExecution;
}
return ExceptionContinueSearch;
}
int main(int argc, char* argv[])
{
__asm
{
// 手工方法将异常函数注册到FS:[0]链表中
push OFFSET _raw_seh_handler
push FS:[0]
mov FS:[0], ESP
// 执行除零异常
xor edx, edx
mov eax, 100
xor ecx, ecx
idiv ecx
mov eax, [ESP]
mov FS:[0], EAX
add esp, 8
}
printf("Hello World!\n");
return 0;
}
网吧精品
网络布线
热门专题
推荐配置
网络安全
路由专题
对比更新
QQ相关
注册表相关
网管初学
网吧优化
网吧无盘优化
网吧系统优化
迅闪2008
网吧三层更新
无盘服务器
MaxDos
Win2008
网吧虚拟磁盘
星际争霸II
锐起
网维大师
网吧游戏菜单
网吧活动
迅闪2009
网吧母盘
万象
博百优
迅闪2010
信佑2010
Windows8
信佑2011
迅闪2011
易游2011
顺网无盘
连锁网吧
黑网吧
2011网吧新闻
网吧闲聊
网吧游戏
互联网类软件
增值联盟
网吧广告联盟
有道搜索联盟
淘123联盟
网吧广告
深度无盘
信佑无盘
网众无盘
MZD无盘
网吧软件故障解决
网吧硬件故障大全
海蜘蛛
ROS
磁盘缓存
网吧GHOST
快吧无盘
快吧教程
网吧防盗
2011网吧政策
绿色网吧
网吧禁烟
万象2004
雪花病毒
网吧电影
网吧达人
QQ网吧
SuperCache|SuperSpeed
CCDISK
网吧远程控制
2011网吧配置
万象密码
迅闪无盘
网吧系统下载
网吧管理系统
网吧键盘
网吧鼠标
天下网吧·网吧天下