首页
社区
课程
招聘
[原创]Ring3逻辑内存地址转Ring0物理内存地址
发表于: 2020-1-14 22:15 8915

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

2020-1-14 22:15
8915
阅读大神的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; 
	}
}


[课程]Linux pwn 探索篇!

最后于 2020-1-14 22:16 被hksoobe编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 583
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢楼主分享技术文章。
2020-1-15 16:00
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
留啥坑呀...
2020-4-4 20:42
0
雪    币: 14
活跃值: (948)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢
2020-12-15 10:47
0
游客
登录 | 注册 方可回帖
返回
//