映射物理页的方法
windows提供了MmMapIoSpace/MmCopyMemory来进行物理页映射(读取物理页存储的数据),如何自写函数实现类似功能 参(chao)考(xi)泄露的WINDOWS源码,或REACTOS相关函数的源码。 Tesla.Angela 发表于 2023-5-13 03:33参(chao)考(xi)泄露的WINDOWS源码,或REACTOS相关函数的源码。
我反汇编了这些函数,也看了REACTOS对应源码,里面函数嵌套太多了,我便想用自己的方法解决,首先我知道X64页表是四级的,而我只需要在系统进程的页表里找到一个4KB空白页表,然后把物理页写进空白页表的PTE,便可直接映射这个物理页,我测试很多系统虚拟机都没问题,但是频繁读写就会内存蓝屏 //函数原理是把参数Physicaladdress映射一个虚拟地址,再读取这个虚拟地址的内容复制给参数1,Size最多4KB
//思路:寻找个内核内存的空白4K页,用于赋值虚拟地址
NTSTATUS ReadPhysicalAddress(PVOID lpBuffer, ULONG64 Physicaladdress, SIZE_T Size)//效率很高
{
//PAadress:接收VaToPa 返回的VA地址的PTE虚拟地址,
//VAadress:接收VaToPa 返回的VA地址,
static PL4PTE PTEadress ;
static VA VAadress ;
if (!Physicaladdress )
return STATUS_UNSUCCESSFUL;
//system进程里找到个空白的4K页用于自写映射,VAadress是找到的空白4K页的虚拟地址,PTEadress是这个虚拟地址的PTE
if (VAadress.Value == 0)
{
VAadress.Value = VaToPa(&PTEadress);
}
//Physicaladdress 传进来的是是ppn+ppo
//adress是实际虚拟地址 后12位是ppo
ULONG64 reallyadress = VAadress.Value + (Physicaladdress & 0xfff);
//不加这个就读内存
//MySleep(1);
KIRQLirql = WPOFFx64();
PTEadress->Value = (Physicaladdress & 0xFFFFFFFFFF000);
PTEadress->Fields.U_S = 0;
PTEadress->Fields.PCD = 1;
PTEadress->Fields.G = 1;
PTEadress->Fields.R_W = 1;
PTEadress->Fields.P = 1;
RtlCopyMemory(lpBuffer, reallyadress, Size);
DbgPrint("%llx%llx %llx %llx\n", *(PLONG64)reallyadress, VAadress.Value, Physicaladdress, PTEadress);
RtlZeroMemory(PTEadress,8);
WPONx64(irql);
return STATUS_SUCCESS;
} 如图 blackbox 发表于 2023-6-28 21:13
//函数原理是把参数Physicaladdress映射一个虚拟地址,再读取这个虚拟地址的内容复制给参数1,Size最多4KB
...
还是有问题的,测试没啥问题,但是死循环读写就会蓝屏,具体原因还没想到
页:
[1]