Securityvirtualizationkvmqemumalware-analysislinux
vfio-native Patches Linux KVM and QEMU Until VMAware's 85 VM-Detection Checks Call a Virtual Machine Bare Metal
A developer who goes by sandwich fixed three places where KVM breaks the AMD64 spec and scrubbed QEMU's emulator fingerprints, taking a Windows guest from 10 VMAware detections to 1.

Plenty of software checks whether it’s running in a hypervisor and quietly changes what it does. “Malware samples self-disable or take a benign branch. Commercial software takes a licensing branch,” the project’s README says. Drivers and firmware pick another code path too, and then “you end up measuring the sandbox instead of the subject.”
The tells come from two places. The first is KVM itself, which “diverges from the AMD64 architecture in ways a guest can read directly”: the wrong exception vector for an SVM instruction, a #GP where the spec calls for #UD, and “a hypercall at CPL>0 that raises no exception at all.” The kernel already knew about one of them. “KVM already carries a FIXME describing exactly this,” sandwich writes in the longer guide. The KVM patches pass checkpatch.pl --strict, ship with a cover letter and a selftest, and are “written to be acceptable upstream.”
The second is QEMU’s fake motherboard, which the README says matches no board “that was ever manufactured.” It lists “ACPI link-device names no real firmware uses, PCI vendor and subsystem IDs that belong to the emulator rather than to a device, firmware table fields no shipping board sets.” Ten patchsets against QEMU 11.1.2 rename all of it. One vm-native-setup command then rewrites the libvirt domain: it pins each virtual CPU onto a real SMT pair, moves the disks to emulated NVMe, writes the SMBIOS and ACPI identity, and backs up the old config first.
Getting the disguise wrong fails silently. Give two ACPI devices the same _UID and “the guest powers itself off after ~70 seconds having read nothing from disk,” the guide warns. “No error, no log line.”
The last surviving check is GPU_CAPABILITIES, which wants a display that reports a gamma ramp. “Not a GPU enumeration despite the name - it is one GetDeviceCaps call,” the README says, and passing a real graphics card through clears it. A timing check called TIMER falls only to an experimental patch that stops KVM from intercepting CPUID, and sandwich is blunt about that one: “It is not upstream material and never will be.” The guide also corrects itself on the record. An earlier version called TIMER unfixable, until sandwich found the probe was using RaiseException where VMAware uses ZwRaiseException. Whether the three spec fixes ever land in mainline KVM is still open; the guide says they were written for it, not that they’ve been sent.
Anti-VM checks have always been a list of cheap tells, and lists like that tend to shrink once someone fixes the tells at the source. A patch that makes KVM match the AMD64 manual is hard to argue against upstream, because it’s just a bug fix. If those land, every KVM guest gets a little harder to fingerprint for free, and detection libraries go looking for the next thing, which by this README’s own scoreboard is the graphics card.
The fine print matters, too. The README’s own condition reads “Run this only on hardware you control and with software you are licensed to run,” and the full level needs the DKMS module bumped on every kernel release, or the stock modules load and “the guest boots fine and scores worse.”