spoof: SMBIOS type0 BIOS vendor/version/date

Force a real, platform-anchored OEM BIOS identity into SMBIOS type0 (patch 0024 +
spoof_bios_version/spoof_bios_date getters) so the guest does not read an empty or
firmware-default BIOS vendor via WMI/dmidecode. Vendor coheres with the board;
version uses the vendor real format. Inert without a seed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 22:14:12 +03:00
parent 06463ee65c
commit 9b17bdfa33
4 changed files with 71 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
qemu-spoof: SMBIOS type0 BIOS vendor / version / date
Stock QEMU leaves type0 vendor/version/date unset, so the guest reads an empty or
firmware-default ("SeaBIOS") BIOS identity via WMI Win32_BIOS / dmidecode -- a tell.
Force a real, platform-anchored OEM BIOS identity (vendor coheres with the board;
version uses the vendor's real format) through smbios_set_defaults, so an explicit
-smbios type=0 still wins and an un-seeded VM stays stock. (spoof.h include added by
0015-smbios-vm-bit.)
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 7d71418..13ffa93 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -1027,6 +1027,12 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
{
smbios_have_defaults = true;
+ /* qemu-spoof: a real OEM BIOS identity (type0). Stock leaves vendor/version/date
+ * unset, so the guest reads an empty / firmware-default ("SeaBIOS") BIOS — a tell.
+ * Platform-anchored so the BIOS vendor coheres with the board. Inert without a seed. */
+ SMBIOS_SET_DEFAULT(smbios_type0.vendor, spoof_bios_vendor(NULL));
+ SMBIOS_SET_DEFAULT(smbios_type0.version, spoof_bios_version(NULL));
+ SMBIOS_SET_DEFAULT(smbios_type0.date, spoof_bios_date(NULL));
SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(smbios_type1.product, product);
SMBIOS_SET_DEFAULT(smbios_type1.version, version);
+1
View File
@@ -25,6 +25,7 @@ match exactly. Naming: `0002` = infra, `0010+` = one aspect each.
| 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 (platform-anchored OEM firmware) |
## Why 0018 is subsystem-only (the PCI-id problem)
+43
View File
@@ -89,6 +89,49 @@ const char *spoof_bios_vendor(const char *def)
{
return spoof_on() ? spoof_plat_bios_vendor() : def;
}
/* BIOS version in the format the platform's firmware vendor actually uses, so it
* coheres with the type0 vendor (AMI "x.yy", Dell "1.x.y", HP "S0x Ver…", etc). */
const char *spoof_bios_version(const char *def)
{
if (!spoof_on()) {
return def;
}
static char v[32];
const char *b = spoof_plat_bios_vendor();
if (strstr(b, "Megatrends")) { /* AMI Aptio */
snprintf(v, sizeof(v), "%u.%02u",
1 + (unsigned)(spoof_field("bios.ami.a") % 3),
(unsigned)(spoof_field("bios.ami.b") % 80));
} else if (strstr(b, "Dell")) {
snprintf(v, sizeof(v), "1.%u.%u",
(unsigned)(spoof_field("bios.dell.a") % 25),
(unsigned)(spoof_field("bios.dell.b") % 10));
} else if (strstr(b, "HP")) {
snprintf(v, sizeof(v), "S0%u Ver. 02.%02u.00",
1 + (unsigned)(spoof_field("bios.hp.a") % 9),
(unsigned)(spoof_field("bios.hp.b") % 30));
} else if (strstr(b, "LENOVO")) {
snprintf(v, sizeof(v), "M1%cKT%uA",
(char)('A' + spoof_field("bios.len.a") % 26),
(unsigned)(spoof_field("bios.len.b") % 90));
} else { /* Insyde (Acer) */
snprintf(v, sizeof(v), "V1.%02u", (unsigned)(spoof_field("bios.ins") % 40));
}
return v;
}
/* Plausible BIOS release date (SMBIOS encodes it as MM/DD/YYYY). */
const char *spoof_bios_date(const char *def)
{
if (!spoof_on()) {
return def;
}
static char d[12];
snprintf(d, sizeof(d), "%02u/%02u/%04u",
1 + (unsigned)(spoof_field("bios.mon") % 12),
1 + (unsigned)(spoof_field("bios.day") % 28),
2020 + (unsigned)(spoof_field("bios.year") % 4));
return d;
}
const char *spoof_baseboard_manufacturer(const char *def)
{
return spoof_on() ? spoof_plat_baseboard() : def;
+2
View File
@@ -36,6 +36,8 @@ bool spoof_pvpanic_hide(void); /* drop the pvpanic device (_HID QEMU000
* The ACPI OEM id, machine desc, BIOS vendor and baseboard all come from a single
* per-seed platform pick (OEM-prebuilt vendor code, or "ALASKA"/AMI for DIY). */
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_baseboard_manufacturer(const char *def); /* SMBIOS type2 */
/* ---- ACPI (spoof-acpi.c; hw/acpi, hw/i386/acpi-build) --------------------- */