线程上的异常处理:
异常处理函数原型:
返回值有两种: ExceptionContinueExecution异常已解决,
ExceptionContinueSearch此SEH未解决问题,继续在SEH链中搜索
EXCEPTION_DISPOSITION __cdecl _except_handler ( _In_ struct _EXCEPTION_RECORD *_ExceptionRecord, //异常记录结构指针 _In_ void * _EstablisherFrame, //指向EXCEPTION_REGISTRATION结构,即SEH链 _Inout_ struct _CONTEXT *_ContextRecord, //Context结构指针 _Inout_ void * _DispatcherContext //无意义 );
注册回调函数的标准动作:
push offset SehHandler ;建立SEH链标准动作 push fs:[0] mov fs:[0],esp ;建立EXCEPTION_REGISTRATION_RECORD结构并将 ;TIB偏移0改为该结构地址
要知道一个结构:TIB,具体的可以百度,这里只需要知道[FS:0]指向ERR结构就好了。
ERR结构两个字段: prev //指向上一个SEH的ERR结构 handle //指向本handler(处理程序)
关于指向,指针的问题在这里又产生了一定的困扰。思路理清了后总结如下:指针就是保存了一个地址的变量,对指针*运算,即[ptr]的同时完成了指向的动作。[FS:0]指向ERR结构 的理解就是,内存地址FS:0处保存的是ERR结构地址,那么[FS:0](对FS:0取地址)当然就是指向ERR结构。
关于指向xx结构,即指向此结构的第一个字段,也就是说[FS:0]就是prev的内容。
_except_handler参数一:
typedef struct _EXCEPTION_RECORD { DWORD ExceptionCode; //异常原因码 DWORD ExceptionFlags;//异常标志,0可修复,1不可修复,2栈展开 struct _EXCEPTION_RECORD *ExceptionRecord;//指向嵌套的异常结构,异常处理程序又引发了异常 PVOID ExceptionAddress; //异常地址 DWORD NumberParameters; ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD;
_except_handler参数二:
1 ;****************************************** 2 ;coded by Rrouned 3 ;****************************************** 4 ;例子2.Thread型异常处理 5 ;****************************************** 6 .386 7 .model flat,stdcall 8 option casemap:none 9 10 include windows.inc 11 include user32.inc 12 includelib user32.lib 13 include kernel32.inc 14 includelib kernel32.lib 15 16 .DATA 17 szTit db "SEH例子",0 18 mesSUC db "修复了除0异常",0 19 .DATA? 20 hInstance dd ? 21 ;;----------------------------------------- 22 .CODE 23 SehHandler proc C uses ebx esi edi pExcept,pFrame,pContext,pDispatch 24 25 Assume esi:ptr EXCEPTION_RECORD 26 Assume edi:ptr CONTEXT 27 28 mov esi,pExcept 29 mov edi,pContext 30 test [esi].ExceptionFlags,3 31 jne _continue_search 32 cmp [esi].ExceptionCode,STATUS_INTEGER_DIVIDE_BY_ZERO ;是除0错? 33 jne _continue_search 34 35 mov [edi].regEcx,10 ;将被除数改为非0值继续返回执行 36 ;这次可以得到正确结果是10 37 38 mov eax,ExceptionContinueExecution ;修复完毕,继续执行 39 ret 40 _continue_search: 41 mov eax,ExceptionContinueSearch ;其他异常,无法处理,继续遍历seh回调函数列表 42 ret 43 SehHandler endp 44 _StArT: 45 assume fs:nothing 46 47 push offset SehHandler ;建立SEH链标准动作 48 push fs:[0] 49 mov fs:[0],esp ;建立EXCEPTION_REGISTRATION_RECORD结构并将 50 ;TIB偏移0改为该结构地址 51 ;引发异常 52 xor ecx,ecx ;ECX=0 53 mov eax,100 ;EAX=100 54 xor edx,edx ;EDX=0 55 56 div ecx ;产生除0错! 57 invoke MessageBox,0,addr mesSUC,addr szTit,0 58 59 pop fs:[0] ;恢复原异常回调函数 60 add esp,4 ;平衡堆栈 61 62 invoke ExitProcess,0 63 END _StArT