首页
社区
课程
招聘
[原创]XP SP2和2003下的4K-PAE的分页情况分析
发表于: 2008-7-9 17:15 5880

[原创]XP SP2和2003下的4K-PAE的分页情况分析

2008-7-9 17:15
5880

题目:XP SP2和2003下的4K-PAE的分页情况分析

我的机器是P4双核3.0G, 1G内存。
研究XP SP2和2003下的4K-PAE的情况可以从如下函数入手:BOOLEAN MmIsAddressValid(IN PVOID VirtualAddress);
而2003下的MmIsAddressValid内部是调用了nt!MiIsAddressValid,2003下的反汇编的代码如下,我在汇编代码中做注释。
nt!MiIsAddressValid:
8084c99a 8bff             mov     edi,edi
8084c99c 55               push    ebp
8084c99d 8bec             mov     ebp,esp
8084c99f 51               push    ecx
8084c9a0 51               push    ecx
8084c9a1 8b4d08           mov     ecx,[ebp+0x8]//把虚拟地址取出
8084c9a4 8bc1             mov     eax,ecx

8084c9a6 c1e812           shr     eax,0x12
8084c9a9 25f83f0000       and     eax,0x3ff8
8084c9ae 2d0000a03f       sub     eax,0x3fa00000
上面三行代码是得到页目录项的地址。注意由于是PAE,所以页表项中每一项都是64位的也就是8字节,每级的索引也由10比特变成了9比特。更多的关于PAE分页的东西请查看Intel或者AMD的系统编程手册,也就是vol2。从最后一句sub     eax,0x3fa00000,我们可以知道4K-PAE的页目录首地址是C0600000,这是虚拟地址,也就是0-3fa00000=C0600000。
这里我们得到的第一个有用的信息就是页目录首地址是C0600000。
8084c9b3 8b10             mov     edx,[eax]
8084c9b5 8b4004           mov     eax,[eax+0x4]
8084c9b8 8945fc           mov     [ebp-0x4],eax
8084c9bb 8bc2             mov     eax,edx
8084c9bd 56               push    esi

判断P位,如果是1,就是存在的页。
8084c9be 83e001           and     eax,0x1

8084c9c1 33f6             xor     esi,esi
8084c9c3 0bc6             or      eax,esi
8084c9c5 7444             jz      nt!MiIsAddressValid+0x71 (8084ca0b)
8084c9c7 be80000000       mov     esi,0x80  //其实这一步的结果如何都要到(8084c9da)进行下一步检测
8084c9cc 23d6             and     edx,esi
8084c9ce 6a00             push    0x0
8084c9d0 8955f8           mov     [ebp-0x8],edx
8084c9d3 58               pop     eax   //其实这里的eax就等于edx
8084c9d4 7404             jz      nt!MiIsAddressValid+0x40 (8084c9da)
8084c9d6 85c0             test    eax,eax
8084c9d8 7435             jz      nt!MiIsAddressValid+0x75 (8084ca0f)

8084c9da c1e909           shr     ecx,0x9
8084c9dd 81e1f8ff7f00     and     ecx,0x7ffff8
8084c9e3 81e900000040     sub     ecx,0x40000000
上面三行是得到页表项的虚拟地址,同时注意到最后一句sub     ecx,0x40000000,我们知道所有的页表都顺序排列在C0000000以后,所以页表项的首地址是C0000000。

8084c9e9 8bc1             mov     eax,ecx
8084c9eb 8b08             mov     ecx,[eax]
8084c9ed 8b4004           mov     eax,[eax+0x4]
8084c9f0 8945fc           mov     [ebp-0x4],eax
8084c9f3 8bc1             mov     eax,ecx

同样的检测P位的有效性
8084c9f5 83e001           and     eax,0x1

8084c9f8 33d2             xor     edx,edx
8084c9fa 0bc2             or      eax,edx
8084c9fc 740d             jz      nt!MiIsAddressValid+0x71 (8084ca0b)
8084c9fe 23ce             and     ecx,esi //这一步的检测依然是没有意义的
8084ca00 52               push    edx
8084ca01 894df8           mov     [ebp-0x8],ecx
8084ca04 58               pop     eax//其实这里的eax就等于ecx
8084ca05 7408             jz      nt!MiIsAddressValid+0x75 (8084ca0f)
8084ca07 85c0             test    eax,eax
8084ca09 7504             jnz     nt!MiIsAddressValid+0x75 (8084ca0f)
8084ca0b 32c0             xor     al,al
8084ca0d eb02             jmp     nt!MiIsAddressValid+0x77 (8084ca11)
8084ca0f b001             mov     al,0x1
8084ca11 5e               pop     esi
8084ca12 c9               leave
8084ca13 c20800           ret     0x8

而XPSP2下的代码和这个是一样的,只不过XPSP2下的代码比较直接,没有再调用函数;而2003下的代码给nt!MiIsAddressValid传入了两个参数,一个参数是我们的虚拟地址,第
二个参数是0,想必是为了以后的扩展,把虚拟地址扩展到了64位而已,但是nt!MiIsAddressValid内部只是使用了低32位。
总结:4K-PAE的页目录首地址是C0600000,页表项首地址是C0000000,这样我们就可以编写自己的虚拟地址和物理地址的相互转换程序了,这是我们的真正目的。


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

收藏
免费 7
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//