D
DioProcess

Physical Memory Access

Ring -1

Read and write physical RAM directly via hypervisor Virtual Machine eXit (VMCALL) operations, bypassing all kernel protections.

Extreme Caution

Direct physical memory access can corrupt system data, cause BSODs, or permanently damage the system. Only use on test systems with full backups.

Overview

The DioProcess hypervisor provides direct physical memory access via VMCALL instructions. This bypasses all kernel-level protections including:

  • • Memory protection (PAGE_GUARD, etc.)
  • • Kernel-mode address validation
  • • Memory access callbacks
  • • Secure kernel isolation

CR3 Page Table Walk

To access process memory physically, the hypervisor walks page tables using the target process's CR3 register value:

Virtual to Physical Translation
PHYSICAL_ADDRESS TranslateVirtualToPhysical(
    ULONG64 Cr3,           // Target process CR3
    ULONG64 VirtualAddress
) {
    // 4-level paging: PML4 -> PDPT -> PD -> PT -> Physical
    
    // 1. Get PML4 entry (bits 47:39 of VA)
    ULONG64 Pml4Index = (VirtualAddress >> 39) & 0x1FF;
    ULONG64 Pml4Entry = ReadPhysical(Cr3 + Pml4Index * 8);
    if (!(Pml4Entry & 1)) return 0;  // Not present
    
    // 2. Get PDPT entry (bits 38:30)
    ULONG64 PdptBase = Pml4Entry & PHYS_ADDR_MASK;
    ULONG64 PdptIndex = (VirtualAddress >> 30) & 0x1FF;
    ULONG64 PdptEntry = ReadPhysical(PdptBase + PdptIndex * 8);
    if (!(PdptEntry & 1)) return 0;
    
    // Check for 1GB huge page
    if (PdptEntry & (1 << 7)) {
        return (PdptEntry & HUGE_PAGE_MASK) + (VirtualAddress & 0x3FFFFFFF);
    }
    
    // 3. Get PD entry (bits 29:21)
    ULONG64 PdBase = PdptEntry & PHYS_ADDR_MASK;
    ULONG64 PdIndex = (VirtualAddress >> 21) & 0x1FF;
    ULONG64 PdEntry = ReadPhysical(PdBase + PdIndex * 8);
    if (!(PdEntry & 1)) return 0;
    
    // Check for 2MB large page
    if (PdEntry & (1 << 7)) {
        return (PdEntry & LARGE_PAGE_MASK) + (VirtualAddress & 0x1FFFFF);
    }
    
    // 4. Get PT entry (bits 20:12)
    ULONG64 PtBase = PdEntry & PHYS_ADDR_MASK;
    ULONG64 PtIndex = (VirtualAddress >> 12) & 0x1FF;
    ULONG64 PtEntry = ReadPhysical(PtBase + PtIndex * 8);
    if (!(PtEntry & 1)) return 0;
    
    // 5. Final physical address
    return (PtEntry & PHYS_ADDR_MASK) + (VirtualAddress & 0xFFF);
}

VMCALL Interface

Hypervisor VMCALL Handling
// VMCALL from ring 0 driver to hypervisor
NTSTATUS HvReadPhysical(
    PHYSICAL_ADDRESS PhysAddr,
    PVOID Buffer,
    SIZE_T Size
) {
    VMCALL_DATA Data = {
        .Operation = HV_READ_PHYSICAL,
        .PhysicalAddress = PhysAddr.QuadPart,
        .Buffer = Buffer,
        .Size = Size
    };
    
    // Execute VMCALL with hypercall key
    __vmcall(HYPERCALL_KEY, &Data);
    
    return Data.Status;
}

// Hypervisor side: handle VMCALL in VM Exit handler
VOID VmExitHandler_Vmcall(PVCPU_CONTEXT Vcpu) {
    PVMCALL_DATA Data = (PVMCALL_DATA)Vcpu->Rdi;
    
    if (Vcpu->Rax != HYPERCALL_KEY) {
        InjectException(Vcpu, INVALID_OPCODE);
        return;
    }
    
    switch (Data->Operation) {
        case HV_READ_PHYSICAL:
            // Direct physical memory copy
            memcpy(
                Data->Buffer,
                PhysToVirt(Data->PhysicalAddress),
                Data->Size
            );
            Data->Status = STATUS_SUCCESS;
            break;
            
        case HV_WRITE_PHYSICAL:
            memcpy(
                PhysToVirt(Data->PhysicalAddress),
                Data->Buffer,
                Data->Size
            );
            Data->Status = STATUS_SUCCESS;
            break;
    }
}

API

Usage
use callback::{hv_read_physical, hv_write_physical, hv_translate_virtual};

// Translate virtual address to physical
let cr3 = get_process_cr3(pid)?;
let phys_addr = hv_translate_virtual(cr3, virtual_addr)?;

// Read physical memory
let mut buffer = [0u8; 4096];
hv_read_physical(phys_addr, &mut buffer)?;

// Write physical memory
let data = [0x90u8; 5];  // 5 NOPs
hv_write_physical(phys_addr, &data)?;

// Combined: read process memory via physical
let mut value: u64 = 0;
hv_read_process_memory(pid, virtual_addr, &mut value)?;

IOCTLs

IOCTLCodeDescription
HV_READ_PHYSICAL0x810Read physical memory
HV_WRITE_PHYSICAL0x811Write physical memory
HV_TRANSLATE_VA0x812Translate VA to PA with CR3
HV_GET_CR30x813Get process CR3 from PID

What Can Be Accessed

  • ✓ Any user-mode process memory
  • ✓ Kernel memory (ntoskrnl, drivers)
  • ✓ Secure kernel (VSM/VBS) memory
  • ✓ UEFI runtime services memory
  • ✓ MMIO device memory

Memory Scanner Integration

The Memory Scanner tab uses physical memory access for scanning:

  • • CR3 walk to enumerate all valid VA ranges
  • • Physical reads for value scanning
  • • Physical writes for memory editing
  • • Support for large pages (2MB, 1GB)

Use Cases

  • • Memory forensics without kernel assistance
  • • Bypassing anti-cheat memory protection
  • • Kernel rootkit detection via physical comparison
  • • Secure kernel research
  • • UEFI runtime memory analysis