`
lingqi1818
  • 浏览: 248455 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【转】一致代码段和非一致代码段

 
阅读更多
原文地址:
http://blog.csdn.net/feijj2002_/article/details/4597174

之所以出现这个定义是因为系统要安全:内核要和用户程序分开..内核一定要安全.不能被用户程序干涉.
但是有时候用户程序也需要读取内核的某些数据,怎么办呢?
操作系统就引入了访问特权等级(0-3)的机制.

这些特权等级,通过三个符号来体现CPL/DPL/RPL.

其中

CPL是存寄存器如CS中,

RPL是代码中根据不同段跳转而确定,以动态刷新CS里的CPL.

DPL是在GDT/LDT描述符表中,静态的。





1.在x86中的数据和代码是按段来存放的:[section],GTL/LDT里的每个段描述符被设置有不同的特权级DPL.
2.程序是通过选择子/门调用等等来在段之间来回走动的.实现用户级与系统级的调用跳转.
3.与GDT里的段描述符一样,CPU寄存器内的每一个选择子/门调用选择子是有分等级的:这个是在选择符的结构中:RPL(最后2位)



调用的选择符和被调用的段都分了等级.那么这些等级在调用时按什么规则实现跳转呢?



先来看看段描述符的相关定义.



段描述符总共有八字节,其中表示段属性的第五字节各位含义:

7  6 5  4  3...0

P  DPL S  TYPE



其中

P:为Persent存在位

1 表示段在内存中存在

0表示段在内存中不存在



DPL

Decsriptor Privilege level

段特权级.0-3



S

表示描述符的类型

1 数据段和代码段描述符

0 系统段描述符和门描述符



当 S=1 时TYPE中的4个二进制位情况:
     3       2       1       0
   执行位 一致位 读写位 访问位


执行位:置1时表示可执行,置0时表示不可执行;
一致位:置1时表示一致码段,置0时表示非一致码段;
读写位:置1时表示可读可写,置0时表示只读;
访问位:置1时表示已访问,置0时表示未访问。

所以一致代码段和非一致代码段的意思就是指这个一致位是否置1,置1就是一致代码段,置0就为非一致代码段。





一致代码段:

简单理解,就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码.

通常这些共享代码,是"不访问"受保护的资源和某些类型异常处理。比如一些数学计算函数库,为纯粹的数学运算计算,

被作为一致代码段.



一致代码段的限制作用

1.特权级高的程序不允许访问特权级低的数据:核心态不允许调用用户态的数据.
2.特权级低的程序可以访问到特权级高的数据.但是特权级不会改变:用户态还是用户态.



非一致代码段:

为了避免低特权级的访问而被操作系统保护起来的系统代码.

非一致代码段的限制作用

1.只允许同级间访问.
2.绝对禁止不同级访问:核心态不用用户态.用户态也不使用核心态.



通常低特权代码必须通过"门"来实现对高特权代码的访问和调用.





不同级别代码段之间转移规则,是通过CPL/RPL/DPL来校验.

如下先来理解这几个概念:



特权级
------------------------------------------------------------------------------------------

CPL是当前进程的权限级别(Current Privilege Level),是当前正在执行的代码所在的段的特权级,存在于cs寄存器的低两位。 (个人认为可以看成是段描述符未加载入CS前,该段的DPL,加载入CS后就存入CS的低两位,所以叫做CPL,其值就等于原段DPL的值)



RPL说明的是进程对段访问的请求权限(Request Privilege Level),是对于段选择子而言的,每个段选择子有自己的RPL,它说明的是进程对段访问的请求权限,有点像函数参数。而且RPL对每个段来说不是固定的,两次访问同一段时的RPL可以不同。RPL可能会削弱CPL的作用,例如当前CPL=0的进程要访问一个数据段,它把段选择符中的RPL设为3,这样虽然它对该段仍然只有特权为3的访问权限。 (个人认为是以CPL来访问段DPL所出示的“证件(RPL)”,如出示的“证件”权级范围在CPL之内且满足DPL的特权检查规则:DPL >= max{CPL,RPL},就能正常通过DPL;反之则不会通过还会发生错误)



DPL存储在段描述符中,规定访问该段的权限级别(Descriptor Privilege Level),每个段的DPL固定。当进程访问一个段时,需要进程特权级检查,一般要求DPL >= max {CPL, RPL}

   下面打一个比方,中国官员分为6级国家ZX1、总理2、省长3、市长4、县长5、乡长6,假设我是当前进程,级别总理(CPL=2),我去南城市(DPL=4)考察,用省长的级别(RPL=3 这样也能吓死他们:-))去访问,可以吧,如果用县长的级别,人家就不理咱了(你看看电视上的微服私访).

为什么采用RPL,是考虑到安全的问题,就好像你明明对一个文件用有写权限,为什么用只读打开它呢,还不是为了安全!







------------------------------------------------------------------------------------------

代码间跳转
------------------------------------------------------------------------------------------

普通转跳(没有经过Gate 这东西):即JMP或Call后跟着48位全指针(16位段选择子+32位地址偏移),且其中的段选择子指向代码段描述符,这样的跳转称为直接(普通)跳转。普通跳转不能使特权级发生跃迁,即不会引起CPL的变化,看下面的详细描述:

    目标是一致代码段:
     要求:CPL >= DPL ,RPL不检查。

          转跳后程序的CPL = 转跳前程序的CPL
    
    目标是非一致代码段:
     要求:CPL = DPL AND   RPL<= DPL

          转跳后程序的CPL = 转跳前程序的CPL

---------------------------------------------------------------------------------------

通过调用门的跳转:当段间转移指令JMP和段间转移指令CALL后跟着的目标段选择子指向一个调用门描述符时,该跳转就是利用调用门的跳转。这时如果选择子后跟着32位的地址偏移,也不会被cpu使用,因为调用门描述符已经记录了目标代码的偏移。使用调门进行的跳转比普通跳转多一个步骤,即在访问调用门描述符时要将描述符当作一个数据段来检查访问权限,要求指示调用门的选择子的 RPL≤门描述符DPL,同时当前代码段CPL≤门描述符DPL,就如同访问数据段一样,要求访问数据段的程序的CPL≤待访问的数据段的DPL,同时选择子的RPL≤待访问的数据段或堆栈段的DPL。只有满足了以上条件,CPU才会进一步从调用门描述符中读取目标代码段的选择子和地址偏移,进行下一步的操作。

    从调用门中读取到目标代码的段选择子和地址偏移后,我们当前掌握的信息又回到了先前,和普通跳转站在了同一条起跑线上(普通跳转一开始就得到了目标代码的段选择子和地址偏移),有所不同的是,此时,CPU会将读到的目标代码段选择子中的RPL清0,即忽略了调用门中代码段选择子的RPL的作用。完成这一步后,CPU开始对当前程序的CPL,目标代码段选择子的RPL(事实上它被清0后总能满足要求)以及由目标代码选择子指示的目标代码段描述符中的DPL进行特权级检查,并根据情况进行跳转,具体情况如下:



    目标是一致代码段:
     要求:CPL >= DPL ,RPL不检查,因为RPL被清0,所以事实上永远满足RPL <= DPL,这一点与普通跳转一致,适用于JMP和CALL。
          转跳后程序的CPL = 转跳前程序的CPL,因此特权级没有发生跃迁。
                          

    目标是非一致代码段:

   当用JMP指令跳转时:
     要求:CPL = DPL (RPL被清0,不检查),若不满足要求则程序引起异常。
          转跳后程序的CPL = DPL
     因为前提是CPL=DPL,所以转跳后程序的CPL = DPL不会改变CPL的值,特权级也没有发生变化。如果访问时不满足前提CPL=DPL,则引发异常。

    当用CALL指令跳转时:

     要求:CPL >= DPL(RPL被清0,不检查),若不满足要求则程序引起异常。

          转跳后程序的CPL = DPL

     当条件CPL=DPL时,程序跳转后CPL=DPL,特权级不发生跃迁;当CPL>DPL时,程序跳转后CPL=DPL,特权级发生跃迁,这是我们当目前位置唯一见到的使程序当前执行优先级(CPL)发生变化的跳转方法,即用CALL指令+调用门方式跳转,且目标代码段是非一致代码段。
分享到:
评论

相关推荐

    这是相位一致性代码,可运行学习

    相位一致性的理论依据是人眼感知图像信息时主要靠的是图像信号的相位而非幅度。与基于灰度的边缘特征提取方法不同,该方法是通过计算图像的相位一致性来检测图像中的边缘,该方法可以不受图像局部光线明暗变化的影响...

    MyBatis表字段名与实体属性名不一致-src.zip

    MyBatis表字段名与实体属性名不一致-src.zip

    数字识别-图像预处理阶段(VC++代码)

    数字识别中的图像预处理阶段的全部代码(注释齐全),包括以下过程: (1) 将彩色图像转换为灰度图,其中有三种方法:最大值法、平均值法和各比例法; (2) 将灰度图转换为黑白图:利用阈值转换算法; (3) 梯度锐化; (4) ...

    Linux内核源代码情景分析 (上下册 高清非扫描 )

    本PDF电子书包含上下两册,共1576页,带目录,高清非扫描版本。 作者: 毛德操 胡希明 丛书名: Linux内核源代码情景分析 出版社:浙江大学出版社 目录 第1章 预备知识 1.1 Linux内核简介. 1.2 Intel X86 CPU系列...

    matlab仿真程序,二阶MASs,事件触发机制 这段代码是一个带有领导者的二阶多智能体的领导跟随一致性仿真 以下是对代码的

    这段代码是一个带有领导者的二阶多智能体的领导跟随一致性仿真。以下是对代码的分析: 1. 代码初始化了系统参数,包括邻接矩阵A、拉普拉斯矩阵L、系统的领导跟随矩阵H等。 2. 代码定义了一个二阶系统的微分方程模型...

    C++代码设计与重用

    11.3.11 保持简短的代码段 11.3.12 避免使用太大的函数 11.3.13 提供在线实例 11.4 参考手册 11.4.1 抽象化 11.4.2 语法接口 11.4.3 函数语义 11.4.4 模板参数约束 11.5 总结 11.6 练习 11.7 参考文献和...

    国家统计局 - 2018年统计用区划代码和城乡划分代码(地址编码)

    为执行国家标准,保证统计部门与民政部门名称相同的县级单位六位区划代码的一致性,国家统计局根据《统计用区划代码和城乡划分代码编制规则》(国统字〔2009〕91号),调整黑龙江省大兴安岭地区所辖的加格达奇区、...

    java代码书写规范

    本文提供一整套编写高效可靠的 Java 代码的标准、约定和指南。它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。而且,通过遵循这些程序设计标准,你作为一个 Java 软件开发者的生产效率会有显著...

    matlab矩阵一致性检验代码-photo_consistency:社区照片集的高效且稳健的色彩一致性

    matlab矩阵检验代码社区照片集的颜色一致性 这是用于以下论文的源代码 @inproceedings{Park2016, author = {Jaesik Park, Yu-Wing Tai, Sudipta N. Sinha, and In So Kweon}, title = {Efficient and Robust Color ...

    C#代码编写规范

    为了统一公司软件开发的设计过程中关于代码编写时的编写规范和具体开发工作时的编程规范,保证代码的一致性,便于交流和维护,特制定此规范。本规范适用于开发组全体人员,作用于软件项目开发的代码编写阶段和后期...

    编写高效可靠的Java 代码的标准、约定和指南

    本文提供一整套编写高效可靠的 Java 代码的标准、约定和指南。它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。而且,通过遵循这些程序设计标准,你作为一个 Java 软件开发者的生产效率会有显著...

    OpenCV将彩色视频转换为灰度视频的代码

    gray_frame, CV_BGR2GRAY )把彩色的bgr_frame帧图像转化为灰度的图像并存储到gray_frame图像实例中,于是这个gray_frame就与写入器要求的彩色三通道帧图像不一致,即分析2中的直觉:写入的帧图像存储格式和写入器...

    Python开发代码需要注意什么,用Python写一段圣诞树源码

    # Python开发代码需要注意什么 在Python开发代码时,需要注意以下几点: ...1. **保持简明扼要和清晰**: 你的代码应易于阅读和维护。这意味着避免过于复杂的逻辑,使用描述性的变量名,并始终保持代码的格式一致

    改进动态窗口DWA算法,模糊控制自适应调整评价因子权重,matlab代码,完全自己编写 这段代码是一个基于动态窗口法(Dyna

    接着,代码对地图进行了旋转,以保证地图和预期设置的地图一致。然后,获取了地图的高度和宽度。 接下来,代码设置了绘图的参数,并绘制了地图中的障碍物。障碍物的坐标保存在obstacle数组中。然后,代码定义了起始...

    Ajax跨域问题及解决方案(jsonp,cors)

     在远程服务器上设法动态的把数据装进js格式的文本代码段中,供客户端调用和进一步处理;在前台通过动态添加script标签及src属性,表面看上去与ajax极为相似,但是,这和ajax并没有任何关系;为了便于使用及交流,...

    代码编写规范Asp.Net(c#)

    为了统一公司软件开发的设计过程中关于代码编写时的编写规范和具体开发工作时的编程规范,保证代码的一致性,便于交流和维护,特制定此规范。 2 范围 本规范适用于开发组全体人员,作用于软件项目开发的代码编写阶段...

    销售管理系统实习代码

    使用图形界面,管理进货信息、销售信息和库存信息。完成功能: ① 通过菜单添加、修改各种信息; ② 可以按指定时间段查询进货清单、销售清单; ③ 按年、月、日统计销售额及利润、销售排行榜; ④ 提供盘存功能,...

    带有领导者的二阶多智能体的领导跟随一致性仿真 二阶MASs,事件触发机制

    这段代码是一个带有领导者的二阶多智能体的领导跟随一致性仿真。以下是对代码的分析: 1. 代码初始化了系统参数,包括邻接矩阵A、拉普拉斯矩阵L、系统的领导跟随矩阵H等。 2. 代码定义了一个二阶系统的微分方程模型...

    Java 编程指南(一整套编写高效可靠的 Java 代码的标准、约定和指南)

    本文提供一整套编写高效可靠的 Java 代码的标准、约定和指南。它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。而且,通过遵循这些程序设计标准,你作为一个 Java 软件开发者的生产效率会有显著...

    linux 内核源代码分析

    9.3 高速缓存与内存的一致性 9.4 SMP结构中的中断机制 9.5 SMP结构中的进程调度 9.6 SMP系统的引导 第10章 系统引导和初始化 10.1 系统引导过程概述 10.2 系统初始化(第一阶段) 10.3 系统初始化(第二...

Global site tag (gtag.js) - Google Analytics