首页 > 编程知识 正文

gdt全局描述符表,gdt符号

时间:2023-05-06 07:04:25 阅读:256542 作者:2650

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

GDT表与段描述符

一、介绍

如果之前学习过“实模式”,那很明白“段”的意义,在实模式中采用“段+偏移”的机制寻址。

现在,我们使用“保护模式”,内存对于我们来说是平坦的。此时,"段"对于我们来说,还有什么意义呢?

这时,"段"相当于一个管理者的角色,它有自己的Base,但往往从0开始计算,这时,更多的充当自己的权限功能。

“每个段”可以存储在寄存器中,比如你访问局部变量,其内存地址为 [a],其实际访问是 sp:[a],虽然不同的段Base都为0开始,但权限是不同的,零环的段是不允许被三环的权限访问的。

二、幽默的过客 与 GDT表

我们在实际使用过程中直观的看到段?答案是通过段寄存器(FS···)。

段寄存器中存储的是什么呢(显然不是段描述符)?实际上存储的是 幽默的过客。

幽默的过客指明了该指明:读取段申请的权限、查哪一张表、在表中的索引位置。(注意,不要误解幽默的过客只表明位置)

1. 拆分幽默的过客:

我们查看寄存器时会发现各种段寄存器的值,我们使用如下方式进行拆分:如果想获取幽默的过客,直接右移3位,selector >> 3。

2. 搜索 gdt 表:

GDT表全程 Global Descriptor Table,段描述符表。

其存储在 gdtr 寄存器中,我们在Windbg中使用 "r gdtr" 即可获取该地址。

然后我们采用 dq address (一个幽默的过客四字,八字节) 来显示 gdt 表,如果知道索引想直接查看其地址,可以使用 dq address + (index * 8) 的公式来进行搜索。

三、段描述符的拆分

这个我们只挑几个重点讲,后续会补充其细节和有关实验。

1. 段限长的换算公式

我们注意到,其段限长为 [0,15]、[24,31],但是如何仔细一看,其明显是24位,少了8位。

这时,我们用到G位(23),颗粒度。

如果 G == 1 , 其颗粒度为 一页,以4KB为单位,4KB。 4KB = 2 ^ 12  =  0x1000,但是,其是从零开始计数的,则应该后补 0xFFF。

如果 G == 0,则直接为原来的数值就好。

2. P位、S位与TYPE位

P位:0 - 无效段 、 1 - 有效段。(查看该段是否有效,最直接的就是查看该位)

S位:0 - 系统段、1 - 代码段或数据段。

TYPE位:如果S位==1,则TYPE位进一步详解其代码段或数据段的有关属性(可读可写可执行等等)。

如下图,一个直观判断到底是代码段还是数据段的方法:TYPE <= 7 数据段 ; TYPE >= 8 代码段。

3. D/B位

该位对于数据段和代码段有着不同的含义,但大体都是与位数大小有关。比如,如果我们使用32位操作系统,一次操作32位,又如何切换到对16位的操作,根本上就是使用这个位。

1)代码段:在32位操作系统下,如果DB == 1,则默认操作数是32位,如果操作16位时,其会加上前缀指令66。

(66 50 push ax / 50 push eax)

2)数据段:该段作用与不同的数据段其含义不同。

(1)SS段:DB == 0 ,使用16位寄存器  sp; DB == 1,使用32位寄存器 esp。

(2) DS、ES、GS、FS:表示界限(Limit),DB == 0 ,Limit 64KB;DB == 1,Limit 0xFFFFFFFF。

4. 段权限检查

1)三个概念:

(1)RPL(Request Privilege Level) 请求特权级别,幽默的过客的后两位。

(2)DPL(Descriptor Privilege Level) 段描述特权级别,13位与14位。

(3)CPL(Current Privilege Level)当前特权级别,当前工作在CSSS段的RPL。

2)权限检查:

简单解释下上面的概念就很好理解,像 mov ,eax,3bh ; mov ds,eax 。 这种就会进行有关段权限检查,如果不通过赋值会失败。

首先,CPL表示当前工作的环境(0环或3环),如果CPL为3环,其幽默的过客后两位不可能为0(不用访问,请求都请求不了)。

而即使你生成请求,其还会和段描述符中的DPL校验,如果校验不通过,你依然无法生成。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。