重新认识Intel权限检查(一)

文章系列:
重新认识Intel权限检查(一)
重新认识Intel权限检查(二)

文章目录

原理

权限检查作为保护模式的一种表现在386被引入,本章介绍不使用调用门时的权限检查,不涉及特权级变化。

  • 检查原则
    一句话概括,代码段分一致和非一致,一致代码段允许同级和低级代码跳转访问,非一致代码段只允许同级访问;数据段总是非一致的,不允许低级代码访问,只允许同级代码访问。一致性代码被访问时RPL不参与权限检查。
    高级代码访问低级代码和数据涉及特权级变化,这里不做讨论。
    一致代码:Conforming Code
    非一致代码:None-Conforming Code
  • 相关结构和寄存器
    • RPL(Request Privilege Level),CPU请求权限,保存在段选择子中。
      在这里插入图片描述

    • CPL(Current Privilege Level),CPU当前权限,保存在CS中。

      在这里插入图片描述

    • DPL(Descriptor Privilege Level),段描述符权限,保存在描述符属性域中。

      在这里插入图片描述

  • 代码访问检查流程
    • CPU执行转移指令,获取段选择子
    • GDT/LDT中查找描述符(TI=0,GDT;TI=1,LDT)
    • 如果段类型为一致代码段,CPL权限小于等于DPL就符合权限,可以跳转。RPL值不考虑。
    • 如果段类型为非一致代码段,CPL权限等于DPL同时RPL不能低于DPL,可以跳转。RPL需要考虑。
    • 如果段类型为数据段

实验

  • 准备阶段
    系统上电到保护模式后默认是ring0,处于最高特权级,想要验证时需要retf返回到低特权级,这里选择ring2。贴出跳转到ring2的关键代码。进入保护模式代码参见重新认识intel段机制寻址方式
    主要流程
    • 准备ring2堆栈段和代码段
    • 计算ring2堆栈段基址和代码段基址,填入描述符表
    • 计算ring2堆栈段选择子和代码段选择子
    • 堆栈选择子压栈,堆栈Top压栈,代码段选择子压栈,retf
1)准备ring2堆栈段
; ring2 堆栈段
[SECTION .s2]
ALIGN   32
[BITS   32]
LABEL_STACK2:
    times   32  db  0
TopOfStack2     equ $   -   LABEL_STACK2    -   1
; end of .s2
2)准备ring2代码段,复用ring0的代码,复用手段:准备两条描述符权限分别是ring2和ring0,描述符中基址指向同一段代码。
[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS   32]
LABEL_SEG_CODE32:
    str ax
    cmp ax, SelectorTSS ; 检查TR是否被加载,如果加载不再重复
    je  .1

    mov ax, SelectorTSS ; 加载TR
    ltr ax
.1:
    mov ax, cs
    and ax, 10b
    cmp ax, 10b         ; 判断CPL
    je  .2              ; 如果CPL!=2,retf到ring2,否则跳转到.2执行测试代码

    push    SelectorStack2	;ring2堆栈段选择子压栈
    push    TopOfStack2		;栈顶指针压栈
    push    SelectorCode32R2	;ring2代码段选择子压栈
    push    0
    retf
3)计算段基址,填入描述符表
[SECTION .gdt]
; GDT
;                             				 段基址,       段界限     , 属性
LABEL_GDT:     Descriptor       0,              0,      0   ; 空描述符
LABEL_DESC_CODE32: Descriptor   0, SegCode32Len - 1,    DA_C + DA_32; 非一致代码段
LABEL_DESC_CODE32R2: Descriptor 0, SegCode32Len - 1,    DA_C + DA_32 + DA_DPL2; 非一致代码段
    ; gdt初始化 32 位代码段描述符
    xor eax, eax
    mov ax, cs
    shl eax, 4
    add eax, LABEL_SEG_CODE32	; 指向LABEL_SEG_CODE32
    mov word [LABEL_DESC_CODE32 + 2], ax
    shr eax, 16
    mov byte [LABEL_DESC_CODE32 + 4], al
    mov byte [LABEL_DESC_CODE32 + 7], ah
    ; gdt初始化 32 位代码段描述符 ring2
    xor eax, eax
    mov ax, cs
    shl eax, 4
    add eax, LABEL_SEG_CODE32	; LABEL_SEG_CODE32
    mov word [LABEL_DESC_CODE32R2 + 2], ax
    shr eax, 16
    mov byte [LABEL_DESC_CODE32R2 + 4], al
    mov byte [LABEL_DESC_CODE32R2 + 7], ah
  • 测试阶段
    • 目的段是一致码段,RPL=3,CPL=2,DPL=2,Confoming
      RPL不参与权限检查,无论RPL是0,1,2,3都无所谓
      关键代码
LABEL_DESC_CODE32R2: Descriptor 0, SegCode32Len - 1,    DA_CCO + DA_32 + DA_DPL2; 一致代码段
SelectorCode32R3    equ (LABEL_DESC_CODE32R2- LABEL_GDT) + SA_RPL3
.2:                     ; 测试代码,CPL=2
    mov ax, SelectorVideo
    mov gs, ax          ; 视频段选择子(目的)
    mov edi, (80 * 11 + 79) * 2 ; 屏幕第 11 行, 第 79 列。
    mov ah, 0Ch         ; 0000: 黑底    1100: 红字
    mov al, 'P'
    mov [gs:edi], ax

    call    SelectorCode32R3:0  ; RPL = 3, CPL = 2, DPL = 2 Confoming  
SegCode32Len    equ $ - LABEL_SEG_CODE32

在这里插入图片描述
确认:callf 0x0013:00000000低4bit 0x3,RPL=3,cs:0x0012CS低4bit 0x2,CPL=2,CS指向的描述符高双字dh=0x0040dd00取其中DPL所在byte为0xd=1101b,DPL=2。同时DPL为一致码段。

  • 目的段是非一致码段,RPL=1,CPL=2,DPL=2,Non-Confoming,检查通过
    CPL必须等于DPL的同时,RPL要参与检查,必须权限大于等于DPL,小于DPL则不通过。
    在这里插入图片描述
  • 目的段是非一致码段,RPL=3,CPL=2,DPL=2,Non-Confoming,检查不通过
    CPL必须等于DPL的同时,RPL要参与检查,必须权限大于等于DPL,小于DPL则不通过。
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

享乐主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值