首页
社区
课程
招聘
[原创]保护模式-分段机制(附多篇保护模式文章)
发表于: 2013-11-5 12:38 23452

[原创]保护模式-分段机制(附多篇保护模式文章)

2013-11-5 12:38
23452
逻辑地址到线性地址的转换
段基址
如果开启了分页选项,那么线性地址就是物理地址,无需再进行转换.
段基地址(Base Address): 32位
段界限(Limit): 描述段的大小,20位
段属性(Attributes): 属性中的最高位G(粒度位)表示字节单位还是4K字节为单位.

段大小计算公式
1.字节方式
段的上限 = 基地址 + 段界限
比如:基地址:00012345H  段界限:5678H
段的上限 = 00012345H + 5678H = 000179BDH
所以段的范围是:000179BDH -- 000179BDH
2.4K方式
段的上限 = 00012345H + 5678H * 4K + 0FFFH = 0568B344H

4K方式追加FFFH的缘由
上面的计算方式中,后面加了一个0FFFH,这是因为20位段界限表示最大值为0FFFFFH,那么
段上限 = 0FFFFFH * 4K = 0FFFFF000H,不能够完全表示4G的范围,所以后面追加一个0FFFH,这样段上限 = 0FFFFFH * 4K + 0FFFH = 0FFFFF000H + 0FFFH = 0FFFFFFFFH,这样
0 -- 0FFFFFFFFH刚好可以表示4GB.

存储段描述符
描述符
描述一个段可以有三个东西:1.段基址 2.段界限 3.段属性
用于表示这三个东西的数据结构就是描述符,可以理解成一个结构体.
描述符分类:
1.存储段描述符(存放段:存放程序可以直接访问的代码和数据的段)
2.系统段描述符
3.门描述符
存储描述符的格式

描述符长8个字节
用位段定位该数据结构


为什么段界限会分开?
为了兼容以前的CPU型号

全局(GDT)和局部描述符表(LDT)
任务
任务:可以理解成线程,每个线程需要一个描述符来描述

描述符表
描述符表:由描述符组成的线性表,描述符表包括:GDT,LDT,IDT.

单核的系统中,GDT和IDT只有一张,LDT每个线程都可以有一张.
多核的系统中,GDT和IDT也可能不止一张.

存储描述符表的特殊数据段最多可包含8K(8192)个描述符.
 
一个任务可使用的整个虚拟地址空间分为相等的两半,一半空间的描述符在全局描述符表中,另一半空间的描述符在局部描述符表中.
由于全局和局部描述符表都可以包含多达8192个描述符,而每个描述符所描述的段的最大值可达4G字节,因此最大的虚拟地址空间可为:
4GB*8192*2=64MMB=64TB

段选择子
段选择子是神马?
段选择子替代了实模式下面的段值.也就是段描述符在段描述符表中的下标.
长度:16位
OD里面查看选择子,也就是各段寄存器里面的值


windows的段描述符表
windows没有采用Intel的LDT,只采用GDT.
可以使用windbg来查看GDT

试验:显示选择子0到100的段描述符

全局描述符表寄存器GDTR
GDTR中的低16位表示界限,GDTR中的高32位表示基地址,前面说了描述符表都存放在特殊的数据段中.
用windbg查看GDTR的值:


使用特权指令获取GDTR的值

部分查询类特权指令3环也可以使用,但是修改类特权指令3环一般是不能用的.

试验:VC来打印GDTR

效果:

我的机器是双核的,说明多核的情况下GDT表可以不止一张.

再谈段选择子
实模式下: 逻辑地址 由  段地址 + 段内偏移地址 组成

保护模式下: 虚拟地址(逻辑地址) 由 段选择子 + 段内偏移 组成.

很明显,段选择子取代了段地址的地位,那么说明段选择子可以确定哪一个段,以及段的起始地址.
因为段描述符都存放在段描述表中的,段描述表相当于一个存放段描述符的数组,那么要确定哪一个段描述符,想想缺少什么条件?对,就是数组下标,段选择子,就是用来确定段描述符在段描述符表中的下标的.

TI位: 取值0:从GDT中读取描述符  取值1:从LDT中读取描述符
由于windows值采用了GDT,所以相应的TI位总是为0.

解析windows某一时刻的段选择子
Ring0

ds,es两个选择子为啥显得怪异?
明明当前是ring0,为什么请求特权级(RRL)对应项是ring3,这是由于内核态只需要用到cs(代码),ss:(堆栈),fs(内核相关数据结构),而不需要用到ds,es,所以ds,es两个选择子并没有进行切换,所以显示的还是原来ring3的选择子的值,所以看起来有的怪异.
对照windbg的GDT表

和以上的手工分析是一致的.

Ring3
如何让选择子切换到3环呢?
我们知道API实现内部都会调用ntdll模块中的快速系统调用这个函数

所以只需要在ntdll!KiFastSystemCall下断点即可.

运行起来,就会断下KiFastSystemCall的入口处,这个时候的选择子就是3环的

                                  GDT索引                     TI               RPL
cs:0x001b  <=> 0000000000011(索引号3)        0(GDT)          11 (ring3)
ss:0x0023  <=> 0000000000100(索引号4)        0 (GDT)          11(ring3)
ds:0x0023  <=> 0000000000100(索引号4)        0 (GDT)          11(ring3)
es:0x0023  <=> 0000000000100(索引号4)        0 (GDT)          11(ring3)
fs:0x003b  <=>  0000000000111(索引号7)        0(GDT)          11(ring3)
对照windbg的GDT表

和手工分析同样是一致的.

windows间接屏蔽掉了VA(虚拟地址)到线性地址的转换
根据上面的各个段的起始地址都是从0开始的,所以表示的范围从0到4GB,这样就造成了虚拟机即线程地址.
例如:
ss:00401000  ==> 线性地址 <==> 0 + 00401000 = 00401000
 
所以,windows里面的 虚拟地址 等价于 线性地址

更多保护模式内容请参看附件,这里一并奉上.
驱动加载工具DIY.doc
windbg命令.doc
应用层和驱动层的通讯.doc
API Ring3切换Ring0流程.doc
通过华生医生抓取崩溃Dump文件.doc
保护模式-分段机制.doc
分段管理之段选择子.doc
分页管理机制.doc
启用PAE后虚拟地址到物理地址的转换.doc
解析VA(804e3a42) --》PA.doc
解析explore.exe中0x77EF1000.doc
在虚拟机中,对calc.exe进程做修改,让关于弹不出.doc
Ring3与Ring0的通讯.doc
模拟API-ReadProcessMemory.doc
ReadProcessMemory简单分析.doc

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (30)
雪    币: 253
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
哈哈。。好贴。。
2013-11-5 12:51
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
3
给自己顶!
2013-11-5 13:32
0
雪    币: 74
活跃值: (703)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害,感谢,mark
2013-11-5 14:14
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢 mark
2013-11-5 15:42
0
雪    币: 27
活跃值: (90)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
6
楼主很努力,好文章我又赶上了
2013-11-5 16:05
0
雪    币: 541
活跃值: (654)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
7
楼主继续啊,楼主啥时候写点x64 CPU的虚拟地址与物理地址转换?
2013-11-5 16:19
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享,看雪有你更精彩!
2013-11-5 16:41
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
9
论坛的编辑功能真心不好使,发一个帖子,图文并茂的话像麻砖头一样,要是能搞成和为知笔记一样就好了,编辑功能这样设计是不是为了防XSS呀?
2013-11-5 16:53
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
mark ~~
2013-11-5 23:08
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
11
鼓励下图文并茂的排版,哈哈.
2013-11-6 09:51
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
12
谢莫大!
2013-11-6 10:49
0
雪    币: 219
活跃值: (738)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
13
支持一下~~
2013-11-6 12:38
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
14
2013-11-6 12:46
0
雪    币: 45
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
问一下,我们的xp系统、win7系统和win8系统分别采用哪种内存管理方式(分段还是分页)?
2013-11-6 16:43
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
收藏一下,下来细细研究,感谢分享
2013-11-6 19:05
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
17
一般来说是既分段又分页
2013-11-6 21:15
0
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
18
最近工作忙,空闲才能弄
2013-11-6 21:16
0
雪    币: 61
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
谢谢分享
2013-11-6 21:36
0
雪    币: 114
活跃值: (180)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不错,支持楼主。
2013-11-6 21:57
0
雪    币: 60
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
最近也在看这方面的东西,谢谢楼主了
2013-11-9 12:43
0
雪    币: 39
活跃值: (2686)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
楼主对"20位段界限"的理解有些偏差。
20位段界限并不表示段长度或页的数量,而是
段末地址或末页编号。当granularity=1且
此值=FFFFF时,表示最后一页编号为FFFFFh,
转化成地址=FFFFFh*4K=FFFFF000,
此地址就是最后一页的首地址,而页长度为
1000H。


4K方式追加FFFH的缘由
上面的计算方式中,后面加了一个0FFFH,这是因为20位段界限表示最大值为0FFFFFH,那么
段上限 = 0FFFFFH * 4K = 0FFFFF000H,不能够完全表示4G的范围,所以后面追加一个0FFFH,这样段上限 = 0FFFFFH * 4K + 0FFFH = 0FFFFF000H + 0FFFH = 0FFFFFFFFH,这样
0 -- 0FFFFFFFFH刚好可以表示4GB.
2013-11-9 22:24
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
MARK
2013-11-10 20:03
0
雪    币: 42
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
支持哈。谢谢分享
2013-11-10 22:42
0
雪    币: 524
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
标记一下,慢慢看
2013-11-12 11:43
0
游客
登录 | 注册 方可回帖
返回
//