完整工程:
链接:https://pan.baidu.com/s/1IGrYu60Mr9gjCLtq-tSqLA
提取码:rrsr
头文件
#pragma once
#include<ntifs.h>
#include<windef.h>
#define READCODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define WRITECODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define DEVICENAME L"\\Device\\ReadWriteDevice"
#define SYMBOLNAME L"\\??\\ReadWriteSymbolName"
typedef struct DATA
{
DWORD pid;//要读写的进程ID
unsigned __int64 address;//要读写的地址
DWORD size;//读写长度
BYTE* data;//要读写的数据,
}Data;
void DriverUnload(PDRIVER_OBJECT driver);
NTSTATUS CreateDevice(PDRIVER_OBJECT driver);
NTSTATUS DriverIrpCtl(PDEVICE_OBJECT device, PIRP pirp);
BOOL ReadMemory(Data* data);
BOOL WriteMemory(Data* data);
.C文件
#include"Driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING path)
{
DbgPrint("驱动已加载,路径:%wZ", path);
driver->DriverUnload = DriverUnload;
CreateDevice(driver);
driver->MajorFunction[IRP_MJ_CREATE] = DriverIrpCtl;
driver->MajorFunction[IRP_MJ_CLOSE] = DriverIrpCtl;
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverIrpCtl;
return STATUS_SUCCESS;
}
void DriverUnload(PDRIVER_OBJECT driver)
{
if (driver->DeviceObject)
{
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SYMBOLNAME);
IoDeleteSymbolicLink(&SymbolName);
IoDeleteDevice(driver->DeviceObject);
}
DbgPrint("驱动已卸载");
}
NTSTATUS CreateDevice(PDRIVER_OBJECT driver)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT device=NULL;
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, DEVICENAME);
status = IoCreateDevice(
driver,
sizeof(driver->DriverExtension),
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&device
);
if (status == STATUS_SUCCESS)
{
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SYMBOLNAME);
status = IoCreateSymbolicLink(&SymbolName, &DeviceName);
if (status != STATUS_SUCCESS)
{
DbgPrint("创建符号链接失败");
IoDeleteDevice(device);
}
}
DbgPrint("驱动设备已创建");
return status;
}
NTSTATUS DriverIrpCtl(PDEVICE_OBJECT device, PIRP pirp)
{
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(pirp);
Data* data;
switch (stack->MajorFunction)
{
case IRP_MJ_CREATE:
{
DbgPrint("设备已打开");
break;
}
case IRP_MJ_CLOSE:
{
DbgPrint("设备已关闭");
break;
}
case IRP_MJ_DEVICE_CONTROL:
{
data=pirp->AssociatedIrp.SystemBuffer;
DbgPrint("PID:%d 地址:%x 大小:%d",data->pid,data->address,data->size);
switch (stack->Parameters.DeviceIoControl.IoControlCode)
{
case READCODE:
{
ReadMemory(data);
break;
}
case WRITECODE:
{
WriteMemory(data);
break;
}
}
pirp->IoStatus.Information = sizeof(data);
break;
}
}
pirp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
BOOL ReadMemory(Data* data)
{
BOOL bRet=TRUE;
PEPROCESS process = NULL;
PsLookupProcessByProcessId(data->pid, &process);
if (process == NULL)
{
DbgPrint("获取进程对象失败");
return FALSE;
}
BYTE* GetData;
__try
{
GetData = ExAllocatePool(PagedPool, data->size);
}
__except (1)
{
DbgPrint("内存分配失败");
return FALSE;
}
KAPC_STATE stack = {0};
KeStackAttachProcess(process, &stack);
__try
{
ProbeForRead(data->address, data->size, 1);
RtlCopyMemory(GetData, data->address, data->size);
}
__except (1)
{
DbgPrint("读取内存出错");
bRet = FALSE;
}
ObDereferenceObject(process);
KeUnstackDetachProcess(&stack);
RtlCopyMemory(data->data, GetData, data->size);
/*DbgPrint("进程ID:%d",data->pid);
for (int i = 0; i < data->size; i++)
{
//data->data[i] = GetData[i];
DbgPrint("地址:%x 数据:%x data:%x", data->address+i,GetData[i],data->data[i]);
}
DbgPrint("输出完毕");*/
ExFreePool(GetData);
return bRet;
}
BOOL WriteMemory(Data* data)
{
BOOL bRet = TRUE;
PEPROCESS process=NULL;
PsLookupProcessByProcessId(data->pid, &process);
if (process == NULL)
{
DbgPrint("获取进程对象失败");
return FALSE;
}
//在进入进程地址空间之前先赋值
BYTE* GetData;
__try
{
GetData = ExAllocatePool(PagedPool, data->size);
}
__except (1)
{
DbgPrint("内存分配失败");
return FALSE;
}
for (int i = 0; i < data->size; i++)
{
GetData[i] = data->data[i];
}
KAPC_STATE stack = {0};
KeStackAttachProcess(process, &stack);
PMDL mdl = IoAllocateMdl(data->address, data->size, 0, 0, NULL);
if (mdl == NULL)
{
DbgPrint("创建MDL失败");
return FALSE;
}
MmBuildMdlForNonPagedPool(mdl);
BYTE* ChangeData = NULL;
__try
{
ChangeData = MmMapLockedPages(mdl, KernelMode);
RtlCopyMemory(ChangeData, GetData, data->size);
}
__except (1)
{
DbgPrint("内存映射失败,%d",sizeof(ChangeData));
bRet = FALSE;
goto END;
}
END:
IoFreeMdl(mdl);
ExFreePool(GetData);
KeUnstackDetachProcess(&stack);
ObDereferenceObject(process);
return bRet;
}