正文

没有用MmMapIoSpace,用了映射的方式对物理地址数据进行读写,之前测试MmMapIoSpace在win10较高版本用不了,貌似是不支持了。然后利用映射的方式测试的时候可以在win10下运行。用法和效果如下,加载驱动后,Read.exe用来读取物理地址的数据,限制为0x100字节大小,当然可以通过修改驱动代码来读取任意字节,我这里只是给了个demo;Write.exe则是对指定的物理地址进行写操作,限制了写入的大小为DWORD32,这里也可以通过修改驱动代码进行调整。

aeaa56067e197d2cf8f0583b3038bd34.png

编译好的程序在bin目录下

a83633c2d18e2e0f375cfddec33c11f9.png

这里编译的是用于64位系统的,32位的话改一下代码就可以,以后有需求的话再更新。

编译环境

VS2015+WDK10

代码

注

不是驱动大佬,可能驱动代码写的并不是很好,如果有什么意见或者驱动存在了蓝屏的问题,欢迎指出和指导

/*

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;

}

更多推荐