posts - 95,comments - 0,views - 12768

特权级

特权级总共有4个级别,数字越小表示的特权级越大

特权级

  • CPL - Current Privilege Level(当前特权级):用于指示处理器当前运行的特权级别
  • DPL - Descriptor Privilege Level(描述符特权级):用于指示段描述符或门描述符的特权级别。每个段描述符或门描述符都有一个DPL字段,它决定了访问该段或门的特权级别限制
  • RPL - Requested Privilege Level(请求特权级):这是指x86架构中在进行段选择器加载或者调用门调用时,请求访问某个段或门时指定的特权级别
    • RPL指定了进程在访问某个段或门时所希望的特权级别,它可以是0、1、2或3,与CPL进行比较决定是否允许访问

特权级转移

  • 通过jmp或call进行直接转移
    • 目标为非一致代码段:CPL=DPL 且 RPL<=DPL
    • 目标为一致代码段:CPL>=DPL
  • 运用门描述符
    • 调用门 (Call gates)
    • 中断门 (Interrupt gates)
    • 陷阱门 (Trap gates)
    • 任务门 (Task gates)

门描述符

  • 门描述符结构

门描述符

  • 门描述符定义
; 门
; usage: Gate Selector, Offset, DCount, Attr
;        Selector:  dw
;        Offset:    dd
;        DCount:    db
;        Attr:      db
%macro Gate 4
    dw  (%2 & 0FFFFh)               ; 偏移1
    dw  %1                          ; 选择子
    dw  (%3 & 1Fh) | ((%4 << 8) & 0FF00h)   ; 属性
    dw  ((%2 >> 16) & 0FFFFh)        ; 偏移2
%endmacro ; 共 8 字节

通过调用门进行有特权级变换的转移

特权级变换的转移的复杂之处,不但在于严格的特权级检验,还在于特权级变化的时候,堆栈也要发生变化

由于每一个人物最多都可能在4个特权级间转移,所以每个任务实际上需要4个堆栈

自身已经有了一个ss和esp,当发生堆栈切换时,从TSS(Task-State Stack)这个数据结构中获得

TSS 偏移4到偏移27的字段中存储另外3个堆栈的信息
tss

  • 低--->高:通过调用门和call指令实现

步骤:

  1. 准备好TSS信息(TSS数据结构的字段信息---新堆栈、描述符、选择子的初始化)
; TSS数据结构的字段信息---新堆栈
[SECTION .tss]
ALIGN   32
[BITS   32]
LABEL_TSS:
         DD  0           ; Back
         DD  TopOfStack      ; 0 级堆栈
         DD  SelectorStack   ; 
         DD  0           ; 1 级堆栈
         DD  0           ; 
         DD  0           ; 2 级堆栈
         DD  0           ; 
         DD  0           ; CR3
         DD  0           ; EIP
         DD  0           ; EFLAGS
         DD  0           ; EAX
         DD  0           ; ECX
         DD  0           ; EDX
         DD  0           ; EBX
         DD  0           ; ESP
         DD  0           ; EBP
         DD  0           ; ESI
         DD  0           ; EDI
         DD  0           ; ES
         DD  0           ; CS
         DD  0           ; SS
         DD  0           ; DS
         DD  0           ; FS
         DD  0           ; GS
         DD  0           ; LDT
         DW  0           ; 调试陷阱标志
         DW  $ - LABEL_TSS + 2   ; I/O位图基址
         DB  0ffh            ; I/O位图结束标志
TSSLen      equ $ - LABEL_TSS

     ; 初始化 TSS 描述符
     xor eax, eax
     mov ax, ds
     shl eax, 4
     add eax, LABEL_TSS
     mov word [LABEL_DESC_TSS + 2], ax     ; LABEL_DESC_TSS为TSS的描述符
     shr eax, 16
     mov byte [LABEL_DESC_TSS + 4], al
     mov byte [LABEL_DESC_TSS + 7], ah

  1. 加载TSS
; Load TSS
mov ax, SelectorTSS
ltr ax  ; 在任务内发生特权级变换时要切换堆栈,而内层堆栈的指针存放在当前任务的TSS中,所以要设置任务状态段寄存器 TR。

假设由代码A到代码B,运用一个调用门G
规则

  • 高--->低:通过带参数的ret指令实现

步骤:

  1. 准备好代码段和堆栈段(描述符、选择子的初始化)
  2. 准备好目标代码段的cs、eip以及ss、esp(依次将ss、esp、cs、eip压入栈中)
push    SelectorStack3        ; ss,堆栈段的选择子
push    TopOfStack3           ; esp
push    SelectorCodeRing3     ; cs,代码段的选择子
push    0                     ; eip
retf                          ; Ring0 -> Ring3
  1. 执行retf 指令
posted on   Dylaris  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示