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 这三个特权级的堆栈,在每次进去时候都会被重置,也就是说不会保留上次进入时的痕迹,而为了在特权级变更的时候传递参数,都会发生内存的拷贝,至于拷贝的字节数,任务门是有任务门的双字节字段决定,中断门和陷阱门有中断或者异常类型自动决定。

  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/alwaysking/p/12345946.html
Copyright © 2011-2022 走看看