Files
qemu-spoof/src/spoof-platform.c
T
lirent 9b17bdfa33 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>
2026-06-11 22:14:12 +03:00

139 lines
7.5 KiB
C

/*
* spoof-platform.c — the PLATFORM anchor: one seed draw selects a coherent
* machine identity (ACPI OEM id, ACPI table id, BIOS vendor, baseboard, the
* board model AND its socket). The board list is split by CPU vendor and indexed
* by the CPU anchor, so the board's chipset/socket always matches the CPU
* (no "Intel H510 board + AMD CPU"). The board's own socket feeds SMBIOS type4.
*
* Two classes: OEM prebuilt (ACPI OEM = vendor code) and DIY/retail (AMI Aptio
* firmware -> ACPI OEM "ALASKA"/"A M I"; the board brand is in the baseboard).
*/
#include "qemu/osdep.h"
#include "hw/misc/spoof.h"
#include "hw/misc/spoof-core.h"
typedef struct { const char *model, *socket; } Board;
/* --- OEM prebuilt: real Intel and (separate) AMD desktop SKUs --- */
static const Board DELL_I[] = { {"OptiPlex 7090","LGA1200"}, {"OptiPlex 5090","LGA1200"},
{"Precision 3650 Tower","LGA1200"}, {"OptiPlex 7000","LGA1700"} };
static const Board DELL_A[] = { {"OptiPlex 5055","AM4"}, {"OptiPlex 7010 AMD","AM4"} };
static const Board HP_I[] = { {"HP EliteDesk 800 G6","LGA1200"}, {"HP ProDesk 600 G6","LGA1200"},
{"HP Z2 Tower G5","LGA1200"}, {"HP EliteDesk 800 G9","LGA1700"} };
static const Board HP_A[] = { {"HP ProDesk 405 G6","AM4"}, {"HP ProDesk 485 G4","AM4"} };
static const Board LEN_I[] = { {"ThinkCentre M720q","LGA1151"}, {"ThinkCentre M920t","LGA1151"},
{"ThinkStation P340","LGA1200"}, {"ThinkCentre M70q Gen 3","LGA1700"} };
static const Board LEN_A[] = { {"ThinkCentre M75q Gen 2","AM4"}, {"ThinkCentre M75s Gen 2","AM4"} };
static const Board ACE_I[] = { {"Veriton M4660G","LGA1151"}, {"Aspire TC-895","LGA1200"},
{"Aspire TC-1760","LGA1700"} };
static const Board ACE_A[] = { {"Nitro N50-110","AM4"}, {"Aspire TC-380","AM4"} };
/* --- DIY/retail boards: the model unambiguously implies the socket --- */
static const Board ASUS_I[] = { {"ROG STRIX Z590-E GAMING WIFI","LGA1200"}, {"PRIME B560M-A","LGA1200"},
{"TUF GAMING Z690-PLUS WIFI","LGA1700"}, {"PRIME H610M-E D4","LGA1700"} };
static const Board ASUS_A[] = { {"TUF GAMING B550M-PLUS","AM4"}, {"ROG STRIX X570-E GAMING","AM4"},
{"PRIME B650M-A","AM5"}, {"ProArt X670E-CREATOR WIFI","AM5"} };
static const Board GBT_I[] = { {"Z390 AORUS PRO","LGA1151"}, {"B660M DS3H DDR4","LGA1700"},
{"Z690 AORUS ELITE AX","LGA1700"} };
static const Board GBT_A[] = { {"X570 AORUS ELITE","AM4"}, {"B450 AORUS M","AM4"}, {"B650 AORUS ELITE AX","AM5"} };
static const Board MSI_I[] = { {"MAG B560 TOMAHAWK","LGA1200"}, {"PRO B660M-A DDR4","LGA1700"},
{"MPG Z690 CARBON WIFI","LGA1700"} };
static const Board MSI_A[] = { {"MPG B550 GAMING PLUS","AM4"}, {"B450 TOMAHAWK MAX","AM4"},
{"MAG B650 TOMAHAWK WIFI","AM5"} };
static const Board ASR_I[] = { {"H510M-HVS","LGA1200"}, {"B660M Pro RS","LGA1700"},
{"Z690 Steel Legend","LGA1700"} };
static const Board ASR_A[] = { {"X570 Taichi","AM4"}, {"B450M Steel Legend","AM4"}, {"B650M PG Riptide","AM5"} };
typedef struct {
const char *oem, *table, *bios, *board, *oemstr;
const Board *intel; size_t ni;
const Board *amd; size_t na;
} Platform;
#define BL(a) (a), ARRAY_SIZE(a)
static const Platform PLAT[] = {
/* --- OEM prebuilt: ACPI OEM id = vendor code --- */
{ "DELL ", "QA09 ", "Dell Inc.", "Dell Inc.", "Dell System", BL(DELL_I), BL(DELL_A) },
{ "HPQOEM", "8054 ", "HP", "HP", "HP", BL(HP_I), BL(HP_A) },
{ "LENOVO", "TP-N1Q ", "LENOVO", "LENOVO", "LENOVO", BL(LEN_I), BL(LEN_A) },
{ "ACRSYS", "ACRSYS ", "Insyde Corp.", "Acer", "Acer System", BL(ACE_I), BL(ACE_A) },
/* --- DIY/retail (AMI firmware): ACPI OEM id "ALASKA"; brand in baseboard --- */
{ "ALASKA", "A M I ", "American Megatrends Inc.", "ASUSTeK COMPUTER INC.", "$ASUS$", BL(ASUS_I), BL(ASUS_A) },
{ "ALASKA", "A M I ", "American Megatrends Inc.", "Gigabyte Technology Co., Ltd.", "GIGABYTE", BL(GBT_I), BL(GBT_A) },
{ "ALASKA", "A M I ", "American Megatrends Inc.", "Micro-Star International Co., Ltd.", "MSI", BL(MSI_I), BL(MSI_A) },
{ "ALASKA", "A M I ", "American Megatrends Inc.", "ASRock", "ASRock", BL(ASR_I), BL(ASR_A) },
};
static const Platform *plat(void)
{
return &PLAT[spoof_field("anchor.platform") % ARRAY_SIZE(PLAT)];
}
/* the chosen board for THIS platform under the CPU-vendor anchor (Intel/AMD). */
static const Board *chosen_board(void)
{
const Platform *p = plat();
const Board *list = spoof_anchor_vendor() ? p->amd : p->intel;
size_t n = spoof_anchor_vendor() ? p->na : p->ni;
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; }
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;
}