SEH异常之编译器原理探究(1)

_try_except原理

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

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

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

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

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

新堆栈结构如下

scopetable

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

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

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

trylevel

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

_except_handler3

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

2.执行_except_handler3函数

<1> 根据trylevel 选择scopetable数组

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

1.EXCEPTION_EXECUTE_HANDLER(1) 执行except代码

2.EXCEPTION_CONTINUE_SEARCH(0) 寻找下一个

3.EXCEPTION_CONTINUE_EXECUTION(-1) 重新执行

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

假设有两个异常点

首先找到trylevel为0

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

然后遍历数组的lpfnFilter

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/579014.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统资源紧缺?不用担心,Linux命令和Shell脚本帮你搞定

在之前的文章中介绍了如何申请AWS免费主机使用WordPress搭建自己的个人网站&#xff0c;但是在我使用过程中发现了一个问题&#xff0c;由于陆陆续续安装了好几个插件&#xff0c;偶尔在访问网站时会出现数据库连接出错的异常情况&#xff0c;导致页面无法访问。稍等一会儿刷新…

基于Springboot+vue的鲜花销售商城网站

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;鲜花销售商城当然也不能排除在外。鲜花销售商城是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#x…

vue-v-for遍历index与id

一.遍历列表key的作用&#xff08;index作为key&#xff09; 虚拟DOM上有key,是虚拟的&#xff0c;但是真实DOM上没有&#xff0c;key是Vue内部的 当使用index作为key的时候&#xff0c;Vue会根据初识数据生成一个初始的虚DOM&#xff0c; 然后在页面上映射出真实DOM 如果向数据…

C#_事件_多线程(基础)

文章目录 事件通过事件使用委托 多线程(基础)进程:线程: 多线程线程生命周期主线程Thread 类中的属性和方法创建线程管理线程销毁线程 事件 事件&#xff08;Event&#xff09;本质上来讲是一种特殊的多播委托&#xff0c;只能从声明它的类中进行调用,基本上说是一个用户操作&…

kubernetes(K8S)学习(五):K8S进阶(Lifecycle......偏理论)

K8S进阶&#xff08;Lifecycle......偏理论&#xff09; 一、Pod进阶学习之路1.1 Lifecycle1.2 重启策略1.3 静态Pod1.4 健康检查1.5 ConfigMap1.6 Secret1.7 指定Pod所运行的Node 二、Controller进阶学习之路2.1 Job & CronJob2.2 StatefulSet2.3 DaemonSet2.4 Horizontal…

039—pandas 不规则表头转换为规整DataFrame

使用步骤 读入数据 代码如下&#xff08;示例&#xff09;&#xff1a; import pandas as pd import numpy as np df pd.DataFrame({0: [姓名, 性别],1: [张三, 男],2: [年龄,np.nan],3: [18,np.nan]}) dfdf.values.reshape([4,2])r len(df.columns)(pd.DataFrame(df.valu…

MQTT.fx连接新版OneNet平台的一些问题

对于使用通信主题publish给OneNET时&#xff0c;如图所示&#xff1a; 但是点击Publish后&#xff0c;出现了Broker connection lost的问题 原因在于&#xff1a;新版OneNET和旧版OneNET的通信主题不一致了&#xff0c;查阅文档获知&#xff0c;格式如下&#xff1a; $sys/{p…

家庭网络防御系统搭建-配置流量镜像到NDR系统

由于需要将家庭网络中的全部流量送到NDR分析系统进行分析&#xff0c;因此需要一个具备流量镜像功能的交换机或者路由器。在前面文章所提及的家庭网络架构中&#xff0c;需要一台交换机即可拷贝东西向流量以及南北向流量。当然如果家庭中的路由器或者其他设备具备交换机镜像功能…

代码审计之远程调试方法介绍

前言 在做代码审计时&#xff0c;通常需要将源码运行起来&#xff0c;用于验证漏洞是否真实存在&#xff0c;通过debug可以更加直观的观察程序的运行细节&#xff0c;可以比较快的确认有效漏洞&#xff0c;debug也是开发人员在代码调试测试阶段经常用到的方法。但源码开始运行…

Linux:程序地址空间详解

目录 一、堆、栈、环境参数所在位置 二、进程地址空间底层实现原理 ​编辑 三、什么是地址空间 四、为什么要有进程地址空间 五、细谈写实拷贝的实现及意义 在C/C学习中&#xff0c;都学习过如上图所示的一套存储结构&#xff0c;我们大致知道一般存储空间分为堆区&#…

社交网络的未来:Facebook如何塑造数字社交的下一章

引言 社交网络已成为我们生活中不可或缺的一部分&#xff0c;而Facebook作为其领军者&#xff0c;一直在塑造着数字社交的未来。本文将深入探讨Facebook在未来如何塑造数字社交的下一章&#xff0c;并对社交网络的发展趋势进行展望和分析。 1. 引领虚拟社交的潮流 Facebook将…

建立一个简单的网页音乐盒模型效果#css#h5

“音乐盒”可以看做一个大盒子&#xff0c;用<div>标签进行定义。大盒子的上面为文本内容&#xff0c;可以在<div>标签中嵌套<h2>和<p>标签来实现&#xff1b;大盒子下面为图像&#xff0c;通过在<div>标签中嵌套<img/>标签来实现。 样式…