ec27a8f4e5
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>
86 lines
4.4 KiB
Diff
86 lines
4.4 KiB
Diff
qemu-spoof: register per-VM anti-detect machine properties
|
|
|
|
Adds string machine properties spoof-seed / spoof-mode / spoof-hv / spoof-waet /
|
|
spoof-vmgenid / spoof-pvpanic on the x86 machine, backed by X86MachineState fields.
|
|
The qemu-spoof module (hw/misc/spoof*) reads them via
|
|
object_property_get_str(current_machine, "spoof-*"). spoof-mode (none|hyperv|vbs|
|
|
physical) is the master fork; spoof-hv is the legacy knob. Inert unless set.
|
|
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
|
|
index 01872cb..702b327 100644
|
|
--- a/hw/i386/x86.c
|
|
+++ b/hw/i386/x86.c
|
|
@@ -372,6 +372,27 @@ static void x86_machine_initfn(Object *obj)
|
|
x86ms->above_4g_mem_start = 4 * GiB;
|
|
}
|
|
|
|
+/* qemu-spoof: plain string machine properties, read back by the spoof module via
|
|
+ * object_property_get_str(current_machine, "spoof-*"). */
|
|
+#define X86_SPOOF_PROP(field) \
|
|
+ static char *x86_machine_get_##field(Object *obj, Error **errp) \
|
|
+ { \
|
|
+ return g_strdup(X86_MACHINE(obj)->field); \
|
|
+ } \
|
|
+ static void x86_machine_set_##field(Object *obj, const char *value, \
|
|
+ Error **errp) \
|
|
+ { \
|
|
+ X86MachineState *x86ms = X86_MACHINE(obj); \
|
|
+ g_free(x86ms->field); \
|
|
+ x86ms->field = g_strdup(value); \
|
|
+ }
|
|
+X86_SPOOF_PROP(spoof_seed)
|
|
+X86_SPOOF_PROP(spoof_mode)
|
|
+X86_SPOOF_PROP(spoof_hv)
|
|
+X86_SPOOF_PROP(spoof_waet)
|
|
+X86_SPOOF_PROP(spoof_vmgenid)
|
|
+X86_SPOOF_PROP(spoof_pvpanic)
|
|
+
|
|
static void x86_machine_class_init(ObjectClass *oc, const void *data)
|
|
{
|
|
MachineClass *mc = MACHINE_CLASS(oc);
|
|
@@ -426,6 +447,31 @@ static void x86_machine_class_init(ObjectClass *oc, const void *data)
|
|
"in ACPI table header."
|
|
"The string may be up to 8 bytes in size");
|
|
|
|
+ object_class_property_add_str(oc, "spoof-seed",
|
|
+ x86_machine_get_spoof_seed, x86_machine_set_spoof_seed);
|
|
+ object_class_property_set_description(oc, "spoof-seed",
|
|
+ "qemu-spoof: per-VM persona seed (empty = stock QEMU)");
|
|
+ object_class_property_add_str(oc, "spoof-mode",
|
|
+ x86_machine_get_spoof_mode, x86_machine_set_spoof_mode);
|
|
+ object_class_property_set_description(oc, "spoof-mode",
|
|
+ "qemu-spoof: identity mode (none|hyperv|vbs|physical)");
|
|
+ object_class_property_add_str(oc, "spoof-hv",
|
|
+ x86_machine_get_spoof_hv, x86_machine_set_spoof_hv);
|
|
+ object_class_property_set_description(oc, "spoof-hv",
|
|
+ "qemu-spoof: legacy hv knob (off|hyperv|hidden); prefer spoof-mode");
|
|
+ object_class_property_add_str(oc, "spoof-waet",
|
|
+ x86_machine_get_spoof_waet, x86_machine_set_spoof_waet);
|
|
+ object_class_property_set_description(oc, "spoof-waet",
|
|
+ "qemu-spoof: drop the WAET ACPI table (on|off)");
|
|
+ object_class_property_add_str(oc, "spoof-vmgenid",
|
|
+ x86_machine_get_spoof_vmgenid, x86_machine_set_spoof_vmgenid);
|
|
+ object_class_property_set_description(oc, "spoof-vmgenid",
|
|
+ "qemu-spoof: vmgenid policy (keep|mask|hide)");
|
|
+ object_class_property_add_str(oc, "spoof-pvpanic",
|
|
+ x86_machine_get_spoof_pvpanic, x86_machine_set_spoof_pvpanic);
|
|
+ object_class_property_set_description(oc, "spoof-pvpanic",
|
|
+ "qemu-spoof: drop the pvpanic device (on|off)");
|
|
+
|
|
object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t",
|
|
x86_machine_get_bus_lock_ratelimit,
|
|
x86_machine_set_bus_lock_ratelimit, NULL, NULL);
|
|
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
|
|
index 71fe6b5..c1f5f7e 100644
|
|
--- a/include/hw/i386/x86.h
|
|
+++ b/include/hw/i386/x86.h
|
|
@@ -79,6 +79,9 @@ struct X86MachineState {
|
|
|
|
char *oem_id;
|
|
char *oem_table_id;
|
|
+
|
|
+ /* qemu-spoof: per-VM anti-detect config, read by hw/misc/spoof*.c */
|
|
+ char *spoof_seed, *spoof_mode, *spoof_hv, *spoof_waet, *spoof_vmgenid, *spoof_pvpanic;
|
|
/*
|
|
* Address space used by IOAPIC device. All IOAPIC interrupts
|
|
* will be translated to MSI messages in the address space.
|