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>
This commit is contained in:
2026-06-11 23:15:15 +03:00
parent 3268fe11e1
commit ec27a8f4e5
10 changed files with 131 additions and 46 deletions
+33 -11
View File
@@ -15,8 +15,8 @@ const char SPOOF_DIG[] = "0123456789";
/* ---- config: machine property first, env var as a test fallback ----------- */
static char g_seed[256];
static bool g_ready, g_enabled;
static char g_hv[16], g_waet[16], g_vgid[16], g_pvp[16];
static bool g_ready;
static char g_mode[16], g_hv[16], g_waet[16], g_vgid[16], g_pvp[16];
static void read_prop(const char *prop, const char *env, char *out, size_t n)
{
@@ -37,17 +37,38 @@ static void config_load(void)
return;
}
read_prop("spoof-seed", "QEMU_SPOOF_SEED", g_seed, sizeof(g_seed));
read_prop("spoof-mode", "QEMU_SPOOF_MODE", g_mode, sizeof(g_mode));
read_prop("spoof-hv", "QEMU_SPOOF_HV", g_hv, sizeof(g_hv));
read_prop("spoof-waet", "QEMU_SPOOF_WAET", g_waet, sizeof(g_waet));
read_prop("spoof-vmgenid", "QEMU_SPOOF_VMGENID", g_vgid, sizeof(g_vgid));
read_prop("spoof-pvpanic", "QEMU_SPOOF_PVPANIC", g_pvp, sizeof(g_pvp));
g_enabled = g_seed[0] != '\0';
g_ready = true;
}
bool spoof_on(void) { config_load(); return g_enabled; }
bool spoof_on(void) { return spoof_mode() != SPOOF_MODE_NONE; }
bool spoof_enabled(void) { return spoof_on(); }
SpoofMode spoof_mode(void)
{
config_load();
if (!g_seed[0]) return SPOOF_MODE_NONE;
if (!strcmp(g_mode, "none")) return SPOOF_MODE_NONE;
if (!strcmp(g_mode, "hyperv")) return SPOOF_MODE_HYPERV;
if (!strcmp(g_mode, "vbs")) return SPOOF_MODE_VBS;
if (!strcmp(g_mode, "physical")) return SPOOF_MODE_PHYSICAL;
/* back-compat with the old spoof-hv knob (real-OEM persona either way) */
if (!strcmp(g_hv, "hidden")) return SPOOF_MODE_PHYSICAL;
if (!strcmp(g_hv, "hyperv")) return SPOOF_MODE_VBS;
if (!strcmp(g_hv, "off")) return SPOOF_MODE_NONE;
return SPOOF_MODE_VBS; /* seeded default = VBS (real-OEM + Hyper-V) */
}
bool spoof_persona_msvm(void) { return spoof_mode() == SPOOF_MODE_HYPERV; }
bool spoof_presence_hyperv(void)
{
SpoofMode m = spoof_mode();
return m == SPOOF_MODE_HYPERV || m == SPOOF_MODE_VBS;
}
/* ---- deterministic derivation: fnv1a(seed|key) -> splitmix64 -------------- */
static uint64_t fnv1a(const char *s)
{
@@ -94,25 +115,26 @@ int spoof_anchor_vendor(void)
/* ---- policy knobs --------------------------------------------------------- */
SpoofHvMode spoof_hv_mode(void)
{
config_load();
if (!strcmp(g_hv, "hidden")) return SPOOF_HV_HIDDEN;
if (!strcmp(g_hv, "hyperv")) return SPOOF_HV_HYPERV;
if (!strcmp(g_hv, "off")) return SPOOF_HV_OFF;
return g_enabled ? SPOOF_HV_HYPERV : SPOOF_HV_OFF; /* seeded default = hyperv */
switch (spoof_mode()) { /* derived from the mode preset */
case SPOOF_MODE_HYPERV:
case SPOOF_MODE_VBS: return SPOOF_HV_HYPERV; /* present Hyper-V */
case SPOOF_MODE_PHYSICAL: return SPOOF_HV_HIDDEN; /* bare metal */
default: return SPOOF_HV_OFF;
}
}
bool spoof_waet_drop(void)
{
config_load();
if (!strcmp(g_waet, "on")) return true;
if (!strcmp(g_waet, "off")) return false;
return g_enabled; /* seeded default = drop */
return spoof_on(); /* any spoof mode drops WAET */
}
bool spoof_pvpanic_hide(void)
{
config_load();
if (!strcmp(g_pvp, "on")) return true;
if (!strcmp(g_pvp, "off")) return false;
return g_enabled; /* seeded default = hide pvpanic */
return spoof_on(); /* QEMU pvpanic isn't a Hyper-V/real device */
}
SpoofVgidPolicy spoof_vmgenid_policy(void)
{
+14 -1
View File
@@ -16,7 +16,20 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
bool spoof_on(void); /* seed present */
bool spoof_on(void); /* a persona is active (seed set + mode != none) */
/* The master config fork. Two axes (persona x presence) as named presets:
* none stock persona + stock-kvm presence (no spoof)
* hyperv microsoft-vm persona + hyperv presence (honest Hyper-V child VM)
* vbs real-OEM persona + hyperv presence (mimic physical Win11 + VBS)
* physical real-OEM persona + bare-metal presence (VBS-off machine) */
typedef enum {
SPOOF_MODE_NONE = 0, SPOOF_MODE_HYPERV, SPOOF_MODE_VBS, SPOOF_MODE_PHYSICAL
} SpoofMode;
SpoofMode spoof_mode(void);
bool spoof_persona_msvm(void); /* hardware persona = Microsoft "Virtual Machine" */
bool spoof_presence_hyperv(void);/* present Hyper-V enlightenments (hyperv|vbs) */
uint64_t spoof_field(const char *key); /* stable 64-bit draw for a key */
uint64_t spoof_field_n(const char *key, unsigned i); /* nth independent draw */
const char *spoof_pick(const char *key, const char *const *arr, size_t n);
+6 -2
View File
@@ -17,11 +17,15 @@ static const char *const EDID_NAME[] = {
const char *spoof_edid_vendor(const char *def)
{
return spoof_on() ? SPOOF_PICK("edid.vend", EDID_VEND) : def;
if (!spoof_on()) return def;
if (spoof_persona_msvm()) return "MSF"; /* Microsoft synthetic display */
return SPOOF_PICK("edid.vend", EDID_VEND);
}
const char *spoof_edid_name(const char *def)
{
return spoof_on() ? SPOOF_PICK("edid.name", EDID_NAME) : def;
if (!spoof_on()) return def;
if (spoof_persona_msvm()) return "Hyper-V Monitor";
return SPOOF_PICK("edid.name", EDID_NAME);
}
uint16_t spoof_edid_model(uint16_t def)
{
+24 -7
View File
@@ -77,13 +77,15 @@ static const Board *chosen_board(void)
return &list[spoof_field("mach.board") % n];
}
const char *spoof_plat_acpi_oem(void) { return plat()->oem; }
const char *spoof_plat_acpi_table(void) { return plat()->table; }
const char *spoof_plat_bios_vendor(void) { return plat()->bios; }
const char *spoof_plat_baseboard(void) { return plat()->board; }
const char *spoof_plat_machine_desc(void) { return chosen_board()->model; }
const char *spoof_plat_socket(void) { return chosen_board()->socket; }
const char *spoof_plat_oem_string(void) { return plat()->oemstr; }
/* In hyperv mode the hardware persona is an honest Hyper-V "Virtual Machine"
* (real Hyper-V ACPI OEM = VRTUAL/MICROSFT, vendor = Microsoft Corporation). */
const char *spoof_plat_acpi_oem(void) { return spoof_persona_msvm() ? "VRTUAL" : plat()->oem; }
const char *spoof_plat_acpi_table(void) { return spoof_persona_msvm() ? "MICROSFT" : plat()->table; }
const char *spoof_plat_bios_vendor(void) { return spoof_persona_msvm() ? "Microsoft Corporation" : plat()->bios; }
const char *spoof_plat_baseboard(void) { return spoof_persona_msvm() ? "Microsoft Corporation" : plat()->board; }
const char *spoof_plat_machine_desc(void) { return spoof_persona_msvm() ? "Virtual Machine" : chosen_board()->model; }
const char *spoof_plat_socket(void) { return spoof_persona_msvm() ? "None" : chosen_board()->socket; }
const char *spoof_plat_oem_string(void) { return spoof_persona_msvm() ? "Hyper-V" : plat()->oemstr; }
const char *spoof_bios_vendor(const char *def)
{
@@ -96,6 +98,9 @@ const char *spoof_bios_version(const char *def)
if (!spoof_on()) {
return def;
}
if (spoof_persona_msvm()) {
return "Hyper-V UEFI Release v4.1";
}
static char v[32];
const char *b = spoof_plat_bios_vendor();
if (strstr(b, "Megatrends")) { /* AMI Aptio */
@@ -136,3 +141,15 @@ const char *spoof_baseboard_manufacturer(const char *def)
{
return spoof_on() ? spoof_plat_baseboard() : def;
}
/* SMBIOS type1 (system) — the most guest-visible identity (Win32_ComputerSystem).
* hyperv: Microsoft "Virtual Machine"; real-OEM: the board brand + model. */
const char *spoof_system_manufacturer(const char *def)
{
if (!spoof_on()) return def;
return spoof_persona_msvm() ? "Microsoft Corporation" : spoof_plat_baseboard();
}
const char *spoof_system_product(const char *def)
{
if (!spoof_on()) return def;
return spoof_persona_msvm() ? "Virtual Machine" : spoof_plat_machine_desc();
}
+4 -2
View File
@@ -124,7 +124,7 @@ static void v_init(void)
v.done = true;
}
const char *spoof_disk_model(const char *def) { if (!spoof_on()) return def; d_init(); return d.model; }
const char *spoof_disk_model(const char *def) { if (!spoof_on()) return def; if (spoof_persona_msvm()) return "Virtual HD ATA Device"; d_init(); return d.model; }
const char *spoof_disk_serial(const char *def) { if (!spoof_on()) return def; d_init(); return d.serial; }
const char *spoof_disk_fw(const char *def) { if (!spoof_on()) return def; d_init(); return d.fw; }
uint64_t spoof_disk_wwn(uint64_t def) { if (!spoof_on()) return def; d_init(); return d.wwn; }
@@ -155,7 +155,9 @@ void spoof_nvme_nguid(uint8_t out[16])
}
const char *spoof_cdrom_model(const char *def)
{
return spoof_on() ? SPOOF_PICK("cdrom.model", CDROM_MODEL) : def;
if (!spoof_on()) return def;
if (spoof_persona_msvm()) return "Msft Virtual DVD-ROM";
return SPOOF_PICK("cdrom.model", CDROM_MODEL);
}
/* ATA rotation rate: 1 = non-rotational (SSD), else RPM — matched to the model
* so an "SSD 870 EVO" reports SSD and an "ST1000DM" reports a spinning rate. */
+2
View File
@@ -38,6 +38,8 @@ bool spoof_pvpanic_hide(void); /* drop the pvpanic device (_HID QEMU000
const char *spoof_bios_vendor(const char *def); /* SMBIOS type0 */
const char *spoof_bios_version(const char *def); /* SMBIOS type0 (vendor-format) */
const char *spoof_bios_date(const char *def); /* SMBIOS type0 (MM/DD/YYYY) */
const char *spoof_system_manufacturer(const char *def); /* SMBIOS type1 */
const char *spoof_system_product(const char *def); /* SMBIOS type1 */
const char *spoof_baseboard_manufacturer(const char *def); /* SMBIOS type2 */
/* ---- ACPI (spoof-acpi.c; hw/acpi, hw/i386/acpi-build) --------------------- */