前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >物理地址读写驱动

物理地址读写驱动

作者头像
战神伽罗
发布2021-01-06 10:52:21
2.4K2
发布2021-01-06 10:52:21
举报

正文

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

编译好的程序在bin目录下

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

编译环境

VS2015+WDK10

代码

QKSword/Physical_RW​github.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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
  • 编译环境
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档