Physical Memory Operations
Read and write arbitrary physical memory from within SMM. Because SMM runs below the hypervisor and the kernel, this bypasses EPT hooks, PatchGuard, and any usermode/kernel memory protection.
Physical Memory Is Not a Toy
Writing to the wrong physical page can corrupt kernel state, page tables, firmware variables, or MMIO registers. Always verify the target address, and prefer read-only operations for research.
Read Physical Memory
Copies size bytes from physical address src into the SMM communication buffer. The kernel driver then copies the result back to usermode.
use smm::{read_physical, SmmError};
let bytes: Vec<u8> = read_physical(0x1000, 4096)?;
println!("{:02X?}", &bytes[..16]);Write Physical Memory
use smm::write_physical;
let patch: [u8; 8] = [0x90; 8]; // 8 NOPs
write_physical(0xFFFFF80012340000, &patch)?;Translate Virtual → Physical
SMM walks the target process's CR3 page tables to translate a virtual address into its physical page. Combines with read_physical/write_physical to reach usermode memory that the OS would otherwise mediate.
use smm::{translate_virtual, read_physical};
let phys = translate_virtual(target_pid, 0x7FF612340000)?;
let bytes = read_physical(phys, 256)?;CR3 Page Table Walk
The SMM handler walks the standard 4-level x86-64 paging hierarchy — PML4 → PDPT → PD → PT — reading each level directly from physical memory.
// efi/DioProcessSmm/Memory.c (simplified)
UINT64 TranslateVa(UINT64 Cr3, UINT64 Va) {
UINT64 Pml4e = ReadPhys(Cr3 + ((Va >> 39) & 0x1FF) * 8);
if (!(Pml4e & 1)) return 0;
UINT64 Pdpte = ReadPhys((Pml4e & PA_MASK) + ((Va >> 30) & 0x1FF) * 8);
if (!(Pdpte & 1)) return 0;
if (Pdpte & PS_BIT) return (Pdpte & PA_MASK) + (Va & 0x3FFFFFFF); // 1GB
UINT64 Pde = ReadPhys((Pdpte & PA_MASK) + ((Va >> 21) & 0x1FF) * 8);
if (!(Pde & 1)) return 0;
if (Pde & PS_BIT) return (Pde & PA_MASK) + (Va & 0x1FFFFF); // 2MB
UINT64 Pte = ReadPhys((Pde & PA_MASK) + ((Va >> 12) & 0x1FF) * 8);
if (!(Pte & 1)) return 0;
return (Pte & PA_MASK) + (Va & 0xFFF); // 4KB
}Why Not Just Use the Hypervisor?
- • Deeper isolation — SMRAM is chipset- locked and invisible to both Ring 0 and Ring -1 EPT tables
- • Survives HV takedown — even if a security product unloads the DioProcess hypervisor, the SMM handler remains resident
- • Firmware-persistent — SMM code is loaded from platform firmware, not a driver — it activates before Windows even boots
Limitations
- • SMI latency is measurable (µs–ms) — not suitable for high-frequency polling
- • All CPU cores stall while SMM executes — long handlers cause visible system pauses
- • Communication buffer is bounded (4 KB per request) — large reads require chunking
- • SMM cannot call OS functions — everything must be self-contained
Implementation
| Item | Location |
|---|---|
| SMM memory ops | efi/DioProcessSmm/Memory.c |
| Command dispatcher | efi/DioProcessSmm/Commands.c |
| Rust bindings | crates/smm/src/driver.rs |