驱动开发:通过内存拷贝读写内存

举报
王瑞专家 发表于 2022/11/02 14:13:15 2022/11/02
1.7k+ 0 0
【摘要】 内核中读写内存的方式有很多,典型的读写方式有CR3读写,MDL读写,以及今天要给大家分享的内存拷贝实现读写,拷贝读写的核心是使用`MmCopyVirtualMemory`这个内核API函数实现,通过调用该函数即可很容易的实现内存的拷贝读写。

内核中读写内存的方式有很多,典型的读写方式有CR3读写,MDL读写,以及今天要给大家分享的内存拷贝实现读写,拷贝读写的核心是使用MmCopyVirtualMemory这个内核API函数实现,通过调用该函数即可很容易的实现内存的拷贝读写。

封装KeReadProcessMemory()内存读取。

#include <ntifs.h>
#include <windef.h>
#include <stdlib.h>

NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);
NTSTATUS NTAPI MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize);

// 定义全局EProcess结构
PEPROCESS Global_Peprocess = NULL;

// 普通Ke内存读取
NTSTATUS KeReadProcessMemory(PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
	__try
	{
		PEPROCESS TargetProcess = PsGetCurrentProcess();
		SIZE_T Result;
		if (NT_SUCCESS(MmCopyVirtualMemory(Global_Peprocess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
			return STATUS_SUCCESS;
		else
			return STATUS_ACCESS_DENIED;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return STATUS_ACCESS_DENIED;
	}
	return STATUS_ACCESS_DENIED;
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver Is OK \n");
}

// By:lyshark.cnblogs.com
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("hello lyshark \n");

	// 根据PID打开进程
	DWORD PID = 6672;
	NTSTATUS nt = PsLookupProcessByProcessId((HANDLE)PID, &Global_Peprocess);

	DWORD ref_value = 0;

	// 将地址处读取4字节到ref_value中
	NTSTATUS read_nt = KeReadProcessMemory((PVOID)0x0009EDC8, &ref_value, 4);

	DbgPrint("读出数据: %d \n", ref_value);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

读取效果如下:

image.png

封装KeWriteProcessMemory()内存读取。

#include <ntifs.h>
#include <windef.h>
#include <stdlib.h>

NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);
NTSTATUS NTAPI MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize);

// 定义全局EProcess结构
PEPROCESS Global_Peprocess = NULL;
// 普通Ke内存写入
NTSTATUS KeWriteProcessMemory(PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
	PEPROCESS SourceProcess = PsGetCurrentProcess();
	PEPROCESS TargetProcess = Global_Peprocess;
	SIZE_T Result;

	if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
		return STATUS_SUCCESS;
	else
		return STATUS_ACCESS_DENIED;
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver Is OK \n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("hello lyshark \n");

	// 根据PID打开进程
	DWORD PID = 6672;
	NTSTATUS nt = PsLookupProcessByProcessId((HANDLE)PID, &Global_Peprocess);

	DWORD ref_value = 10;

	// 将地址处写出4字节
	NTSTATUS read_nt = KeWriteProcessMemory((PVOID)0x0009EDC8, &ref_value, 4);

	DbgPrint("写入数据: %d \n", ref_value);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

写出内存效果:

image.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。