SEH异常之编译器原理探究

本文深入探讨了Windows系统下的SEH(Structured Exception Handling)异常处理机制,包括&_try_except_、&_try_finally_原理,异常处理函数的注册与执行流程,以及未处理异常的处理方式,如UnhandledExceptionFilter和线程启动时的安全防护措施。
摘要由CSDN通过智能技术生成

_try_except原理

调用_except_handle3这个异常处理函数,这里并不是每个编译器的异常处理函数都是相同的,然后存入结构体,将esp的值赋给fs:[0],再就是提升堆栈的操作

每个使用 _try _except的函数,不管其内部嵌套或反复使用多少_try _except,都只注册一遍,即只将一个 _EXCEPTION_REGISTRATION_RECORD 挂入当前线程的异常链表中(对于递归函数,每一次调用都会创建一个 _EXCEPTION_REGISTRATION_RECORD,并挂入线程的异常链表中)。

typedef struct _EXCEPTION_REGISTRATION_RECORD {

    struct _EXCEPTION_REGISTRATION_RECORD *Next;

    PEXCEPTION_ROUTINE Handler;

  } EXCEPTION_REGISTRATION_RECORD;

可以看到只有一个异常处理函数

那么这里编译器是如何做到只用一个异常处理函数的呢?编译器把原来_EXCEPTION_REGISTRATION_RECORD结构进行了拓展,添加了三个成员

struct _EXCEPTION_REGISTRATION{
        struct _EXCEPTION_REGISTRATION *prev;
        void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION, PCONTEXT, PEXCEPTION_RECORD);
        struct scopetable_entry *scopetable;
        int trylevel;
        int _ebp;
    };       

新堆栈结构如下

scopetable

struct scopetable_entry
{
       DWORD previousTryLevel  //上一个try{}结构编号 
       PDWRD        lpfnFilter         //过滤函数的起始地址
       PDWRD        lpfnHandler    //异常处理程序的地址     
}

查看地址可以发现有三个结构体

存储着的正式异常函数的开始地址和结束地址

第一个值previousTryLevel是上一个try结构的编号,这里如果在最外层就是-1,如果在第二层就是0,如果在第三层就是1,以此类推

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值