CFuncGetPhysicalAddressAndPageAttributes(
unsigned int VirtualAddress,
unsigned int *PhysicalAddress,
unsigned int *PageAttributes
)
{
unsigned int *PageTableEntry;
*PhysicalAddress = 0;
*PageAttributes = 0;
PageTableEntry = (unsigned int *)0xC0000000 + (VirtualAddress >> 0x0C);
if ((*PageTableEntry)&0x01) {
*PhysicalAddress = ((*PageTableEntry)&0xFFFFF000) + (VirtualAddress&0x00000FFF);
*PageAttributes = (*PageTableEntry)&0x00000FFF;
return TRUE;
} else {
return FALSE;
}
}
CfuncGetPhysicalAddressAndPageAttributes() 函数使用调用门在内核态执行。此函数认为进程的页表总是映射在虚地址 0xC0000000 上。该地址上是一个由 1024 个页表构成的数组,每个页表又是 1024 个页表项的数组。访问此内存区时可以把它整个看作一个连续的页表项的数组。这个大数组的第一个成员对应着虚地址范围为 0到1024,第二个则对应着 4096 到 8192,依次类推。函数通过用给定的虚地址除以 1024 来计算其在大 PTE 数组中的索引——即将虚地址右移12位。将索引值加到 PTE 数组的基地址上就得到了所要的 PTE。每个 PTE 长4个字节(32位),
高20位表示物理页地址,低12位表示页属性。只有当最低位置位时,物理地址和页属性才有效。函数检查最低位是否置位,通过合适的掩码将物理页地址和页属性分离开。最后将页内偏移加到物理页地址上就得到了给定虚地址的物理地址。
虚拟地址转物理地址代码(摘自Undocument NT)
最新推荐文章于 2024-01-17 17:36:52 发布