# qemu-spoof Seed-driven, **per-VM** hardware-identity anti-detection for QEMU / Proxmox VE — a drop-in `pve-qemu-kvm` build. Each VM derives a *coherent, unique* hardware persona from a per-VM seed, so a fleet of VMs does not share one fingerprint, and with **no seed it falls back to stock QEMU** (zero behaviour change). ## Why seed-driven (not a static fork) A hard-coded anti-detect fork gives every VM the *same* firmware/bus identity (same ACPI OEM, same fw_cfg signature, same PCI IDs, same monitor) — which is itself a **fleet fingerprint**: many VMs with identical "hardware" correlate trivially. qemu-spoof instead derives a **coherent persona from a per-VM seed**, so each VM looks like a different real machine while staying internally consistent (CPU vendor ↔ chipset ↔ ACPI OEM ↔ board ↔ socket all cohere). ## How it works A small in-tree module (`hw/misc/spoof.c`, source kept in `src/`) holds pools of real identities and a pure derivation `seed -> splitmix64 -> pool pick`. Every anti-detect call site is patched from a hard-coded literal to a getter: ```c - memcpy(signature, "KVMKVMKVM\0\0\0", 12); + memcpy(signature, spoof_kvm_signature("KVMKVMKVM\0\0\0"), 12); ``` The getter returns the seed-derived value, or the **stock default** when no seed is set — so the patch is inert until a VM opts in. ### Seed input ``` -machine ,...,spoof-seed= # preferred (Proxmox: via args) QEMU_SPOOF_SEED= # env fallback (testing) ``` Same seed → same persona. Mix in a host secret so personas are not guessable from the vmid. Proxmox: add `spoof-seed=` through the VM `args:` line. ### Modes `-machine ...,spoof-mode=` selects the identity strategy (two axes — hardware persona × hypervisor presence — as presets): | mode | persona | presence | looks like | |---|---|---|---| | `none` | stock | KVM | a plain VM (no spoof) | | `hyperv` | Microsoft "Virtual Machine" | Hyper-V | an honest Hyper-V guest | | `vbs` (default when seeded) | real OEM | Hyper-V | a physical Win11 box with VBS on | | `physical` | real OEM | bare metal | a physical machine (no hypervisor) | The presence axis (clearing the hypervisor bit / Hyper-V enlightenments) is partly the CPU model configuration (`cpu: host,hidden=1` + `hv-*`); set it to match the mode. ## Layout ``` pve-qemu/ git submodule -> https://git.proxmox.com/git/pve-qemu.git (pinned) src/spoof*.{c,h} the seed-driven identity module (decomposed by aspect) patches/ quilt patches injected into pve-qemu/debian/patches/series: 0002 register the spoof-seed machine property 0010+ wire each anti-detect call site to a getter Makefile prepare -> build the .deb ``` ## Build ```sh git submodule update --init --recursive # pve-qemu + its qemu submodule make prepare # inject spoof module + patches + changelog make deb # dpkg-buildpackage -> pve-qemu/*.deb ``` Builds on Debian trixie (matches pve-qemu 11.0). Use a clean builder / WSL, never a production node. `make deb` produces `pve-qemu-kvm_*_amd64.deb` (+ `-dbgsym`). ## Packaging & delivery Install the built `.deb` on a Proxmox VE node in place of the stock package, or serve it from any apt repository (e.g. a Debian package registry). ### Surviving Proxmox updates (epoch + per-commit revision) The Makefile stamps an **epoch** — `1:+qemu-spoofN`, where `N` is the commit count — so the package permanently outranks stock `pve-qemu-kvm` (no epoch). An `apt upgrade` from the Proxmox repo therefore never reverts the spoof; you are the source of truth for this package on your nodes. Pull upstream QEMU fixes deliberately by rebuilding on a newer `pve-qemu` (the epoch carries forward). Optional belt-and-suspenders apt pin on each node: ``` Package: pve-qemu-kvm Pin: origin Pin-Priority: 1001 ``` ## Companion config (machine options, not code) A few tells are configuration, not code — set them when provisioning a spoofed VM (alongside the `spoof-seed`): - `-machine ...,vmport=off` — disable the VMware backdoor port (0x5658) - prefer real-id emulated devices over virtio where stealth matters: `e1000e` NIC, SATA/AHCI disk (their PCI vendor:device are real Intel; virtio's `1af4` is a tell and its id cannot be spoofed without breaking the guest driver) - GPU: vfio passthrough with `x-pci-vendor-id/...` overrides - CPU: `host,hidden=1` (+ hv enlightenments for Windows) to back the `spoof-hv` policy ## License Patches and module are derivative of QEMU and licensed under **GPL v2** (the QEMU license). See the COPYING file in the QEMU tree.