SEH结构化异常处理03

线程上的异常处理:

异常处理函数原型:

返回值有两种: 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
原文地址:https://www.cnblogs.com/Rrouned/p/3362724.html