没有用MmMapIoSpace,用了映射的方式对物理地址数据进行读写,之前测试MmMapIoSpace在win10较高版本用不了,貌似是不支持了。然后利用映射的方式测试的时候可以在win10下运行。用法和效果如下,加载驱动后,Read.exe用来读取物理地址的数据,限制为0x100字节大小,当然可以通过修改驱动代码来读取任意字节,我这里只是给了个demo;Write.exe则是对指定的物理地址进行写操作,限制了写入的大小为DWORD32,这里也可以通过修改驱动代码进行调整。
编译好的程序在bin目录下
这里编译的是用于64位系统的,32位的话改一下代码就可以,以后有需求的话再更新。
VS2015+WDK10
QKSword/Physical_RWgithub.com
不是驱动大佬,可能驱动代码写的并不是很好,如果有什么意见或者驱动存在了蓝屏的问题,欢迎指出和指导
/*
function
读取物理地址,大小为FF
argv
MapAddress:物理地址映射出来的地址
Physicaladdress:指定读取的物理地址
return
返回状态
*/
NTSTATUS ReadPhysicalAddress(PVOID MapAddress, DWORD64 Physicaladdress)
{
NTSTATUS status;
PVOID BaseAddress = NULL; // 映射的虚地址
DWORD32 offset;
LARGE_INTEGER SectionOffset; //存放物理地址
SIZE_T size = 0x2000; //映射大小
//打开内核对象
status = GetPhysicalHandle();
if (status < 0)
{
status = FALSE;
goto Leave;
}
//读取出来的地址是4K对齐,所以偏移自己处理一下即可
offset = Physicaladdress & 0xFFF; //取低12位作为偏移使用
SectionOffset.QuadPart = (ULONGLONG)(Physicaladdress);
// 映射物理内存地址到当前进程的虚地址空间
status = ZwMapViewOfSection(
hPhysicalhandle,
NtCurrentProcess(),
(PVOID *)&BaseAddress,
0,
size,
&SectionOffset,
&size,
ViewShare,
MEM_TOP_DOWN,
PAGE_READWRITE);
if (status < 0)
{
status = FALSE;
goto Leave;
}
//获取映射出来的数据
memmove_s(MapAddress, 0x100, (PVOID)((DWORD64)BaseAddress + offset), 0x100);
// 完成操作,取消地址映射
status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
if (status < 0)
{
status = FALSE;
goto Leave;
}
Leave:
if (hPhysicalhandle != NULL)
{
ZwClose(hPhysicalhandle);
}
return status;
}
/*
function
写物理地址,大小为DWORD
argv
PhysicalAddress:物理地址
WriteData:写入数据
return
返回状态
*/
NTSTATUS WritePhysicalMemory(DWORD64 PhysicalAddress, DWORD32 WriteData)
{
NTSTATUS status;
PVOID BaseAddress = NULL; // 映射的虚地址
DWORD32 offset;
LARGE_INTEGER SectionOffset; //存放物理地址
SIZE_T size = 0x2000; //映射大小
//打开内核对象
status = GetPhysicalHandle();
if (status < 0)
{
status = FALSE;
goto Leave;
}
offset = PhysicalAddress & 0xFFF; //取低12位作为偏移使用
SectionOffset.QuadPart = (ULONGLONG)(PhysicalAddress);
// 映射物理内存地址到当前进程的虚地址空间
status = ZwMapViewOfSection(
hPhysicalhandle,
NtCurrentProcess(),
(PVOID *)&BaseAddress,
0,
size,
&SectionOffset,
&size,
ViewShare,
MEM_TOP_DOWN,
PAGE_READWRITE);
if (status < 0)
{
status = FALSE;
goto Leave;
}
memmove_s((PVOID)((DWORD64)BaseAddress + offset), sizeof(DWORD32), &WriteData, sizeof(DWORD32));
status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
if (status < 0)
{
status = FALSE;
}
Leave:
if (hPhysicalhandle != NULL)
{
ZwClose(hPhysicalhandle);
}
return status;
}
/*
function
打开内核对象
argv
NULL
return
返回调用状态
*/
NTSTATUS GetPhysicalHandle()
{
NTSTATUS status;
UNICODE_STRING PhysicalMemoryString;
OBJECT_ATTRIBUTES attributes;
WCHAR PhysicalMemoryName[] = L"\\Device\\PhysicalMemory";
RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
status = ZwOpenSection(&hPhysicalhandle, SECTION_MAP_READ | SECTION_MAP_WRITE, &attributes);
return status;
}