《真象还原》读书笔记——第五章 保护模式进阶,向内核迈进(特权级)

5.4 特权级深入浅出

防止程序"越轨操作",于是给予其对应的权力。

5.4.1 特权级那点事

实际上就是检查访问者的特权级和受访者的特权级是否匹配。
特权级:0,1,2,3。数越小,权力越大。

  • 0是内核级特权直接控制硬件。
  • 1,2一般是虚拟机、驱动程序等系统服务。
  • 3不用说了,就是用户程序。
    特权级

5.4.2 TSS(任务状态段)简介

TSS (Task State Segment)任务状态段是处理器硬件原生系统级数据结构

  • 最小(不加IO位图)104字节。
  • 三个栈指针是为了不同特权级不同栈准备的。

两类特权级转移

  • 低特权级转高:中断门,调用门等
    • 要提前将高特权级的栈写入TSS中,在转高时会自动使用。
    • 不需要写3特权级的栈,因为最低,没有更低的向它转移。
    • 所以3级可以写入012,2可以写入01,1可以写入0的栈。
  • 高特权级转低:调用返回指令
    • 该操作是“回来”,因此由在“*”的时候会将低特权的堆栈指针存放在转到的高级的栈指针位置,以便于再回来时继续使用低级栈。该过程称为向外层转移,但是高等级栈指针也会丢失,如果不人为进行更新的话。

TSS 由 TR(Task Register)寄存器加载。
32位TSS结构

5.4.3 CPL和DPL入门

指令是资源的请求者,指令“请求,访问”其他资源的能力等级即为请求特权级
选择子中的RPL位代表代码请求资源能力的等级。代码段寄存器CS和指令指针寄存器EIP指向的指令就是当前处理器中正在运行的代码的等级。称为请求特权级或是当前特权级
就是说处理器当前的特权级为CS.RPL也叫CPL(Current Privilege Level 当前特权级)。转移后的段的特权级称为DPL,也就是将要成为的CPL
在段描述符中有个DPL,就是特权级。如果是当前的段,则该DPL就是当前的特权级。

DPL (Descriptor Privilege Level)描述符特权级
两个字节:可以代表 00b 01b 10b 11b特权级。

再次强调:访问者只能是代码段中的指令,因为数据段是不具备执行能力的
当前的访问者只能说代码段DPL :.

  • 受访者为数据段:只有 访问者DPL权限大于等于被访问者DPL权限才能继续访问。
  • 受访问者为代码段:只有 访问者DPL权限==被访问DPL权限才能访问,即平级访问。
  • 唯一的特殊情况:中断发生后,处理器从中断处理程序中返回到用户态。这是由高特权到低特权的。

不过该过程也仅仅是在目标段被访问的时候检查一下罢了。

既能执行高权限代码又不会获得高权限的方法。

利用一致性代码段。

段描述符中type中的C位来表示该段是否为已执行代码段。
1:一致性代码段。0:非一致性代码段。
非一致性只能平级转移。

一致性代码段又称依从代码段

  • 转移后的DPL权限一定要大于转移前的CPL权限。
    • 数值上:CPL(转移前) >= 一致性代码段DPL(转移后),比方3>=0。
    • 转移后的特权级不会被DPL替换,而是保持原本的CPL,并未提升。
    • 代码段可以有一直和非一致,但数据段只有非一致。

5.4.4 门,调用门与RPL序

门描述符和段描述符类似,都是8字节大小的数据结构。

任务门描述符格式
终端门描述符格式
陷阱门描述符格式
调用门描述符格式
除了任务门外,其他的对应的是一段函数。存放的是选择子和偏移量。

  • 任务门可以放在GDT,LDT和IDT中。
  • 调用门可以位于GDT,LDT中。
  • 中断、陷阱门仅位于IDT中。

任务门、调用门都位于描述符表中,访问它们和普通的段描述符是一样的,必须通过选择子。
陷阱门和中断门只存在于IDT中,不能主动调用,只能通过中断信号触发。
任务门用任务TSS的描述符选择子来描述一个任务。

提供的四种门都可以实现从低特权级的代码段到高特权级的代码段。

  1. 调用门:call和jmp指令后接调用门选择子。
  2. 中断门:以int指令主动发中断。linux系统调用此中断门实现。
  3. 陷阱门:int3指令主动发中断。一般是编译器调试的时候。
  4. 任务门:任务以任务状态段TSS为单位,用来实现任务切换,也可以借助中断或指令发起。

访问者的特权级再低也不能比门描述符的DPL特权低。
门的作用
三者关系:

  • 门的特权级要低于等于当前特权级。
  • 当前特权级要低于等于目标特权级。

**在调用门为了实现例程时,会通过压栈的方式传入参数。会造成一个问题:低特权的时候在低特权栈中传入参数,调用高特权后,那参数这么搬到高特权栈中?事实上,处理器在固件上已经实现了自动复制,会将用户进程压在3特权栈中的参数自动复制到0特权栈中。**调用门的高32位中,前5位就是参数个数。最多31个参数。

5.4.5 调用门的过程保护

三特权通过call使用调用门到特权级0

  1. 在call调用门之前在3特权级栈中压入参数。调用门控制转移前用户栈
  2. 根据门描述符中选择子对应的目标代码段DPL,这里假设为0。处理器自动在TSS中找到合适的栈段选择子SS和栈指针ESP,它们作为转移后的新栈。记为 SS_new ESP_new。
  3. 检查新栈段选择子对应的DPL和type,如果未达标则处理器引发异常。
  4. 如果转移后的DPL比CPL更高。为了特权级转换,需要切换到新栈。转移前也要将SS_old和ESP_old存入新栈中。这样才能在恢复时返回。而在未加载SS_new和ESP_new时,处理器会先找个地方临时保存两个old。之后将两个new加载到栈段寄存器和栈指针寄存器中。
  5. 启动新栈后将ss_old和esp_old压入新栈中,因为是新栈32位,旧的16位高位由0填充。
    特权级转移新栈
  6. 根据调用门描述符中的参数个数决定复制几个参数。
  7. 使用调用门调用后,将旧的cs,eip加载到栈中。
  8. 加载调用门中的代码段选择子到cs,将偏移量加载到eip。
    如果是平级转移,则当作直接远转移,跨过中间几步,直接做第7部。
retf指令从调用门返回的过程
  1. 检查cs选择子的rpl位。
  2. 栈中弹出eip_old到eip,弹出cs_old到cs中。
  3. 跳开参数,让esp_new指向esp_old.
  4. 将esp_old加载到esp寄存器和ss_old加载到ss寄存器。

如果ds没有人为修改,还是高权限的话会被填充0,指向0哑描述符,引发处理器异常。

5.4.6 RPL的前世今生

RPL(Request Privilege Level)请求特权级:真正资源请求者的CPL
在请求某特权等级资源时,检查的不只有CPL还有RPL。
RPL和CPL的特权必须同时大于等于受访者的特权DPL。
恍然大悟特权级

5.4.7 IO特权级

IO位图只有在数值上CPL>IOPL,当前特权级比IOPL低时才有效,若当前特权级高于IOPL时,任何端口都可以直接访问。
I/O位图位于TSS中,可以存在,可以不存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值