《X86汇编-从实模式到保护模式》14. 任务和特权级保护

DPL

  • 对于数据段来说,决定了访问它们所应当具备的最低特权级。

    CPL <= DPL
    

    假设 DPL 为 2,则只有特权级为 0、1、2 的程序才可访问它。

CPL

  • 当前处理器正在执行的代码段,则该代码段的特权级称为当前特权级。
  • 位置:选择子位于 CS 寄存器中,最低两位就是当前特权级的值。

特权指令

  • 指令当前特权级 CPL 为 0 时才能执行的指令,称为特权级指令。

RPL - 请求特权级

无论是通过 jmp / call 指令,并且提供目标代码段的选择子,转移到其它代码段。还是访问内存数据,通过一些寄存器,且提供段选择子加载到段寄存器中。
这些都可以看做是一个请求,请求者提供一个段选择子,请求访问某个代码段,又或者是请求访问内存数据。
在大多数时候,请求者都是当前程序自己,因此 CPL = RPL,要判断请求者是谁,最简单的方法就是看谁提供的选择子。

[SECTION A] ; 书上没有这个,放在这只是为了方便理解
  jmp dword 0x0010:flush ; 由当前 A 段提供的选择子,向 CS 请求 0x0010
[SECTION A]
  mov eax, 0x0008 ; 这里并不触发 RPL,只是单纯把值传入 EAX
  mov ds, eax ; 由当前 A 段提供的选择子,向 DS 请求 0x0008

当然,也有 CPL != RPL 的情况:
image-20220925215435457
特权级为 3 的应用程序想要访问磁盘,只能通过调用特权级为 0 的例程来实现,但必须通过调用门,因为特权级间的控制转移必须通过门。假设必须传入三个参数,分别为 CX 中保存的数据段选择子、EBX 寄存器中保存的段内偏移,以及 EAX 中的逻辑扇区号。
高特权级别的程序可以访问低特权级别的数据段。 因此操作系统会使用传入的参数 CX 中的数据段选择子,将其代入段寄存器:

mov ds, cx

在执行这条执行时,CX 中的段选择子,其中 RPL 字段值为 3,当前特权级 CPL 变为 0,因为通过 call 调用门可以改变当前特权级。
而请求者并非当前程序(即特权级为 0 的例程),而是特权级为 3 的应用程序,RPL != CPL。
在这里插入图片描述

如图所示,假设应用程序已知操作系统数据段的选择子,希望通过这个选择子访问操作系统的数据段。这显然不可能,因为操作系统中的数据段 DPL 为 0,而应用程序的 CPL 为3,处理器会拒绝该访问。
但是,可以借助调用门。调用门工作在目标代码段的特权级上,一旦处理器的执行流离开应用程序,通过调用门进入操作系统例程是,当前特权级从 3 变为 0。当某个恶意程序将一个执行操作系统的数据段的选择子通过 CX 寄存器作为参数传入调用门时,因为当前特权级已经从 3 变为 0,因此可以从磁盘读写数据。

引入请求特权级(RPL) 的原因是处理器在遇到一条将选择子传送到寄存器的指令时,无法区分真正的请求者是谁。
就拿上面的图来说,应用程序通过调用门调用内核例程,并且传入 CX 内容为指向内核数据段的选择子,内核例程中有这么一条语句 mov ds, cx。此时虽然我们可以人为分析出来,请求者是应用程序,但处理器并不知道请求者到底是应用程序还是内核例程。
引入 RPL 并不能解决这个问题,这只是处理器和操作系统之间的一种协议。

每当处理器执行一个将段选择子传送到段寄存器(DS、ES、FS、GS)的指令时,会检查以下两个条件是否都满足:

  • 当前特权级 CPL 高于或和数据段描述符的 DPL 相同。

    CPL <= 数据段描述符的 DPL
    
  • 请求特权级 RPL 高于或和数据段描述符的 DPL 相同。

    RPL <= 数据段描述符的 DPL
    

若以上两个条件不能同时成立,则处理器就会阻止这种操作,并引发异常。

引入 RPL 的意图是 “确保特权代码不会代替应用程序访问一个段,除非应用程序自己拥有那个段的权限”。

栈段

处理器要求,在任何时候,栈段的特权级别必须和当前特权级 CPL 相同。因此,要对段寄存器 SS 进行修改时,必须进行特权级检查。

mov ss, ax ; 修改 SS

在对段寄存器 SS 进行修改时,要求当前特权级 CPL 和请求特权级 RPL 必须等于目标栈段描述符的 DPL。即在数值上:

CPL = 目标栈段描述符的 DPL
RPL = 目标栈段描述符的 DPL

特权级转移

一般来说,控制转移只允许发生在两个特权级相同的代码段之间。

低特权返回高特权

第一种方法:将高特权级的代码段定义为依从的。
在段描述符中,有个 TYPE 字段,其中的 C 位,若 C = 0,则该代码段只可被相同的特权级所调用。若 C = 1,则该代码段为依从的代码段。

// 若要调用某个过程,则需要满足:
CPL >= 目标代码段描述符的 DPL

若要调用的目标过程的 DPL 为 1,则该代码段只能被特权级分别为 1、2、3 的代码段所调用。

第二种方式:通过调用门。

高特权转移到低特权

不允许直接从高转移到低,只能通过 ref 或 iret 才能实现从高特权转移到低特权级。

门的类型:

  • 调用门:用于不同特权级之间的切换。
  • 中断门 / 陷阱门:作为中断过程使用。
  • 任务门:对应单个任务,用来执行任务切换。

通过调用门进行转移:jmp far 或 call far 指令,将调用门描述符的选择子作为操作数进行转移。

  • jmp far:可以将控制通过门转移到当前特权级高的代码段,但不改变当前特权级。
  • call far:可以将控制通过门转移到当前特权级高的代码段,同时将当前特权级提升到目标代码段的特权级别。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
x86汇编语言从实模式保护模式》是一本经典的计算机软件和硬件教材。该书通过详细讲解x86汇编语言模式保护模式两个阶段的特点和转换过程,帮助读者深入了解计算机的底层工作原理。 模式是早期x86处理器的工作模式,它具有简单和直接访问内存的特点,但存在一些限制,例如只能寻址最多1MB的内存空间。《x86汇编语言从实模式保护模式》首先介绍了模式的基本概念和操作指令,然后通过际的编程示例,让读者熟悉模式下的汇编语言编程。 接着,《x86汇编语言从实模式保护模式》详细介绍了保护模式的内存管理、特权和中断处理等概念和机制。保护模式是现代操作系统常用的工作模式,它具有更强大的内存管理能力和安全性,可以有效地利用计算机的资源。通过学习保护模式的相关知识,读者可以了解操作系统的内核和应用程序的执行过程,并且能够编写更强大和高效的程序。 《x86汇编语言从实模式保护模式》还介绍了x86处理器的特殊指令和编程技巧,例如x87浮点指令和SSE指令集等。这些指令和技巧可以提高程序的性能和效率,使程序员能够充分发挥x86体系结构的优势。 总之,《x86汇编语言从实模式保护模式》是一本全面且用的教材,通过对x86汇编语言的学习,读者可以更深入地了解计算机的底层原理和操作系统的工作方式。无论是想成为程序员还是深入研究计算机体系结构的人员,这本书都是一本必读之作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值