-
-
[原创]Ring3逻辑内存地址转Ring0物理内存地址
-
发表于:
2020-1-14 22:15
8916
-
[原创]Ring3逻辑内存地址转Ring0物理内存地址
阅读大神的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;
}
}
[课程]Android-CTF解题方法汇总!
最后于 2020-1-14 22:16
被hksoobe编辑
,原因: