【编程技术- 不调用系统api读写物理内存的方法】此文章归类为:编程技术。
话不多说,直接上代码
PVOID Mapper = 0;
PTE_64* MapperPte = 0;
u64 MapperPteOrigPfn = 0;
VOID Init()
{
Mapper = MmAllocateIndependentPages(0x1000, -1);
memset(Mapper, 0, 0x1000);
MapperPte = MiGetPteAddress(Mapper);
MapperPteOrigPfn = MapperPte->PageFrameNumber;
}
VOID ReadPhysicalMemoryInPage(PVOID Buffer, u64 Phys, u64 Size)
{
_disable();
MapperPte->PageFrameNumber = Phys >> PAGE_SHIFT;
__invlpg(Mapper);
__movsb((PUCHAR)Buffer, (PUCHAR)Mapper + (Phys & 0xFFF), Size);
MapperPte->PageFrameNumber = MapperPteOrigPfn;
_enable();
}
原理:
先分配一个Mapper,用MmAllocateIndependentPages的原因是不会分配出大页,用ExAllocatePool等api是有概率分配出大页Pde内存的哦
获取Mapper的Pte并保存原始Pfn,用于后续还原
改Pte->Pfn使得Mapper映射我们的物理地址,刷tlb,拷贝内存,还原Pfn
关中断的原因是invlpg之后切到其他核心会导致在其他核心的tlb没被刷新从而拷贝到错误的数据,其实提升irql就行了
注意事项:
多核情况要注意分配多个Mapper给每个核心使用
仅拷贝一个页面,跨页要自己处理
未修复内存缓存属性,读物理内存没什么问题,写入物理内存就要注意了,可以通过pte.pat实现
总结:
非常简单的手动映射物理内存读写
其实类似的代码在各个开源的VT上多少有出现过
UC上的人还在用MmCopy...
更多【编程技术- 不调用系统api读写物理内存的方法】相关视频教程:www.yxfzedu.com