-
-
[原创]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,这样我们就可以编写自己的虚拟地址和物理地址的相互转换程序了,这是我们的真正目的。