zoukankan      html  css  js  c++  java
  • 汇编学习笔记(17)

    特权级的基本概念

    CPL 当前代码的特权级 = CS寄存器中的RPL

    RPL 选择子中要求的特权级

    DLP 目标段中要求的特权级

    好比如说我是ROOT 用户拥有root权限, 我是用读权限打开一个文件, 这个文件的权限是 777 

    CPL = ROOT 权限

    RPL = 读权限

    DLP = 777 

     数据段的装载 

    ss 寄存器

      1. 可读写数据段
      2. CPL=DL=RPL

     

    其他数据段寄存器

      1. 可读可写数据段,可读代码段
      2. CPL<=DPL, RPL<=DPL

     

    运行权的变更(CS的装载 )

     指向代码段

    JMP

    CALL

    要求

    非一致代码,CPL = DPL, RPL<=DPL

    一致代码,CPL >= DLP

    结果

    CS 的INDEX 和TI 被改变 而CPL不变

    RET

    要求

    RPL = CPL

    RET返回使用的是之前CS的选择子,因为在CALL的时候CPL是不变的,所以无意外的话RPL=CPL总是成立的之后就相当于CALL 和 JMP 了

    提炼:

      1. 特权级永远不会变
      2. 对于转入非一致代码 要求 CPL = DPL,则强制规定了 非一致代码只能同级转入
      3. 对于转入一致代码要求CPL >= DLP, 则一致代码只能同级或者从外层向内转,但是无论哪种情况特权级不变
      4. RET 用的是压在堆栈中的之前的CS,所以 RPL=前 CPL, 因为CPL保持不变所以 前CPL=CPL总成立,所以RET的首要条件总是满足
      5. 由于 非一致代码要求 CPL = DPL 和 一致代码要求 CPL >= DPL 的要求看,而CPL不变,所以合法的调用链中 CPL >= DLP 是永远成立的
      6. 由4可知RPL就是CPL的压栈,而CPL不变,所以可知RPL = CPL, 所以得出结论,调用栈中  RPL=CPL>=DLP
      7. 一致代码不要求 RPL,所以从一致代码返回一致代码是可能出现的RPL > DLP的情况被忽略,而因为非一致代码都是CPL=DPL的,所以无论从何处返回非一致代码 情况都是 CPL=DPL=RPL(满足6中RPL=CPL>=DLP的情况),也能正常返回

     

    小结

    1. 使用CALL 和 JMP的时候根据转移目标代码的不同需要满足如下情况

    目标是非一致代码:CPL = DPL, RPL<=DPL

    目标是一致代码: CPL >= DLP

    2. CPL 永远不变

    3. 只要CALL满足执行条件 对应的RET永远也满足条件

     

     

    指向调用门

    首先指向门的调用中只有选择子有效,偏移地址是会被忽略的

    其次调用门有自己DPL,所以想要使用调用门需要满足如下场景

    CPL <  门DPL, RPL < 门 DPL

    满足条件之后会从调用门中取出选择子和偏移地址,来替换掉转移指令中的选择子和偏移地址,在替换之前会将新选择子的RLP设为0,也就是说门中的选择子的RPL是没意义的始终会被替换成0. 

    之后和 直接指向段的转跳大致相当,只要当使用CALL指令转移到非一致代码的情况有特殊

    当使用CALL指令指向的调用门指向了非一致代码段的时候

    如果出现 CPL > DPL的情况 在直接指向的情况下是会出错的,但是在指向门的情况下 会出现 设置CPL = DPL,也就是说出现提权的情况。

    对应的RET指令在发现RPL>CPL的时候,也会设置CPL = RPL 也是就说降权。

    注意:权限切换的时候还涉及到堆栈的切换,这个将在任务门相关内容的时候解释。

     

    小结

          1. 指向门是只有选择子有效,偏移地址无意义

          2. 调用的时候会有 CPL <  门DPL, RPL < 门 DLP 的验证

          3. 实际调用的地址由门给出,同时实际调用的RPL总是0

          4. 其他调用规则同直接指向一致,唯一的区别是当CALL实际指向的地址是非一致代码的时候如果出现 CPL > DPL 的情况不会调用失败,而是设置CPL = DPL,对应的RET会发现RPL>CPL的时候会设置CPL=RPL,这里的RPL实际就是CALL指令压栈的CS寄存器的CPL,也就是或恢复特权级。

    指向TSS数据

    要求权限,CPL <=DPL RPL<= DPL

    调用指令中的偏移地址被忽略,CPU直接用TSS中的数据直接切换任务(线程)了。

    指向任务门

    和直接指向TSS的数据没啥区别,就是多了些权限检测

    首先检测 CPL < 门DPL, RPL <= 门DPL

    然后检测 CPL < TSS的DPL, 门RPL <= TSS的DPL

    然后就使用TSS的数据切换任务,指令和门中的偏移都没意义。

    注意这里用JMP和用CALL 是有一点区别的

    CALL 会引起任务的嵌套,所以使用CALL进行任务门的调用的话是可以用RET返回原来的任务的

         

     特权级切换时堆栈的切换

          在特权级发生切换的时候会有堆栈的切换,每个特权级都有自己的堆栈,这些地址是被保存在TSS中的,而且 0 1 2 这三个特权级的堆栈,在每次进去时候都会被重置,也就是说不会保留上次进入时的痕迹,而为了在特权级变更的时候传递参数,都会发生内存的拷贝,至于拷贝的字节数,任务门是有任务门的双字节字段决定,中断门和陷阱门有中断或者异常类型自动决定。

  • 相关阅读:
    常见的7种排序算法
    ZooKeeper
    线上问题排查(2)——JDK内置工具
    Java并发编程:深入剖析ThreadLocal
    没有main的hello world 程序——Java 分类: java 2015-06-24 16:20 11人阅读 评论(0) 收藏
    Django笔记 —— 模型
    Django笔记 —— MySQL安装
    USACO Section2.3 Controlling Companies 解题报告 【icedream61】
    USACO Section2.3 Money Systems 解题报告 【icedream61】
    USACO Section2.3 Zero Sum 解题报告 【icedream61】
  • 原文地址:https://www.cnblogs.com/alwaysking/p/12345946.html
Copyright © 2011-2022 走看看