首页
社区
课程
招聘
[原创]Windows下的分页模式- 页目录和页表从物理内存到虚拟映射求值
发表于: 2012-12-6 12:45 17661

[原创]Windows下的分页模式- 页目录和页表从物理内存到虚拟映射求值

2012-12-6 12:45
17661

昨天在网上看到一段代码令大为不解,大家都知道一个虚拟地址到物理地址的转换伪公式为:
*(*(*PD[(VirtualAddress>>22)] & FFFFF000) [(VirtualAddress & 3FF000)] )&FFFFF000 + VirtualAddress & FFF;
PD为页目录基址,
*PD[(VirtualAddress>>22)]  主要算出页表的物理页号(即定位哪一张页表)后面是属性位,而后& FFFFF000获得该页表所在的实际物理地址。
而后以页表的实际物理地址牵引[(VirtualAddress & 3FF000)] 即定位该页表的哪一个页表项,得到虚拟地址所在页的物理页号和一些属性位。而后将其)&FFFFF000,即得到所在页的物理地址,最后再加上虚拟地址的低12bit(即 VirtualAddress & FFF),即为页内偏移,从而得到真实物理地址。

后来才发现原来伪公式是针对你可以直接访问物理地址而言的,并不能直接使用,在Windows保护模式下实际物理页表和物理页目录都被映射到进程的地址空间了,每个进程都有自己的页目录和页表,以此进行隔离进程。因此在内存空间中对页目录和页表的访问应当以虚拟地址的方式进行访问。网上摘录代码如下:

unsigned int PDE;
unsigned int PTE;

if (VirtualAddress >= 0x80000000 && VirtualAddress < 0xa0000000)
{
    PhysicalAddress = VirtualAddress - 0x80000000;
}
else
{
    PDE = * (unsigned int *) ( (VirtualAddress >> 22) * 4 + 0xC0300000);
    if (PDE & 0x00000001)
    {
        PTE = * (unsigned int *) ( (VirtualAddress >> 12) * 4 + 0xC0000000);
        if (PTE & 0x00000001)
        {
            PhysicalAddress = ( (PTE & 0xFFFFF000) + (VirtualAddress & 0x00000FFF) );
        }
    }
}
if (VirtualAddress >= 0x80000000 && VirtualAddress < 0xa0000000)
{
    PhysicalAddress = VirtualAddress - 0x80000000;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (30)
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
继续写,不知道新手能不能看懂,真怕写完后我自己都看不懂,语言太差了。抱歉谅解。
2012-12-6 13:38
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
3
前排 顶了 补字
2012-12-6 14:10
0
雪    币: 248
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
MARK下,以后看
2012-12-6 16:39
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
5
前排站位,谢谢楼主的分享!
2012-12-6 17:45
0
雪    币: 61
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
殊不知,windows的分页方式有两种。10_10_12是一种,还有一种是2_9_9_12分页方式,由控制寄存器cr4的一个位来控制,可以通过设置这个位来选择使用哪种分页方式。。。所以希望楼主继续研究,说的全面一些。。。
2012-12-6 19:53
0
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
PAE么,还没研究。。。
一步一步走。
2012-12-6 20:10
0
雪    币: 149
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
支持不错.. 靠谱
2012-12-6 23:09
0
雪    币: 29
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
如题,大家要不要期待一下!
2012-12-7 09:38
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
10
楼主帖子内容不全面,只是一种情况,应该是4种。。
2012-12-7 09:42
0
雪    币: 29
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
兄弟,开启与不开启PAE的情况各有两种,一共有四种情况!
2012-12-7 09:44
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
12
应该有五种情况,但实际Windows系统地址映射转换只有4种~
2012-12-7 10:46
0
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
13
谢谢各位牛牛们提醒,看来我还得回去好好研究。
2012-12-8 12:34
0
雪    币: 350
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
马克 标记一下
2012-12-8 16:04
0
雪    币: 465
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
前排站位,谢谢楼主的分享!
2012-12-8 16:45
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
期待!
2012-12-8 17:59
0
雪    币: 296
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
拍照留念。。
2012-12-8 19:53
0
雪    币: 193
活跃值: (1210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
挺高深的,mark一下,以后看
2012-12-9 09:03
0
雪    币: 524
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
Mark 标记一下
2012-12-9 09:11
0
雪    币: 61
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
我只说windows的分页方式有这两种。。。。并没有说虚拟地址到物理地址的转换。       觉得很没有价值的东西,还不如写一个能直接读物理内存的函数来的有价值。。。
2012-12-11 13:35
0
雪    币: 284
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark,mark
2012-12-11 14:08
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
22
不是两种,五种!
2012-12-11 14:32
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
23
一:2_9_9_12

二:2_9_21

三:10_10_12

四:10_22

五:10_22 大页面扩展

方式有五种!

另外Windows也并非由控制寄存器cr4的一个位来控制,
而是由页目录PS标志位决定的,测试过的~
2012-12-11 14:39
0
雪    币: 56
活跃值: (490)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
顶一下
2012-12-11 15:55
0
雪    币: 61
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
  以为自己才疏学浅,竟然第一次知道windows的分页方式有5种啊。。。竟然大页小页也能算是另外的分页方式啊。。。。。。。。你意思是不用cr4来控制?   直接用ps属性位?   ps属性位只是标志是按大页还是小页方式分页。。。大页为4M,小页为4K。孩纸,这不属于windows的分页方式。跟 2_9_9_12和 10_10_12不能同日而语。windows切换分页方式是通过  mov cr4,eax  这样切换的。。。。

若感觉自己技术好,那请问一个问题。。。mov cr4,eax  执行执行之前是10_10_12分页方式,所以下一条指令也是按这个分页方式存放的,线性地址也是10_10_12的分页方式,但是 mov cr4,eax执行完以后,分页方式换为2_9_9_12分页方式,线性地址指向的物理地址必然已经不一样了。。。请问,切换分页方式的代码应该放在什么地方,才能保证那条指令执行完以后下一条指令还能正常执行。。。。
2012-12-11 17:41
0
游客
登录 | 注册 方可回帖
返回
//