Files
qemu-spoof/patches/README.md
T
lirent ec27a8f4e5 spoof: spoof-mode master fork (none/hyperv/vbs/physical) + microsoft-vm persona
Phase 0. Replace the spoof-hv knob with spoof-mode, a first-class selector modeled as
two axes (persona x presence) exposed as 4 presets:
- none: stock (spoof_on now requires mode != none, killing half-spoof states)
- hyperv: Microsoft Virtual Machine persona + Hyper-V presence (honest child VM)
- vbs (seeded default): real-OEM persona + Hyper-V presence (mimic physical Win11+VBS)
- physical: real-OEM persona + bare metal

Engine: spoof_mode()/spoof_persona_msvm()/spoof_presence_hyperv() in spoof-core; the
hv/waet/pvpanic/vmgenid policies now derive from the mode. microsoft-vm persona wired
across platform (ACPI OEM VRTUAL/MICROSFT, Microsoft Corporation), system type1
(Virtual Machine), storage (Virtual HD / Msft Virtual DVD-ROM) and EDID (MSF/Hyper-V).
New getters spoof_system_manufacturer/product (type1, real-OEM or Hyper-V). Patches:
0002 registers spoof-mode; 0024 now also forces type1 system identity. spoof-hv kept
as a back-compat alias. Inert without a seed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 23:15:15 +03:00

3.4 KiB

Anti-detect patch series

Quilt patches injected (by make prepare) into pve-qemu/debian/patches/series, applied in order during the .deb build. Each wires a stock QEMU literal to a spoof_*() getter from the in-tree module (hw/misc/spoof.{c,h}, dropped in by the Makefile). The getter returns the seed-derived value, or the stock default when no spoof-seed is set — so the whole series is inert until a VM opts in.

Authored against the pinned pve-qemu/qemu tree (QEMU 11.0) so the context lines match exactly. Naming: 0002 = infra, 0010+ = one aspect each.

patch covers
0002-x86-machine-spoof-properties register spoof-seed / spoof-mode / spoof-hv / spoof-waet / spoof-vmgenid / spoof-pvpanic machine props
0010-acpi-table-header ACPI OEM id / table id / creator + FADT hypervisor-vendor
0011-acpi-policy-waet-vmgenid drop the WAET table; skip the vmgenid SSDT when policy = hide
0012-acpi-device-hids vmgenid _HID (mask), pvpanic _HID (hide), fw_cfg _HID
0013-cpuid-kvm-sig-freq CPUID KVM signature + leaf 0x16 frequency
0014-fwcfg-signatures fw_cfg selector + DMA signatures
0015-smbios-vm-bit clear the SMBIOS type0 "VM" characteristic bit
0016-edid-monitor EDID vendor / name / model / serial / manufacture-date
0017-storage-identity IDE model / serial / fw / cdrom + NVMe model / serial / fw
0018-pci-subsystem-id realize-time OEM-brand of PCI subsystem ids + class-bound nvme vendor:device
0019-machine-desc machine desc string → platform board model
0021-smbios-identity SMBIOS type3 chassis / type4 socket + cpu-mfr / type11 OEM / type17 memory
0022-storage-extra IDE WWN + rotation rate; NVMe EUI-64 + NGUID
0023-cpu-microcode CPU microcode revision (IA32_UCODE_REV), vendor-positioned
0024-smbios-bios-type0 SMBIOS type0 BIOS vendor/version/date + type1 system manufacturer/product (real-OEM or Hyper-V persona)

The PCI-id problem (why 0018 is careful)

The PCI vendor:device id IS the guest driver-binding contract: NetKVM binds 1af4:1000, the ivshmem driver binds 1af4:1110, the GPU driver binds its id. Spoofing those breaks the device (no driver matches). So 0018 rewrites the subsystem id of all emulated devices (not used for binding; skips 0x1af4 because legacy-virtio encodes the device type there), and overrides the full vendor:device ONLY for class-bound controllers that bind by class code rather than id — currently qemu-nvme → a real NVMe vendor:device matched to the spoofed model brand. virtio / ivshmem / GPU ids are NOT touched (their id is load-bearing); they are de-fingerprinted by device choice (e1000e / SATA) and vfio x-pci-*.

Out of scope (handled by config or upstream, not these patches)

  • xHCI vendor:device: also class-bound; prefer the nec-usb-xhci device (real NEC id) via config over spoofing qemu-xhci. (qemu-nvme is handled by 0018.)
  • HDA codec id (QEMU_HDA_ID_VENDOR 0x1af4): a compile-time constant baked into a static const codec descriptor; spoofing needs a runtime override of the GET_PARAMETER verb response.
  • vmport/vmmouse (VMware backdoor port 0x5658): disable via -machine vmport=off (a machine option).
  • hv-mode / hypervisor bit: via the CPU model flags (cpu: host,hidden=1 + hv enlightenments). The module's spoof_hv_mode policy is the intent; enforcement is configuration.