驱动读写应用程序内存

驱动读内存

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

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;
}

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

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾无法无天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值