保护模式3-段描述符属性

段寄存器位96位但是可见位数只有16位,剩下80位怎么填充?80位里每一位代表什么意思?

保护模式3-段描述符属性

上面为段描述符的结构

这里学习一下怎么快捷使用gdt表和idt表,还有拆分段描述符

0: kd> r gdtr //常规访问gdt表
0: kd>dq 8003f000
0: kd> dq gdtr //当进一步缩写时
//如果我们要查看段描述符,需要对照查看
0: kd> dq 8003f008
8003f008 00cf9b00`0000ffff
0: kd> dq 8003f010
8003f010 00cf9300`0000ffff
//当使用dg命令时:
0: kd> dg 08
 P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0008 00000000 ffffffff Code RE Ac 0 Bg Pg P Nl 00000c9b
//
0: kd> dg 10
 P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0010 00000000 ffffffff Data RW Ac 0 Bg Pg P Nl 00000c93

P位(15):段描述符有效位

P=1 段描述符有效

P=0 段描述符无效

DPL位(13-14):访问该段的权限级别(Descriptor Privilege Level)

S位(12): 系统段描述符/用户段描述符

S=1 代码段或者数据段描述符

S=0 系统段描述符

P+DPL+S位联合拆解:

p位 DPL DPL S位 TYPE TYPE

TYPE TYPE 15

14 13 12 11 10 9 8 1 1/01/0 1/0 1/0 1/0 1/0 1/0

p位为1时段描述符才有效,DPL只能同时为1或者同时为0,S位为1时才是代码段或者数据段

当12位到15位

情况1:P位一定为1,DPL为3(11),S位为1,这个段描述符有效,且DPL为3,是系统段描述符

那么12到15位就是F

情况2: P位一定为1,DPL为0(00),S位为1, 这个段描述符有效,且DPL为0,是系统段描述符

那么12到15位就是9

00cffb00`0000ffff
00cf9b00`0000ffff

情况3: P位一定为1,DPL为0(00),S位为0,这个段描述符有效,且DPL为0,是用户段描述符

80008b04`200020ab

-------------------------------------------------------------------------------------------------------------------------------------------------------------- TYPE位(8-11):属性位,由S位来决定TYPE位的属性 --------------------------------------------------------------------------------------------------------------------------------------------------------------

当S位为1的时候,TYPE位里是数据段或者代码段

保护模式3-段描述符属性

8到11位决定了是代码段描述符,还是数据段描述符

数据段描述符

  1. 0-只读
  2. 1-只读,并且被访问过
  3. 2-可读,可写
  4. 3-可读,可写,并且被访问过
  5. 4-只读,向下扩展
  6. 5-只读,向下扩展,并且被访问过
  7. 6-可读,可写,向下扩展
  8. 7-可读,可写,向下扩展,并且被访问过

向下扩展属性位:

保护模式3-段描述符属性

代码段描述符:

  1. 8-只可执行
  2. 9-只可执行,被执行过1次以上
  3. A-可执行,可读
  4. B-可执行,可读,被执行过1次以上
  5. C-只可执行,一致代码段
  6. D-只可执行,一致代码段,被执行过一次以上
  7. E-可执行,可读,一致代码段
  8. F-可执行,可读,一致代码段,被执行过一次以上

一致代码段:

简单理解,就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码

通常这些共享代码,是"不访问"受保护的资源和某些类型异常处理。比如一些数学计算函数库,为纯粹的数学运算计算

一致代码段的限制作用

特权级高的程序不允许访问特权级低的数据: Ring3不允许调用Ring0的数据

特权级低的程序可以访问到特权级高的数据 但是特权级不会改变: 权限不会发生切换,不会从Ring3进入Ring0

非一致代码段的限制作用

只允许同级间访问

绝对禁止不同级访问: 核心态不用用户态.用户态也不使用核心态

通常低特权代码必须通过""来实现对高特权代码的访问和调用

这里了解即可

拆分用户段TYPE位实战

这里有一个技巧

当TYPE为数据段描述符的时候,第11位一定为0

当TYPE为代码段描述符的时候,第11位一定为1

当TYPE位4个属性位组合成一个16进制数的时候,当这个数大于8则一定是代码段描述符,小于8则是数据段描述符,如果不懂建议去搬砖

-----3--`-------- //数据段描述符,可读,可写,被访问过
-----b--`-------- //代码段描述符,可执行,可读,并且被执行了1次以上
-----9--`-------- //代码段描述符,只可执行,并且被执行了1次以上
-----2--`-------- //数据段描述符,只读,并且被访问过

当S位为0的时候,TYPE位里是系统段描述符

保护模式3-段描述符属性

  1. 0-保留
  2. 1-可获得的16位TSS
  3. 2-LDT
  4. 3-繁忙的16位TSS
  5. 4-16位调用门
  6. 5-任务门
  7. 6-16位中断门
  8. 7-16位陷阱门
  9. 8-保留
  10. 9-可获得的32位TSS
  11. A-保留
  12. B-繁忙的32位TSS
  13. C-32位调用门
  14. D-保留
  15. E-32位中断门
  16. F-32位陷阱门
实战拆解系统段描述符
-----3--`-------- //繁忙的16位TSS
-----c--`-------- //32位调用门
-----7--`-------- //16位陷阱门
-----f--`-------- //32位陷阱门

TYPE位检查

当CPU使用段或者门的时候,其中的检查步骤之一就是检查GDT表中的的段描述符的TYPE位的属性,当

GDT表中存在中断门的时候,通过call或者jmp访问中断门的时候,CPU就会在硬件层面抛出一个异常

保护模式3-段描述符属性

--------------------------------------------------------------------------------------------------------------------------------------------------------

实战P位+DPL位+S位+TYPE位联合拆解,直接拆分GDT表的内容

00cf9b00`0000ffff //这个段描述符有效,DPL为3(11),S位为1,是用户段描述符,且是代码段描述符,只可执行,并且被执行了1次以上
00cf9300`0000ffff //这个段描述符有效,且DPL为0(00),S位为1,是用户段描述符,且是数据段描述符,可读,可写,并且被访问过
80008b04`200020ab //这个段描述符有效,且DPL为0(00),S位为0,是系统段描述符,且是繁忙的32位TSS
0000f200`0400ffff //这个段描述符有效,切DPL为3(00),且S位为1,是用户段描述符,且是数据段描述符,可读可写
 

--------------------------------------------------------------------------------------------------------------------------------------------------------

G位(23):粒度 字节/页

我们先看看段描述符的结构

Struct SegMent
{
WORD Select; //16位段选择子
WORD Attributes; //16位属性
DWORD Base; //32位基址
DWORD Limit; //32位段限长
}

除去16位段选择子,剩下16位属性,32位基址,32位段限长,16+32+32为80位

段基址位(0-8位+24-31位)[32位]+(16-31位)

段限长16-19位+0-15位,只有20位,剩下的12位怎么填充呢?由G位来决定

如果 G = 0,把段描述符中的LIMIT取出来,比如 0xfffff,然后在前面补 0 至32bit,即 limit = 0x000fffff
如果 G = 1,把段描述符中的LIMIT取出来,比如 0xfffff,然后在后面补 f 至32bit, 即 LIMIT = 0xffffffff

G位存在的意义除了填充属性位以外:兼容 优化

当系统使用TSS段的时候,每个TSS大小至少为104个字节

保护模式3-段描述符属性

当前正在运行的CPU里的线程为2529,如果存在G位,每个线程的TSS加起来才使用了256KB

如果没有G位,内存分页为4K小页时。占用内存为10M,如果为大页,则会非常耗费空间,这里只做了解

如果没有 G 位,将会极大浪费内存空间

DB位(22):扩展属性位,争对不同的段描述符有不同的影响,通常由S位来决定DB位的作用

代码段 D:默认操作数大小-32位系统里加指令前缀当成16位来操作

数据段 B:扩展属性位

向上扩展:Base起始地址,Limit最大有效地址

向下扩展:Limit最低有效地址 最高地址由DB位中的B来决定

B=0:64K B=1:4G

情况一:对CS段的影响

情况一:对CS段的影响

D = 0 采用16位寻址方式

前缀67 改变寻址方式

67:8965 FF MOV DWORD PTR DS:[DI+FFFF],ESP //DI 16位

情况二:对SS段的影响

D = 1 隐式堆栈访问指令(如:PUSH POP CALL) 使用32位堆栈指针寄存器ESP

D = 0 隐式堆栈访问指令(如:PUSH POP CALL) 使用16位堆栈指针寄存器SP

隐式堆栈访问(比如PUSH EAX的时候,并没有动ESP寄存器,但是堆栈会自动变化)

情况三:向下拓展的数据段

D = 1 段上限为4GB

D = 0 段上限为64KB

保护模式3-段描述符属性

AVL(20):可以获取,CPU与OS都没有使用

自由发挥

保护模式3-段描述符属性


分享到:


相關文章: