blackbox 发表于 2023-5-12 22:26:29

映射物理页的方法

windows提供了MmMapIoSpace/MmCopyMemory来进行物理页映射(读取物理页存储的数据),如何自写函数实现类似功能

Tesla.Angela 发表于 2023-5-13 03:33:56

参(chao)考(xi)泄露的WINDOWS源码,或REACTOS相关函数的源码。

blackbox 发表于 2023-6-28 21:12:12

Tesla.Angela 发表于 2023-5-13 03:33
参(chao)考(xi)泄露的WINDOWS源码,或REACTOS相关函数的源码。

我反汇编了这些函数,也看了REACTOS对应源码,里面函数嵌套太多了,我便想用自己的方法解决,首先我知道X64页表是四级的,而我只需要在系统进程的页表里找到一个4KB空白页表,然后把物理页写进空白页表的PTE,便可直接映射这个物理页,我测试很多系统虚拟机都没问题,但是频繁读写就会内存蓝屏

blackbox 发表于 2023-6-28 21:13:35

//函数原理是把参数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:19:23

如图

blackbox 发表于 2023-6-29 12:50:56

blackbox 发表于 2023-6-28 21:13
//函数原理是把参数Physicaladdress映射一个虚拟地址,再读取这个虚拟地址的内容复制给参数1,Size最多4KB
...

还是有问题的,测试没啥问题,但是死循环读写就会蓝屏,具体原因还没想到
页: [1]
查看完整版本: 映射物理页的方法