博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
0.ring0-PAE-(虚拟地址转换成物理地址详细示例)
阅读量:2455 次
发布时间:2019-05-11

本文共 2346 字,大约阅读时间需要 7 分钟。

PAE是Physical Address Extension的缩写,即物理地址扩展。简单来说,就是把IA-32处理器的寻址能力从原来的4GB扩展到64GB。寻址4GB空间,要求物理地址的宽度为32位。类似的,要寻址64GB空间,那么物理地址的宽度就是36位。因为这个原因,PAE又被称为PAE-36bit。

一般电脑都可以轻松看出是不是使用了PAE,最简单是看系统属性:

如果不启用PAE机制,每个进程的DirBase 的低12位应该是0,启用PAE机制低5位是0。在lkd模式下,!pte显示是不正确的

以下是PAE启用的显示:

以下为示例:

代码:

[cpp] 
  1. char *g_test = "123456789";  
  2.   
  3. int main()  
  4. {  
  5.     printf(g_test);  

1.找到g_test的地址

[cpp] 
  1. 00498004 test!g_test = 0x00486c6c "123456789"  

2.启用内核调试,观察test进程:

上面标红的即为CR3的值,即PDPTR的内容

我们再查看下虚拟地址分解:

==》

最高两位是页目录表指针表的索引(00)

接下来9位是页目录索引即2

接下来9位为页表索引即0x86

最后12位是页内偏移为0Xc6c

[cpp] 
  1. </pre><p></p><p><span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif"><span style="font-size:14px">可以这样理解,三张表:</span></span></p><p><span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif"><span style="font-size:14px">页目录指针表-->页目录表基地址</span></span></p><p><span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif"><span style="font-size:14px">页目录表-->页表基地址</span></span></p><p><span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif"><span style="font-size:14px">页表+页内偏移即为物理地址</span></span></p><p>3.首先通过02b40320观察指针表,因为是物理地址,所以用!dq</p><p></p><pre code_snippet_id="224619" snippet_file_name="blog_20140308_4_3950583" name="code" class="cpp">kd> !dq 02b40320    
  2. # 2b40320 00000000`0313a801 00000000`1fdfb801  
  3. # 2b40330 00000000`1fc3c801 00000000`03579801  
  4. # 2b40340 00000000`10c5e801 00000000`10bdf801  
  5. # 2b40350 00000000`10ce0801 00000000`10d5d801  
  6. # 2b40360 00000000`111bb801 00000000`1123c801  
  7. # 2b40370 00000000`1143d801 00000000`1137a801  
  8. # 2b40380 00000000`115dd801 00000000`1151e801  
  9. # 2b40390 00000000`1145f801 00000000`1165c801  

每个指针对共有4个表项,每个表项是8字节(64位),上面2分析为0号表项,即00000000`0313a801

4.把00000000`0313a801砍去低12位,高32位,就是页目录表的基地址为0313a000,观察它的第2项:

[cpp] 
  1. kd> !dq 313a000+8*2  
  2. # 313a010 00000000`03425867 00000000`00000000  
5.把00000000`03425867砍去低12位,高32位,就是页表基地址为:03425000,观察它的0x86项:

[cpp] 
  1. kd> !dq 03425000+0x86*8  
  2. # 3425430 00000000`03f80025 00000000`03301025  
  3. # 3425440 00000000`00000000 00000000`00000000  
  4. # 3425450 00000000`1fc2e025 00000000`00000000  
  5. # 3425460 00000000`00000000 00000000`00000000  
  6. # 3425470 00000000`00000000 00000000`00000000  
  7. # 3425480 00000000`031b7025 00000000`00000000  
  8. # 3425490 00000000`00000000 00000000`00000000  
  9. # 34254a0 00000000`00000000 00000000`0362c025  

6.把00000000`03f80025砍去低12位,高32位,即内存页基地址为03f8000,加上页内偏移c6c:

下面再发张全图加深下理解:

注意PAE是扩展,所以都是64位的:

你可能感兴趣的文章
c专家编程/c陷阱_如何避免常见的初学者陷阱并像专家一样开始编码
查看>>
classlist使用方法_如何通过使用HTML5的classList API在没有jQuery的情况下操作类
查看>>
openstack项目_新项目,安全性以及更多OpenStack新闻
查看>>
美国正在丢掉非洲数字市场_即插即用服务器可访问非洲数百万个数字文档
查看>>
openstack做安卓_我们是我们为OpenStack做出的贡献
查看>>
为什么从SparkFun而不是Bigbox卖家购买?
查看>>
使用TurnKey Linux的用户友好型虚拟主机
查看>>
64 位文件共享锁定数溢出_一位教授如何通过共享教科书为学生节省数百万美元
查看>>
组织学习:DevOps的新视角
查看>>
openstack项目_沃尔玛的OpenStack,项目改革现状等
查看>>
unity 作弊_屏幕作弊没问题,Unity打开,等等
查看>>
推动互操作性,OpenStack卡座等
查看>>
linkedin开源列表_Google的新容器项目,LinkedIn上的开源代码,Raspberry Pi B +,等等
查看>>
openstack项目_软件定义的经济,OpenStack的新孵化项目等
查看>>
git项目中的子git项目_使用子模块和子树管理Git项目
查看>>
sh脚本和bash脚本_使用此简单的Bash脚本在家打印双面文档
查看>>
raspberry pi_使用Raspberry Pi构建感知假肢
查看>>
raspberry pi_一个方便的实用程序,用于创建Raspberry Pi SD卡图像
查看>>
盲打每分钟资源10几个字_每个系统管理员应了解的10个资源
查看>>
横向扩展基础架构_您应该使用的7种基础架构性能和扩展工具
查看>>