驱动读写应用程序内存

驱动读内存

先定义一个结构,方便应用层调用读写

typedef struct DATA
{
	DWORD pid;//不用HANDLE类型也可以,个人觉得用DWORD方便应用层调用
	unsigned __int64 address;
	int data;
}Data;

读内存

1.使用通过进程ID获取进程对象PsLookupProcessByProcessId,此时内核对象引用数会加1
2.KeStackAttachProcess进入进程的地址空间
3.ProbeForRead检查内存地址是否有效
4.RtlCopyMemory将指定的内存Copy到一个缓冲区,至此,内存已经读到
5.收尾:
调用KeUnstackDetachProcess解除与进程的绑定,退出进程地址空间,
调用ObDereferenceObject使内核中对象引用数减1

BOOL ReadMemory(Data* data)
{
	PEPROCESS process=NULL;
	//获取进程对象
	NTSTATUS status = PsLookupProcessByProcessId(data->pid,&process);

	if (process == NULL)
	{
		DbgPrint("获取进程对象失败,PID:%d",data->pid);
		return FALSE;
	}

	KAPC_STATE state = { 0 };
	//绑定进程对象,进入进程地址空间
	KeStackAttachProcess(process, &state);

	__try
	{
		//读取内存
		ProbeForRead(data->address, sizeof(data->data), 1);
		RtlCopyMemory(&(data->data), data->address, sizeof(data->data));
	}
	__except(1)
	{
		//解除绑定
		KeUnstackDetachProcess(&state);
		//让内核对象引用数减1
		ObDereferenceObject(process);
		DbgPrint("读取进程 %d 的地址 %x 出错", data->pid, data->address);
		return FALSE;
	}

	//解除绑定
	KeUnstackDetachProcess(&state);
	//让内核对象引用数减1
	ObDereferenceObject(process);
	DbgPrint("进程 %d 地址 %x 数据:%d", data->pid, data->address, data->data);

	return TRUE;
}

写内存

1.使用通过进程ID获取进程对象PsLookupProcessByProcessId,此时内核对象引用数会加1
2.KeStackAttachProcess进入进程的地址空间
3.IoAllocateMdl创建地址描述符
4.MmBuildMdlFornon将该内存与我们的驱动绑定
5.调用MmMapLockedPages将MDL映射到我们驱动里的一个变量,对该变量读写就是对MDL对应的物理内存读写
6.用RtlCopyMemory来修改对应内存储存的数值
7.收尾:
MmUnmapLockedPages解除映射,
KeUnstackDetachProcess解除与进程的绑定,退出进程地址空间,
ObDereferenceObject使内核中对象引用数减1

BOOL WriteMemory(Data* data)
{
	PEPROCESS process=NULL;
	//获取进程对象
	PsLookupProcessByProcessId(data->pid, &process);

	if (process == NULL)
	{
		DbgPrint("获取进程对象失败");
		return FALSE;
	}

	KAPC_STATE state = { 0 };
	//绑定进程
	KeStackAttachProcess(process, &state);

	//创建MDL
	PMDL mdl = IoAllocateMdl(data->address, sizeof(data->data), 0, 0, NULL);
	if (mdl == NULL)
	{
		DbgPrint("创建MDL失败");
		return FALSE;
	}

	//使MDL与驱动进行绑定
	MmBuildMdlForNonPagedPool(mdl);

	int* ChangeData = NULL;

	__try
	{
		//将内存映射到ChangeData
		ChangeData = MmMapLockedPages(mdl, KernelMode);
	}
	__except (1)
	{
		DbgPrint("映射内存失败");
		IoFreeMdl(mdl);
		KeUnstackDetachProcess(&state);
		//让内核对象引用数减1
		ObDereferenceObject(process);
		return FALSE;
	}

	RtlCopyMemory(ChangeData, &(data->data), sizeof(data->data));
	DbgPrint("进程ID:%d 地址:%x 写入数据:%d",data->pid, data->address,*ChangeData);

	//让内核对象引用数减1
	ObDereferenceObject(process);
	MmUnmapLockedPages(ChangeData, mdl);
	KeUnstackDetachProcess(&state);
	return TRUE;
}

新手一个,如有错误,望指教

发布了23 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44286745/article/details/100070288