不调用系统api读写物理内存
原理
利用内核模式下的内存映射技术,将一个物理地址映射到一个虚拟地址上,然后通过操作这个虚拟地址来读取物理内存的内容。具体步骤包括:
- 分配一个虚拟地址空间
Mapper
,确保不会分配出大页,以保证后续操作的灵活性。 - 获取
Mapper
对应的页表条目,并保存原始的页帧号。 - 修改页表条目,将
Mapper
映射到目标物理地址上,然后刷新 TLB 以确保页表修改生效。 - 关闭中断,避免并发问题。
- 使用汇编指令将物理内存数据复制到目标缓冲区。
- 恢复原始的页表条目,以确保不会影响其他操作。
- 恢复中断状态,保证系统的正常运行。
实现代码
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…
GPT优化版
#define PAGE_SIZE 4096
typedef struct _PTE_64 {
ULONG64 PageFrameNumber;
} PTE_64;
ULONG_PTR Mapper = 0;
PTE_64* MapperPte = NULL;
ULONG_PTR MapperPteOrigPfn = 0;
VOID Init()
{
// 分配 4KB 内存,并清零
Mapper = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPCM');
if (Mapper == 0) {
// 处理内存分配失败的情况
return;
}
// 获取 Mapper 对应的页表条目
MapperPte = (PTE_64*)((ULONG_PTR)Mapper & ~(PAGE_SIZE - 1));
MapperPteOrigPfn = MapperPte->PageFrameNumber;
}
VOID ReadPhysicalMemoryInPage(PVOID Buffer, ULONG_PTR Phys, SIZE_T Size)
{
// 关闭中断
ULONG_PTR oldIrql;
_disable();
// 修改页表条目,映射物理地址到 Mapper
MapperPte->PageFrameNumber = Phys >> 12;
__invlpg(Mapper);
// 拷贝内存数据到目标缓冲区
__movsb((PUCHAR)Buffer, (PUCHAR)Mapper + (Phys & (PAGE_SIZE - 1)), Size);
// 恢复原始页表条目
MapperPte->PageFrameNumber = MapperPteOrigPfn;
// 恢复中断
_enable();
}
文档信息
- 本文作者:Nattevak
- 本文链接:https://HLuKT.github.io/2024/05/16/%E7%89%A9%E7%90%86%E5%86%85%E5%AD%98%E8%AF%BB%E5%86%99/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)