段的基础

段寄存器

页保护主要实现进程与进程之间的互相隔离
段是一种权限用来限制R3的各种操作

8086段寄存器

8086CPU有20根地址线,最大可寻址内存空间为1MB。而8086的寄存器只有16位,指令指针(IP)和变址寄存器(SI、DI)也是16位的。用16位的地址寻址1MB空间是不可能的。所以就要把内存分段,也就是把1MB空间分为2 ^ 4,即16个段,每段不超过64KB(2 ^ 16,16位数据线就可以寻址)。

	   代码段寄存器CS        程序的段地址
	   数据段寄存器DS        操作数的段地址
	   堆栈段寄存器SS        堆栈的段地址
	   附加段寄存器ES        辅助数据段的段地址

把内存分段后,每一个段就有一个段基址,段寄存器保存的就是这个段基址的高16位,这个16位的地址左移四位(后面加上4个0)就可构成20位的段基址。

64位段寄存器

	   代码段寄存器CS        程序的段地址
	   数据段寄存器DS        操作数的段地址
	   堆栈段寄存器SS        堆栈的段地址
	   附加段寄存器ES,FS,GS        辅助数据段的段地址

代码段只能读和执行
FS在windows的作用中应用层保存的是TEB地址(内核中描述线程的结构是ETHREAD),内核中保存的是KPCR。
64位下段寄存器存放的不再是段的基地址,而是段选择符。段寄存器中有96位,但是有80位都隐藏起来了

WORD Seiector;  //16位
WORD Atrribute; //16位  段描述符从高四字节 第八位开始到第二十三位结束
DWORD Base;  //32位   Base 和 BaseAdress 组成
DWORD Limit;   //32位  高16到19 低0到15

我们可以通过MOV,LES,LSS等指令来修改寄存器,但是不能修改CS,因为CS是代码段,修改了的话,必然会连EIP一起改。
同时修改CS和EIP的指令
CALL CS:EIP 跨段长调用 会先把CS的值压入堆栈,如果长调用并提权了,还要压入CS,ESP和SS的值
1.跨段调用是,一旦权限切换,就会切换堆栈
2.CS的权限改变了,SS的要跟着一起变
3.JMP FAR只能跳转到同级非一致代码段,但CALL FAR可以通过调用门提权,提升CPL的权限

跨段间的跳转执行的流程

JMP 0x40:0x00324132
CALL 0x40:0x00324132 //提权

首先拆分 段选择子0x40 = 0000 0000 0100 0000
RPL = 00
TI = 0 查GDT表
Index = 8 找到相应的段描述符

权限检查 如果是数据段,要求CPL 和 RPL 大于或等于 DPL。如果是代码段,则要求 CALL JMP 权限高或者同等级·,提升权限,RETF IRETD 权限低或者同等权限,降权。

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

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

如果CALL,之后回去不能用RET,要用RETF或IRETF,降权。

段是在内存中划分出来的一块块区域,举个例子,比如下图这个色块
在这里插入图片描述
黄色的假设是内存,其他色块就是内存中的段,比如可以是代码段(CS),数据段(DS,ES),栈(SS),状态段(TR)。
假设这个内存空间是从上往下依次增大的,那么1的位置就是深蓝色这个段的段基地址,段基地址(Base Address)就是规定线性地址空间中段开始的地址。如果是在8086里面段的起始位置还必须要被16整除。
段的界限就是段的大小,段的大小用20位byte来表示,同时在段属性中段大小指定的粒度也可能不相同,可能1B也可能4KB,
段的增长方向也有两种:从低地址走到高地址和从高地址走向低地址。比如代码段和数据段就是低地址走向高地址,而栈段就是高地址走向低地址,所以不同的段对应的段基地址的判断也会有所不同。

段描述符

在windbg中查看GDT表,表中存放的数据即为段描述符,当我们执行比如MOV DS,AX指令时,CPU会查表,根据AX来决定查找GDT还是LDT。

kd> r gdtr
gdtr=80b95000
kd> r gdtl
gdtl=000003ff
kd> dd 80b95000
80b95000  00000000 00000000 0000ffff 00cf9b00
80b95010  0000ffff 00cf9300 0000ffff 00cffb00
80b95020  0000ffff 00cff300 400020ab 80008b1e
80b95030  9c003748 834093f6 f0000fff 7f40f3fd
80b95040  0400ffff 0000f200 00000000 00000000
80b95050  70000068 830089f6 70680068 830089f6
80b95060  00000000 00000000 00000000 00000000
80b95070  500003ff 800092b9 00000000 00000000

段描述符是段的基地址,界限和属性的数据结构,占8个字节。
在这里插入图片描述
上图就是段描述符的结构,8个字节,64位byte,低32位,高32位。
其中低32位的16到31位和高32位的0到7位组成了这个段的基地址。段的大小也被分成了两个部分,低32位的0到15位和高32位的16到19位。
高32位中第23位的G是段界限粒度位,为0是Limit 最大界限为000FFFFF,为1是Limit 最大界限是FFFFFFFF。
旁边的D/B则要分三种情况来看,如果该段是代码段,那么1代表32位地址和操作数,0代表16位地址和操作数;如果该段是向下扩展数据段,1表示上部界限为4G,0为64K;如果该段为栈段,1表示32位栈顶指针ESP,0表示16位SP。(1都表示32位,0都表示16位)
AVL是软件可利用位,没有多大用处,先不管。
P是存在位(Present),1表示存在内存中,0则不存在返回访问异常。
DPL是描述符特权级有两位(00或者是11),00(0)就是ring0,内核级,11(3)就是ring3,应用层。
S表示段的区别种类,如果该段是数据段代码段为1,任务状态段为0.
Type占了4位用来表示存储段的具体属性

3210
0数据段扩展方向可写&只读被访问
1代码段一致代码段可读&只执行被访问

一致代码段:低级别(r3)能访问高级别(r0)共享出来的代码段叫做一致代码段。非一致代码段就是只能本级别访问的代码段,不能越级进行访问。
根据这些能写出Type的值对应的是什么

01234567
数据段只读只读 已访问可写可写 已访问只读 向下扩展只读 向下扩展 已访问可写 向下扩展可写 向下扩展 已访问
89ABCDEF
代码段只执行只执行 已访问可读可读 已访问只执行 一致代码只执行 一致代码 已访问可读 一致代码可读 一致代码 已访问

段描述符表

段描述符都是存放在段描述符表里的,有三种类型的描述符表。其中GDT和IDT表只能有一张,而LDT表可以有若干张,每个任务一张。

	全局描述符表GDT,GDTR是存放GDT表的寄存器
	局部描述符表LDT,LDTR是存放LDT表的寄存器
	中断描述符表IDT,IDTR是存放IDT表的寄存器

GDT表中含有每个任务都可以去访问的段的描述符,通常包含了描述操作系统所使用的代码段,数据段和堆栈段的描述符。
LDT则是每个进程所私有的,与其他进程向隔离,起到了保护进程的作用。一个进程只能修改自己的LDT表中所对应的段。当进程切换时,只切换LDT表,不切换GDT表。
一个任务通常高2G的段都存放在GDT表中,因为通常都是内核代码,低2G的段存放在LDT表中,这通常都是进程空间。

段选择符

在这里插入图片描述

64位下段寄存器(CS,DS,SS等)中存放的是段选择符。段选择符一共有16位。
低两位是请求特权位RPL,是段请求权限,用于特权检查,0(00)为最高级别,3(11)为最低级别。每当有一个代码段选择子装入CS寄存器中是,处理器会自动地把CPU当前特权级(CPL CPL就是CS段的RPL)存放入CS的RPL字段中。然后这个在和之前段描述符中的DPL进行对比,两者一样,才是一个合法访问。
下一位是引用描述符表指示为TI,当TI为0是从GDT表中读取描述符,TI为1是从LDT表中读取描述符。
接下来的13位是描述符索引(Index),索引是指描述符在描述符表中的序号。
RPL需要小于或者等于DPL。

任务状态段TSS

TSS是操作系统在进行进程切换时保存进程现场信息的段,即保存CPU中个寄存器(如CS,EIP,eflags等)的值,实现任务的挂起和恢复,进程之间的切换。由104个字节组成。
任务状态段寄存器TR:当前任务的任务状态段描述符选择符(类似CS,DS)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值