Snapchange - Snapshot-Based Fuzzing with KVM Cheatsheet
Snapchange (by AWS) is a Rust framework for snapshot-based fuzzing. Traditional fuzzers restart the target for each input, which is fatally slow when the interesting code sits behind expensive setup — a network handshake, a login, a parsed config, a loaded database. Snapchange instead takes a memory snapshot of the target at exactly the moment of interest, then restores that state and mutates from there using KVM, achieving very high iteration rates against code that conventional fuzzing struggles to reach at all.
Snapshot fuzzing requires KVM and root. Run in an isolated environment.
Requirements
| Requirement | Note |
|---|
| Linux with KVM | /dev/kvm accessible |
| Rust toolchain | Snapchange is a Rust library |
| QEMU | Used to take the snapshot |
| Root | For KVM and memory access |
The Model
| Phase | What happens |
|---|
| 1. Snapshot | Run the target in QEMU to the point of interest, dump memory + registers |
| 2. Harness | Write a Rust fuzzer describing where input goes and when to stop |
| 3. Fuzz | Snapchange restores the snapshot per iteration and mutates the input |
| 4. Triage | Crashes are recorded with the exact register/memory state |
The critical insight: all the setup cost is paid once, in the snapshot. Every subsequent iteration starts from that state in microseconds.
Taking a Snapshot
# Conceptual: run the target under QEMU, break at the function of interest,
# then dump physical memory and register state
./snapchange/qemu_snapshot/take_snapshot.sh --target ./my-server
| Artifact | Contains |
|---|
fuzzvm.physmem | Full guest physical memory |
fuzzvm.qemuregs | CPU register state |
*.symbols | Symbol table for coverage/breakpoints |
vmlinux / binary | For symbolization |
Writing a Fuzzer
// Conceptual shape — see Snapchange examples for complete code
impl Fuzzer for MyFuzzer {
type Input = Vec<u8>;
const START_ADDRESS: u64 = 0x555555555000;
const MAX_INPUT_LENGTH: usize = 1024;
fn set_input(&mut self, input: &Self::Input, fuzzvm: &mut FuzzVm<Self>) -> Result<()> {
// Write the mutated input into guest memory where the target reads it
fuzzvm.write_bytes_dirty(VirtAddr(BUFFER_ADDR), CR3, input)?;
Ok(())
}
fn reset_breakpoints(&self) -> Option<&[AddressLookup]> { /* stop conditions */ }
fn crash_breakpoints(&self) -> Option<&[AddressLookup]> { /* crash sites */ }
}
| Element | Purpose |
|---|
START_ADDRESS | Where execution resumes each iteration |
set_input | Inject the fuzz input into guest memory |
reset_breakpoints | Where an iteration ends normally |
crash_breakpoints | Addresses that indicate a crash (e.g. panic, abort) |
Running
| Command | Description |
|---|
cargo run -r -- fuzz -c 8 | Fuzz with 8 cores |
cargo run -r -- project translate | Symbolize/inspect the snapshot |
cargo run -r -- coverage | Generate coverage from the corpus |
cargo run -r -- trace <input> | Single-step trace an input |
cargo run -r -- minimize <input> | Shrink a crashing input |
Why Snapshot Fuzzing Wins Here
| Target characteristic | Conventional fuzzing | Snapchange |
|---|
| Expensive startup | Pays it every iteration | Pays it once |
| Requires auth/handshake | Hard to reach | Snapshot past it |
| Stateful protocol | Difficult | Snapshot mid-session |
| Kernel/hypervisor code | Very hard | Natural fit |
Coverage & Triage
| Capability | Note |
|---|
| Breakpoint coverage | Coverage via breakpoints on basic blocks |
| Crash dedup | Grouped by faulting address/state |
| Single-step traces | Full instruction trace for a given input |
| Memory inspection | Read guest memory at crash time |
Snapchange vs Other Fuzzers
| Aspect | Snapchange | AFL++ | LibAFL (Nyx) | syzkaller |
|---|
| Execution | KVM snapshot restore | Process fork | Snapshot (Nyx) | VM + syscalls |
| Setup cost | Paid once | Every iteration | Once | Per VM |
| Target | Anything in a VM snapshot | Userspace binaries | Configurable | OS kernels |
| Effort | High (write a Rust fuzzer) | Low | High | Medium |
Compare with LibAFL (which also offers snapshot backends) and syzkaller for kernel syscall fuzzing.
Resources