_try_except原理探究

_try_except原理探究_第1张图片

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

_try_except原理探究_第2张图片

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

_try_except原理探究_第3张图片

_try_except原理探究_第4张图片

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

_try_except原理探究_第5张图片

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

_try_except原理探究_第6张图片

新堆栈结构如下:

_try_except原理探究_第7张图片

scopetable

_try_except原理探究_第8张图片

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

_try_except原理探究_第9张图片

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

_try_except原理探究_第10张图片

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

_try_except原理探究_第11张图片

_try_except原理探究_第12张图片

trylevel

该成员表示代码运行到了哪个try结构里面,进入一个try则加1,try结构执行完成之后则减1

_try_except原理探究_第13张图片

_try_except原理探究_第14张图片

_except_handler3

1.CPU检测到异常 -> 查中断表执行处理函数 -> CommonDispatchException -> KiDispatchException -> KiUserExceptionDispatcher                 -> RtlDispatchException ->VEH -> SEH

2.执行_except_handler3函数

<1> 根据trylevel 选择scopetable数组

<2> 调用scopetable数组中对应的lpfnFilter函数

_try_except原理探究_第15张图片

<3> 如果lpfnFilter函数返回0 向上遍历 直到previousTryLevel=-1

假设有两个异常点

_try_except原理探究_第16张图片

首先找到trylevel为0

_try_except原理探究_第17张图片

然后找到异常过滤表达式为1

_try_except原理探究_第18张图片.

然后遍历数组的lpfnFilter

_try_except原理探究_第19张图片

_try_except原理探究_第20张图片

如果返回值为1则调用异常处理函数,如果为0则该异常函数不处理,如果为-1则继续从原异常点向下执行

_try_except原理探究_第21张图片

_try_except原理探究_第22张图片

假设在B这个地方出异常,得到trylevel为2

_try_except原理探究_第23张图片

那么这里就回去遍历lpfnFilter为2的地方

_try_except原理探究_第24张图片

假设这里返回值为0,则继续查找,注意这个地方是向上查找,首先判断当前previousTryLevel的值是否为-1,如果为-1就停止查找(-1代表已经是最外层)try结构,然后再向上找,假设这里返回值仍然为0,判断previousTryLevel的值为-1,就停止查找,没有找到响应的异常处理函数

_try_except原理探究_第25张图片

你可能感兴趣的:(java,开发语言,web安全,网络,安全)