驱动读内存
先定义一个结构,方便应用层调用读写
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;
}
新手一个,如有错误,望指教