Kernel Memory Dump
Ring 0Dump process memory using kernel-level APIs to bypass usermode protections.
KsDumper-style
This feature uses MmCopyVirtualMemory for direct kernel-to-kernel memory transfer, similar to the KsDumper tool.
Overview
Protected processes (PPL, AV, EDR) often prevent memory reading via standard APIs like ReadProcessMemory. The kernel memory dump feature bypasses these restrictions by using MmCopyVirtualMemory directly from Ring 0.
Implementation
Kernel Copy Memory
NTSTATUS KernelCopyMemory(
ULONG TargetProcessId,
ULONG64 SourceAddress,
ULONG64 DestinationAddress, // In caller's process
ULONG Size,
PULONG BytesCopied
) {
PEPROCESS SourceProcess;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
SIZE_T NumberOfBytes = 0;
// 1. Get target process EPROCESS
NTSTATUS Status = PsLookupProcessByProcessId(
(HANDLE)TargetProcessId,
&SourceProcess
);
if (!NT_SUCCESS(Status)) return Status;
// 2. Use MmCopyVirtualMemory for direct transfer
// This function is undocumented but widely used
Status = MmCopyVirtualMemory(
SourceProcess, // Source process
(PVOID)SourceAddress, // Source address
CurrentProcess, // Destination process (caller)
(PVOID)DestinationAddress, // Destination address
(SIZE_T)Size, // Size to copy
KernelMode, // Previous mode
&NumberOfBytes // Bytes copied
);
*BytesCopied = (ULONG)NumberOfBytes;
ObDereferenceObject(SourceProcess);
return Status;
}API
Usage
use callback::kernel_copy_memory;
use process::get_process_modules;
// Get main module info
let modules = get_process_modules(pid)?;
let main_module = &modules[0]; // First module is usually the main exe
// Allocate buffer for dump
let mut buffer = vec![0u8; main_module.size as usize];
// Read memory via kernel
let bytes_copied = kernel_copy_memory(
pid,
main_module.base_address,
buffer.as_mut_ptr() as u64,
buffer.len() as u32
)?;
// Save dump to file
std::fs::write("dump.bin", &buffer[..bytes_copied as usize])?;Request Structures
Structures
struct KernelCopyMemoryRequest {
ULONG TargetProcessId; // Target process PID
ULONG64 SourceAddress; // Address in target to read
ULONG64 DestinationAddress; // Address in caller's buffer
ULONG Size; // Bytes to copy (max 64MB)
};
struct KernelCopyMemoryResponse {
ULONG BytesCopied;
BOOLEAN Success;
};IOCTL
| IOCTL | Code | Description |
|---|---|---|
| COPY_MEMORY | 0x00222180 | Copy memory from target process |
What Can Be Dumped
- ✓ Protected processes (AV, EDR)
- ✓ PPL (Protected Process Light)
- ✓ LSASS (credential dumping)
- ✓ Processes with ObRegisterCallbacks protection
- ✓ Any committed memory regions
UI Access
Right-click process → Miscellaneous → Kernel (Ring 0) → 📦 Dump Process
The dump operation:
- Gets the main module base address and size
- Allocates a buffer and calls
kernel_copy_memory() - Opens a save dialog for destination file
- Saves the raw memory dump to disk
PE Reconstruction
The dumped file is a raw memory dump, not a valid PE file. For static analysis:
- • IAT may need reconstruction — Imports are resolved to runtime addresses
- • Use PE-bear or Scylla — Tools to rebuild IAT from memory dump
- • Section alignment — Memory dump has section alignment, not file alignment
Limitations
- • Maximum 64MB per request (larger dumps need multiple calls)
- • Cannot dump non-committed memory
- • PAGE_GUARD pages may cause issues
- • Some kernel-protected memory still inaccessible
Use Cases
- • Dump protected PE files from memory
- • Credential extraction from LSASS
- • Malware analysis of packed/protected samples
- • Forensic collection of running process memory