黑客入门保护模式中存储器的保护

原有用来生命GDT大小和线性基地址用
gdt_size dw 0
gdt_base dd 0x0000007e00
但现在已经改成:
pdgt dw 0
dd 0x0000007e00

将 (GDT的基地址) / 16
;binary左移4位,高位存在eax中,低位0000存在edx中;并传输给ds和ebx

修改段寄存器时的保护:随着程序的执行,经常要对段寄存器进行修改,此时,处理器在变更寄存器以及隐藏的描述符高速缓存器的内容时,要检查其代入值的合法性。
在执行涉及段寄存器的指令时,处理器把指令中给出的选择子传送到段寄存器的选择器上,但是,处理器的固件在完成传送之前,要先确认选择子是正确的,并且该选择子的描述符也是正确的。

如果没有检查到指定的段描述符,其位置超过表的边界时,处理器终止处理,产生异常中断13,同时段寄存器中的值不改变
接着还要对描述符的类别进行确认,这段描述符是可读、可写还是可执行的。举个例子,若描述符的类别是只执行的代码段,则不允许加载到CS之外的其他段寄存器中。
换句话说,就是先检测描述符的类别字段必须是有效的值,接着检查描述符的类别是否与段寄存器的用途所匹配。

最后,还要检查描述符中的P位,如果P = 0,表明虽然描述符以定义,但是不存在于物理内存中。此时处理器终止处理,引发异常中断11,把该描述符所对应的段从硬盘调回内存,然后置P。返回后,处理器再次尝试刚才的操作。

地址变换时的保护:一旦相应的描述符被加载到段寄存器的描述符高速寄存器,则处理器取指令和执行指令时候,将不再访问描述符表,而是直接使用段寄存器的描述符高速换岑起,从其中获得线性基地址,,同指令指针寄存器EIP的内容相加,共同形成32位的物理地址从内存中获取下一条指令。

每个代码段都有自己的段界限,位于其描述符内。实际使用的段界限,其数值和粒度(G)有关,如果G = 0,实际使用的段界限就是描述符中记载的段界限;如果G = 1,则使用的段界限就是:描述符中的段界限 * 0x1000 + 0xFFF

代码段是向上扩展(高地址方向)的,实际使用的段界限就是当前段内的最后一个访问的偏移地址。当处理器在该段内取指令执行时,偏移地址由EIP提供。指令很有可能是跨越边界的,一部分在边界内,一部分在边界外,或者一条单字节指令正好位于边界上。因此,要执行的那条指令,其长度减1后,与EIP寄存器的值相加,结果必须小于等于实际使用的段界限。否则引发异常处理,即:
0 <= (EIP + 指令长度 - 1) <= 实际使用的段界限

栈操作时的保护:处理器在32位的栈段上进行压栈和出栈操作时,默认使用ESP寄存器。栈段是向下扩展的,每当往栈中压入数据的时,ESP的内容就要减去操作数的长度,所以相对于代码段的区别是:实际可使用的段界限就是段内不允许访问的最低端偏移地址,必须符合以下规则:
实际使用的段界限 + 1 <= (ESP - 操作数的长度) <= 0xFFFFFFFF(最高端地址没有限制)

发布了47 篇原创文章 · 获赞 10 · 访问量 1720

猜你喜欢

转载自blog.csdn.net/Antonio_Salieri/article/details/103243106
今日推荐