阅读大神的64位逻辑地址转物理地址,本来想偷懒做个伸手党,结果找了一大圈也没找到^-^!,无奈自己撸一个吧,拙作一枚,勿笑
PS:留了小坑一枚,仔细看参考资料的自己搞定,不看的不好用别骂我~_~
/* 虚拟地址转物理地址 参数:pAddress 虚拟地址,只是简单验证合法性,乱填BSOD概不负责 参考资料:https://bbs.pediy.com/thread-203391.htm 2020年1月14日 完成编码并在IDA中验证,未考虑大分页情况 */ PVOID LogicAddressToPhysicalAddress(PVOID pAddress) { ULONG64 ulAddress = (ULONG64)pAddress; ulAddress = ((ULONG64)ulAddress >> 48) + 1; ULONG64 Cr3Addr = __readcr3(); if (ulAddress <= 1) //只要是合法地址,必然不会超过1 { PHYSICAL_ADDRESS PhysicalAddress; ulAddress = (ULONG64)pAddress; //ptme ulAddress = ulAddress << (63 - 47); ulAddress = ulAddress >> (39 + (63 - 47)); ulAddress = ulAddress & 0x1ff; HvUtilLogDebug("PTME 序号:0x%llx\n", ulAddress); //CR3为PTEM地址,通过序号计算,得到PTEM链表中的偏移 ULONG64 PTEMAddr = Cr3Addr + (ulAddress * 8); HvUtilLogDebug("PTME 地址:0x%llx\n", PTEMAddr); //读取PTEM项中存放的地址,该地址位PDPT的地址,这个地址只需要12到35位,并在低12位补零 PhysicalAddress.QuadPart = PTEMAddr; ulAddress = *(PULONG64)MmGetVirtualForPhysical(PhysicalAddress); HvUtilLogDebug("读取到的PDPT:0x%llx\n", ulAddress); //计算PDPT ulAddress = (ulAddress << 28); ULONG64 PDPTAddr = (ulAddress >> (28 + 12)) << 12; HvUtilLogDebug("PDPTAddr基址 0x%llx\n", PDPTAddr); //计算PDPT序号 ulAddress = (ULONG64)pAddress; ulAddress = ulAddress << (63 - 38); ulAddress = ulAddress >> 30 + (63 - 38); HvUtilLogDebug("PDPT 序号:0x%llx\n", ulAddress); //计算PDPT中的偏移 PDPTAddr = PDPTAddr + (ulAddress * 8); //读取PDPT中的地址,该值位PDE的基址 PhysicalAddress.QuadPart = PDPTAddr; ulAddress = *(PULONG64)MmGetVirtualForPhysical(PhysicalAddress); HvUtilLogDebug("读取到PDE基址偏移:0x%llx\n", ulAddress); //计算PDE基址 ulAddress = (ulAddress << 28); ULONG64 PDEAddr = (ulAddress >> (28 + 12)) << 12; HvUtilLogDebug("PDE基址:0x%llx\n", PDEAddr); //计算PDE序号 ulAddress = (ULONG64)pAddress; ulAddress = ulAddress << (63 - 29); ulAddress = ulAddress >> 21 + (63 - 29); HvUtilLogDebug("PDE序号 0x%llx\n", ulAddress); //计算PDE中偏移,该值为PTE的基址 PDEAddr = PDEAddr + (ulAddress * 8); PhysicalAddress.QuadPart = PDEAddr; ulAddress = *(PULONG64)MmGetVirtualForPhysical(PhysicalAddress); HvUtilLogDebug("读取到PTE地址 0x%llx\n", ulAddress); ulAddress = (ulAddress << 28); ULONG64 PTEAddr = (ulAddress >> (28 + 12)) << 12; HvUtilLogDebug("PTE地址 0x%llx\n", PTEAddr); //计算PTE序号 ulAddress = (ULONG64)pAddress; ulAddress = ulAddress << (63 - 20); ulAddress = ulAddress >> 12 + (63 - 20); HvUtilLogDebug("PTE序号 0x%llx\n", ulAddress); //计算PTE偏移,该偏移为页地址 PTEAddr = PTEAddr + (ulAddress * 8); //读取PTE的地址,该地址为页地址 PhysicalAddress.QuadPart = PTEAddr; ulAddress = *(PULONG64)MmGetVirtualForPhysical(PhysicalAddress); HvUtilLogDebug("读取到页地址 0x%llx\n", ulAddress); ulAddress = (ulAddress << 28); ULONG64 PageAddr = (ulAddress >> (28 + 12)) << 12; HvUtilLogDebug("页地址 0x%llx\n", PageAddr); //计算页地址偏移量 ulAddress = (ULONG64)pAddress; ulAddress = ulAddress << (63 - 12); ulAddress = ulAddress >> (63 - 12); HvUtilLogDebug("页地址偏移量为 0x%llx\n", ulAddress); ulAddress = PageAddr + ulAddress; HvUtilLogDebug("修正页地址 0x%llx\n", ulAddress); return (PVOID)ulAddress; } }
[2020元旦礼物]《看雪论坛精华17》发布!(补齐之前所有遗漏版本)!
最后于 15小时前 被hksoobe编辑 ,原因: