Ring3逻辑内存地址转Ring0物理内存地址
2020-01-15 14:46:58 Author: bbs.pediy.com(查看原文) 阅读量:375 收藏

[原创]Ring3逻辑内存地址转Ring0物理内存地址

15小时前 279

[原创]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; 
	}
}

[2020元旦礼物]《看雪论坛精华17》发布!(补齐之前所有遗漏版本)!

最后于 15小时前 被hksoobe编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-257234.htm
如有侵权请联系:admin#unsafe.sh