windows保护模式(一)

  1. 段寄存器

CPU通过段和页的机制来限制内存访问,共8个分别为ES CS SS DS FS GS LDTR TR  

 

段寄存器结构

当我们用汇编读写某一个地址时:

mov dword ptr ds:[0x123456],eax

我们真正读写的地址是:ds.base + 0x123456

2、段寄存器成员

XP上一般如下

我的Win10上

注意:GS 一走调试就必须进0环,进0环后被内核清空

3、段描述符与段选择子

1)先说两张表

GDT(全局描述符表)和LDT(局部描述符表)

当我们执行类似MOV DS,AX指令时,CPU会查表,根据AX的值来决定查找GDT还是LDT、查找表的什么位置、查多少数据。

2)gdtr寄存器:存放GDT的位置和GDT的大小

3)查看GDT

查看GDT的位置

查看GDT的大小

查看GDT数据

4)段描述符

GDT表里存放的数据就是段描述符,段描述符有8个字节64位,结构如下

用dq指令查看

对应关系

P=0段描述符无效

P=1段描述符有效

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

S=0是系统段描述符

当S=1时根据Type区分是代码段还是数据段,如下表

注意:expand-up的意思是段的有效范围Base~Base+Limit

expand-down段的有效范围是除了(Base~Base+Limit)以外的区域;C位为1 时是一致代码段(conforming)也叫共享段,C位为0时是非一致代码段(unconforming)

一个经验区分方法:

S=0是系统段描述符,系统描述符有如下类型

段描述符与段寄存器的对应关系

WORD Selector 16位 对应段选择子

WORD Attribute 对应段描述符高4字节的 23:8位

DWORD BASE 32位 对应段描述符Base31:24+Base23:16+Base Address31:16

DWORD Limit 32位 对应段描述符 高4字节19:16+Segment Limit15:00

如果G=0,则在余下高位补0,则最高为000FFFFF;如果G=1,则在余下高位补1,则最高为FFFFFFFF

5)段选择子Selector

16位的段描述符,该描述符指向了定义该段的段描述符,结构如下

6)举例

MOV DS,AX  其中AX的值位0x0023

0x0023二进制为 0000 0000 0010 0011

对应的段选择子

RPL:11

TI:0  查GDT

Index:0000 0000 0010 0  查GDT的第4个

查的结果为:00cff300`0000ffff

按段描述符进行拆分

0x00cff300

Base31:24 0000 0000

G:1

D/B:1

0:0

AVL:0

Seg-Limit19:16  1111

P:1

DPL:11

S:1

Type:0011

Base23:16 0000 0000

 

0x0000ffff

Baseaddress:0x0000

SegmentLimit:0xFFFF

可以得到以下信息

第一,P=1有效

第二,S=1,说明是代码段或数据段

第三,Type为 0011说明是数据段、expand-up、Read/Write、Accessed

第四,DPL=RPL 如果CPL<=DPL(CPL后面介绍)则可以将GDT中的这个段描述符加载到段寄存器DS中

7)除了MOV指令,我们还可以使用LES、LSS、LDS、LFS、LGS指令修改寄存器.

CS不能通过上述的指令进行修改,CS为代码段,CS的改变会导致EIP的改变,要改CS,必须要保证CS与EIP一起改。

4、段描述符的D/B位

情况一:对CS段的影响

D = 1 采用32位寻址方式

D = 0 采用16位寻址方式

前缀67 改变寻址方式

情况二:对SS段的影响

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

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

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

D = 1 段上限为4GB

D = 0 段上限为64KB

4、段寄存器CS和SS的选择子Selector中的低两位RPL,又叫做CPL(Current Privilege Level)即当前进程的特权级别。这两个的Selector的低两位相同。

用OD打开一个程序

低两位为11,说明当前程序为ring3的。

5、DPL(Descriptor Privilege Level)描述符特权级别

DPL存储在段寄存器中,规定了访问该段所需要的特权级别,描述的是访问这个段需要什么权限。

例如

Mov DS,AX

如果AX指向的段DPL=0,当前程序的CPL=3,则这条指令会执行失败。

6、RPL(Request Privilege Level)请求特权级别

RPL是针对段选择子而言的,每个段的选择子都有自己的RPL,描述的是用什么权限去访问一个段。

Mov ax,0x0008

Mov ds,ax

和下面的指令

Mov ax,0x000B

Mov ds,ax

指向的是同一个段描述符,但RPL是不一样的。

7、数据段的权限检查

假设当前的程序处于ring0,也就是CPL=0

Mov ax,0x000B  //RPL=3

Mov DS,ax   //ax指向的段描述符中的DPL=0

 

只有CPL<=DPL并且RPL<=DPL时mov DS,ax 才会执行成功。上述不满足RPL<=DPL所以执行失败。

8、代码间的跳转(段间跳转)

1)指令介绍

只改变EIP的指令

JMP/CALL/JCC/RET

同时修改CS和EIP的指令

JMP FAR/ CALL FAR / RETF / INT / IRETED

2)JMP FAR

指令格式 JMP 段选择子:要跳转的地址

例如:JMP 0x20:0x004183D7

0x20:段选择子

0x004183D7:要跳转的地址

执行过程

第一步,拆分段选择子0x20

对应的二进制 0000 0000 0010 0000

得到RPL=0 TI=0 Index=4

第二步,查表得到段描述符

TI=0 查询GDT表

Index = 4 对应的段描述符,如果找到的段描述符是代码段、调用门、TSS任务段、任务门这四种,是可以跳转的。注意:后面三种都是系统段描述符。

第三步,权限检查

如果是非一致代码段,要求CPL==DPL 并且 RPL<=DPL

如果是一致代码段,要求 CPL>=DPL

第四步,加载段描述符,通过上面的权限检查后,CPU会将段描述符加载到CS段寄存器中。

第五步,代码执行,CPU将CS.Base+Offset的值写入EIP,然后执行CS:EIP处的代码。

段间跳转结束。

9、关于一致代码段和非一致代码段

1)一致代码段,也叫共享段,特权级高的程序不允许访问特权级低的数据(核心态不能访问用户态的程序);特权级低的程序可以访问特权级高的数据,但特权级不会改变。

2)非一致代码段,也叫普通代码段,只允许同级访问。

3)直接对代码段进行JMP或者CALL的操作,无论目标是一致代码段还是非一致代码段,CPL都不会发生改变;如果要提升CPL权限,只能通过调用门。

10、一个例子

1)找一个非一致代码段描述符

00cffb00`0000ffff

807d4c68修改为上述值

2)OD中使用jmp far 注意EIP和CS前后变化

可以发现EIP和CS同时发生了变化。

3)选择下面的段描述符 00cf9b00`0000ffff

段选择子应该为 0x00B ,段选择子的RPL=3

上述段描述符的DPL=0,是非一致代码段,跳转应该会失败,如下

4)挑一个或者构造一个一致代码段00cf9d00`0000ffff,如下图

DPL=0,段选择子构造为0x004B RPL=3,Index=9 ,程序的CPL=3,由于是一致代码段可以执行成功,如下

------------------------------------------------------------------------未完~待续~-------------------------------------------------------------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值