首页
社区
课程
招聘
[求助]NewBluePill获取下级页目录的虚拟地址公式没有看懂求指点
发表于: 2018-5-30 23:32 2096

[求助]NewBluePill获取下级页目录的虚拟地址公式没有看懂求指点

2018-5-30 23:32
2096

问题在 下面这个公式 

/----------------------------------------------------------------------------------------------------------------------------

LowerPageTable = (PULONG64)(g_PageTableBases[bLevel - 2] + 8 * (i << (9 * (5 - bLevel))));


这个公式是NBP 中的 在复制windows 也分的时候用来获取下级页目录所映射的虚拟地址。。这个公式用于当前我们在3或2级页目录  取 2级 和1 级页目录 的虚拟地址 (也就是获取下级页目录所映射的虚拟地址),只有获取下级页目录的虚拟地址才能继续Walk 判断是否有值 ,,,,
我的疑惑点在于 ,比如 当前我们在二级页目录  通过下标 i  可以得到对应的一级页目录的物理地址 ,如果 i  下标所对应的项不为0    那么就获取下级页目录的虚拟地址  通过这个公式  ,     但是  i 的范围只有0-512   一个页内的项数  , 但是二级页目录 有很多个  ,为什么通过上面这个公式就能计算出  该二级页目录内 i 所对应项 的 一级页目录的  虚拟地址?






 ULONG64 g_PageTableBases[4] = {
PT_BASE,
PD_BASE,
PDP_BASE,
PML4_BASE
};

NTSTATUS NTAPI MmWalkGuestPageTable(
PULONG64 PageTable, //3级页表的虚拟地址
UCHAR bLevel  //当前页表的级数
)
{
ULONG64 i;
PVOID VirtualAddress;
PUCHAR ShortPageVA;
PHYSICAL_ADDRESS PhysicalAddress;
PULONG64 LowerPageTable; //低一级页表

if (!MmIsAddressValid(PageTable))
return STATUS_SUCCESS;

for (i = 0; i < 0x200; i++)  //每一个页表有0x200=512项 页表项

if (PageTable[i] & P_PRESENT) {//判断表项是否有值

if (((bLevel == 2) && (PageTable[i] & P_LARGE)) || (bLevel == 1)) // 判断是否是二级页表或者一级页表 //根据自映射关系,计算虚拟地址
{
if (bLevel == 1)
VirtualAddress = (PVOID)(((LONGLONG)(&PageTable[i]) - PT_BASE) << 9);   //得到1级页表项对应的的虚拟地址
else
VirtualAddress = (PVOID)(((LONGLONG)(&PageTable[i]) - PD_BASE) << 18); //大页面的情况下就得到二级页表项对应的虚拟地址


  //不管是一级页表虚拟地址还是二级页表虚拟地址 ;都是最低层页表了,  所以把这个虚拟地址处理一下 
if ((LONGLONG)VirtualAddress & 0x0000800000000000)  //判断该虚拟地址是否为内核地址
VirtualAddress = (PVOID)((LONGLONG)VirtualAddress | 0xffff000000000000); //设置高16 位全为FFFFF

PhysicalAddress.QuadPart = PageTable[i] & 0x000ffffffffff000;//2M或4K页表的物理地址

if ((ULONGLONG)VirtualAddress >= PT_BASE && (ULONGLONG)VirtualAddress < PML4_BASE + 0x1000)
// guest pagetable stuff here - so don't map it
continue; //客户机页表自映射,宿主机不映射

DbgPrint("MmWalkGuestPageTable(): %sValid pl%d at 0x%p, index 0x%x, VA 0x%p, PA 0x%p %s\n", bLevel == 3 ? "   " : bLevel == 2 ? "      " : bLevel == 1 ? "         " : "", bLevel, &PageTable[i], i, VirtualAddress, PhysicalAddress.QuadPart, ((bLevel == 2) && (PageTable[i] & P_LARGE)) ? "LARGE" : "");

if (bLevel == 2)
{//Large Page分开映射成标准4k页
for (ShortPageVA = (PUCHAR)VirtualAddress + 0x0 * PAGE_SIZE;
ShortPageVA < (PUCHAR)VirtualAddress + 0x200 * PAGE_SIZE;
ShortPageVA += PAGE_SIZE, PhysicalAddress.QuadPart += PAGE_SIZE)
MmCreateMapping(PhysicalAddress, ShortPageVA, FALSE);
}
else
MmCreateMapping(PhysicalAddress, VirtualAddress, FALSE);
}

if ((bLevel > 1) && !((bLevel == 2) && (PageTable[i] & P_LARGE)))  //如果当前页表级数大于 1 并且 页表等级不等2 或者不为 大页面 则
{
LowerPageTable = (PULONG64)(g_PageTableBases[bLevel - 2] + 8 * (i << (9 * (5 - bLevel))));  //得到每一项 下级页表的物理地址对应的虚拟地址
MmWalkGuestPageTable(LowerPageTable, bLevel - 1);//遍历下一级页表
}
}




[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-5-31 09:05 被兔oO编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//