π Template to read / write the Process Memory from the Kernel (kernelmode) π§
How does it Work?
A: It uses the undocumented NT API "MmCopyVirtualMemory" function in ntoskrnl.exe (Windows NT operating system kernel)
#include <ntdef.h>
#include <ntifs.h>
DRIVER_INITIALIZE DriverEntry;
#pragma alloc_text(INIT, DriverEntry)
// API function from ntoskrnl.exe which we use
// to copy memory to and from an user process.
NTSTATUS NTAPI MmCopyVirtualMemory
(
PEPROCESS SourceProcess,
PVOID SourceAddress,
PEPROCESS TargetProcess,
PVOID TargetAddress,
SIZE_T BufferSize,
KPROCESSOR_MODE PreviousMode,
PSIZE_T ReturnSize
);
NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
_In_ HANDLE ProcessId,
_Outptr_ PEPROCESS* Process
);
NTSTATUS KeReadProcessMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size) {
// Since the process we are reading from is the input process, we set
// the source process variable for that.
PEPROCESS SourceProcess = Process;
// Since the "process" we read the output to is this driver
// we set the target process as the current module.
PEPROCESS TargetProcess = PsGetCurrentProcess();
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
return STATUS_SUCCESS; // operation was successful
else
return STATUS_ACCESS_DENIED;
}
NTSTATUS KeWriteProcessMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size) {
// This write func is just like the read func, except vice versa.
// Since the process writing from is our module
// change the source process variable for that.
PEPROCESS SourceProcess = PsGetCurrentProcess();
// Since the process we write to is the input process
// we set the target process as the argument
PEPROCESS TargetProcess = Process;
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))
return STATUS_SUCCESS; // operation was successful
else
return STATUS_ACCESS_DENIED;
}
NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT* DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
int Writeval = 666;
PEPROCESS Process; // our target process
// enter your process ID here.
PsLookupProcessByProcessId(4872, &Process); //lookup the process by it's id;
KeWriteProcessMemory(Process, &Writeval, 0x010F29B0, sizeof(__int32));
DbgPrint("Value of int i: %d", Writeval);
return STATUS_SUCCESS;
}