
Static reverse-engineering of a GIGABYTE H510M K V2 (`H510MKV2.F3`) BIOS image: full UEFI firmware-volume extraction analysis of the PI-spec SMM Core memory allocator and a targeted hunt for the four SMM memory-corruption vulnerabilities GIGABYTE/Binarly disclosed in 2025 (CVE-2025-7026 CVE-2025-7027 CVE-2025-7028 CVE-2025-7029).
Statisches Reverse-Engineering eines GIGABYTE H510M K V2 (H510MKV2.F3) BIOS-Images: vollständige
UEFI-Firmware-Volume-Extraktionsanalyse des PI-Spezifikations-SMM-Core-Speicher-
Allokators und eine gezielte Suche nach den vier SMM-Speicherkorruptions-
Schwachstellen, die GIGABYTE/Binarly im Jahr 2025 offengelegt haben
(CVE-2025-7026 CVE-2025-7027 CVE-2025-7028 CVE-2025-7029).
Status: 1 von 4 CVEs als vorhanden bestätigt (CVE-2025-7027). Die anderen 3 wurden aktiv im gesamten zugänglichen Firmware-Image gesucht und nicht gefunden – siehe Unconfirmed CVEs für genau was das bedeutet und was nicht.
Dies ist N-Day-Forschung, keine 0-Day-Offenlegung. Alle vier hier referenzierten CVEs wurden bereits öffentlich offengelegt und von GIGABYTE gepatcht (gepatchte Firmware wurde ab 2025-06-12 ausgeliefert), die CVEs wurden von Binarly und CERT/CC vergeben und vor Beginn dieser Forschung beschrieben. Nichts in diesem Repository ist eine neue Schwachstellenentdeckung – es ist eine unabhängige statische Analyse zur Verifizierung, ob die zuvor offengelegten, zuvor gepatchten Bug-Klassen in einem bestimmten öffentlich herunterladbaren BIOS-Build vorhanden sind.
uefi-firmware-parser) – 356 FFS-Dateien im SMM/DXE-Volume aufgelistet,
302 mit extrahierbarem PE32/TE-Image.PiSmmCore (den PI-Spezifikations-SMM-Core) isoliert und vollständig reverse-engineered,
wodurch der echte SMM-Pool/Seiten-Allokator bestätigt und benannt wurde
(SmmAllocatePool/SmmFreePool/SmmAllocatePages/SmmFreePages-
Interna) über seine hartkodierten "sphd"/"tail"-Guard-Signaturen – eine
exakte Übereinstimmung mit der Open-Source-Datei MdeModulePkg/Core/PiSmmCore/Pool.c von EDK2.GenericComponentSmmEntry wurde gefunden und nachverfolgt: Eine NVRAM-Variable
(SetupXtuBufferAddress) wird über ohne Validierung abgerufen
und direkt als Schreibzeiger verwendet, der über SW SMI erreichbar ist – dies
stimmt Punkt für Punkt mit Binarlys öffentlicher Root-Cause-Beschreibung überein.uefi_firmware
(uefi-firmware-parser -e) hat das BIOS-Image rekursiv entpackt: Intel
Flash-Descriptor-Regionen → Firmware-Volumes → FFS-Dateien → Sektionen,
wobei jedes LZMA/Tiano-komprimierte Firmware-Volume dekomprimiert wurde..ui-Sektion (Anzeigename des Treibers)
und einer .pe/.te-Bildsektion wurde als eigenständiges
PE32+/TE-Binary mit dem Namen <DriverName>__<GUID8>.<pe32|te> kopiert.ida-pro-mcp-/idalib-Headless-Worker-Schnittstelle) mit dem Hex-Rays-
Dekompilierer, eine Datenbank pro Modul. Nur Auto-Analyse + Hex-Rays – keine
FLIRT-Signaturen oder EDK2-Typbibliotheken waren in dieser
Umgebung verfügbar (unten als Einschränkung vermerkt).Das BIOS-Image enthält vier Intel-Flash-Descriptor-Regionen; nur
region-bios enthält GIGABYTE/OEM-Code (region-me.fd region-gbe.fd
region-pdr.fd sind Intel Management Engine / GbE / Descriptor-Firmware –
separate Komponenten, die außerhalb des Rahmens liegen und nicht untersucht wurden).
Innerhalb von region-bios wurden vier Firmware-Volumes gefunden und extrahiert:
Alle vier wurden extrahiert und einem Marker-Scan unterzogen (siehe Unbestätigte CVEs).
SMM/
├── README.md this file
├── CVE_ANALYSIS.md full technical deep-dive (code-level detail confidence notes)
├── flash.fd copy of the extracted 16MB BIOS image
├── regions/ raw recursive extraction (every FV/FFS/section as produced by uefi_firmware)
├── smm_modules/ PiSmmCore isolated + fully analyzed (.pe32 + Hex-Rays .i64 renames applied)
├── smm_modules_all/ all 51 `Smm*`-named drivers as standalone PE32/TE + manifest.txt
│ (4 extra ones PiSmmCpuDxeSmm SmmAccess SmmControl SmmLockBox
│ FlashSmiSmm FlashDriverSmm have auto-analyzed .i64 databases)
├── all_modules/ every extractable module from the main DXE/SMM volume (302 not just Smm*-named)
├── extra_volumes_modules/ modules from the two smaller auxiliary firmware volumes
└── f641_pei_modules/ modules from the duplicate PEI-phase volume copy
Gemeinsamer Nenner aller vier: Ein Software-SMI-Handler vertraut einem Register oder einem aus NVRAM stammenden Wert als Zeiger in den Speicher, ohne zu validieren, dass dieser tatsächlich außerhalb von SMRAM liegt. Dadurch kann ein Ring-0-Angreifer (Administrator/root) einen normalen SW-SMI-Auslöser in einen SMM-privilegierten (Ring -2) beliebigen Lese-/Schreibzugriff verwandeln – vollständige Firmware-Kompromittierung, Secure-Boot-Bypass und Persistenz unterhalb des Betriebssystems.
Keine Schwachstelle – Hintergrundforschung, die den Rest der Arbeit verankerte, indem sie bewies, dass die Toolchain (Extraktion → PE-Isolation → IDA/Hex-Rays → manuelles RE) tatsächlich echte, quellenverifizierbare EDK2-Interna rekonstruiert, bevor sie auf Sicherheits-Bugs gerichtet wurde.
PiSmmCore (GUID e94f54cd-81eb-47ed-aec3-856f5dc157a9) ist der PI-Spezifikations-SMM-
Core: Er besitzt SmmAllocatePool/SmmFreePool/SmmAllocatePages/SmmFreePages
und die SMI-Handler-Dispatch-Tabelle.
Aufrufkette (Adressen in smm_modules/PiSmmCore.pe32.i64):
_ModuleEntryPoint (0x1184)
-> SmmCoreEntryPointHelper (0x14D4) writes the "SMST" table signature
-> SmmInternalAllocatePool_wrapper (0x95EC)
-> InternalAllocPoolByIndex_sphd_tail (0x57A8) <- the allocator
-> SmmAllocateZeroedPool (0x961C) alloc + zero wrapper
SmmFreePool_wrapper (0x9714)
-> SmmIsBufferInsideSmram (0x95A8) decides SMRAM-resident vs not
-> SmmInternalFreePool_sphd_tail (0x591C) validates sphd/tail frees
-> InternalFreePages (0x6A2C) page-granularity free + coalesce
InternalFindFreePages (0x6820) page-granularity alloc (mirror of InternalFreePages)
InternalAllocPoolByIndex_sphd_tail (0x57A8) ist als der echte
EDK2-MdeModulePkg/Core/PiSmmCore/Pool.c-Allokator bestätigt: Er kodiert die
literalen ASCII-Signaturen "sphd" (SMM_POOL_HEAD_SIGNATURE) und "tail"
(SMM_POOL_TAIL_SIGNATURE) fest – die exakten magischen Konstanten aus der Open-Source-
Implementierung. Anfragen ≤ 0x800 Bytes durchlaufen einen Sub-Allokator mit Freilisten nach Größenklassen;
größere Anfragen durchlaufen eine Seiten-Freiliste und umhüllen den zurückgegebenen
Block mit Head-/Tail-Guard-Signaturen. Das Gegenstück auf der Freigabeseite
(SmmInternalFreePool_sphd_tail) validiert dieselben Signaturen, bevor
Speicher an die Freiliste zurückgegeben wird.
Alle Umbenennungen sind in smm_modules/PiSmmCore.pe32.i64 eingearbeitet – öffnen Sie es in IDA
mit Hex-Rays, um es direkt zu inspizieren.
Modul: GenericComponentSmmEntry (GUID 9caa3071-3459-4c5b-bbf0-ee68fe4dd46d)
Datei: smm_modules_all/GenericComponentSmmEntry__9caa3071.pe32 (+ analysierte .i64)
Jedes extrahierte Modul (zuerst die 51 Smm*-benannten, dann alle 302 im Hauptvolume,
dann die Hilfsvolumes) wurde per Byte-/String-Scan auf SetupXtuBufferAddress durchsucht –
den exakten NVRAM-Variablennamen, den Binarlys CVE-2025-7027-Analyse zitiert. Es
wurde als UTF-16LE-String in GenericComponentSmmEntry gefunden (und in seinem DXE-
Gegenstück GenericComponentDxeEntry, das es vermutlich setzt/bereitstellt).
1. GetXtuBufferAddress_FromNvram (0x1F270) – ruft
gRT->GetVariable(L"SetupXtuBufferAddress" &Guid NULL &Size=8 &OutBuffer)
(Offset +72 in der Tabelle im Runtime-Services-Stil = GetVariable) auf. Gibt
den rohen 8-Byte-Wert zurück, der in dieser NVRAM-Variablen gespeichert ist – keine Validierung, was
dieser Wert tatsächlich ist.
2. SUSPECTED_CVE_2025_7027_UnvalidatedXtuPtrWrite (0x18400) – ruft
das Obige auf, um v3 (die aus NVRAM stammende "Adresse") zu erhalten, und führt dann eine Schleife aus (begrenzt durch eine
Zählung aus der eigenen Eingabestruktur a1[3]) mit:
*(WORD *)(v3 + 2 * v7 + 12) = v9; // v3 = raw NVRAM value v9 = attacker-influenced data
v3 wird niemals darauf geprüft, eine echte, in den Grenzen liegende Nicht-SMRAM-Adresse zu sein, bevor
es als Schreibziel verwendet wird. SetupXtuBufferAddress ist eine normale
(in diesem Build nicht SMM-gesperrte) NVRAM-Variable – ein Ring-0-Angreifer kann
sie per SetVariable() auf eine beliebige Adresse seiner Wahl setzen (z. B. eine SMRAM-Adresse oder eine
sensible Kernel-/Hypervisor-Struktur), bevor er den SMI auslöst, was
einen kontrollierten SMM-privilegierten Write-what-where erzeugt.
3. ComponentDispatch_KeymapOrXtu (0x18590) – der Dispatch-Callback:
holt ein Byte für den Komponententyp aus einer internen Komponentendatenbank und ruft,
wenn der Typ == 1 ist, die obige anfällige Funktion auf. Typ 0 geht an
SetupVar_SafeKeymapWrite_bounded (0x18234), das – im Kontrast dazu – tatsächlich
eine ordnungsgemäße Größen-gegen-Kapazität-Grenzprüfung gegen eine echte Setup-NVRAM-
Variable durchführt. Genau dieser Kontrast lässt den XTU-Pfad als den
anomalen, ungeprüften hervorstechen.
4. sub_18698 – registriert ComponentDispatch_KeymapOrXtu für den
Dispatch-Wert 0xB2 (178 dezimal) – genau den SwSmiInputValue 0xB2,
den Binarlys Advisory für diese Bug-Klasse nennt. Dadurch wird der Software-SMI-
Auslöseport direkt mit dem anfälligen Dispatch-Pfad verbunden.
SetupXtuBufferAddress) – wörtlich.0xB2).RBX-
Register beim SMI-Eintritt die Komponentenauswahl-Eingabe speist, die
ComponentDispatch_KeymapOrXtu/a1[3] erreicht – wurde nicht bis zum
rohen CPU-Save-State-Read zurückverfolgt. Dafür wäre ein weiterer Durchgang durch das,
was auf den registrierten 0xB2-Wert dispatched, nötig, bevor der registrierte
Callback von GenericComponentSmmEntry aufgerufen wird.Dies ist eine statische Analyse-Bestätigung, dass das im CVE beschriebene anfällige Muster in diesem BIOS-Build vorhanden ist – kein funktionierender Exploit oder PoC. Es wurden weder SMRAM-Inhalte, Save-State-Layout noch Laufzeitverhalten verifiziert.
Jeder Marker, der in Binarlys öffentlichen Analysen zu diesen drei CVEs genannt wird –
$DB$ 2DB$ SwSmi OcHeader FuncBlock CommandRcx0 ReadFlash
WriteFlash EraseFlash GetFlashInfo – wurde sowohl als literale
Bytesequenz als auch (wo zutreffend) als UTF-16LE-String durchsucht über:
flash.fd-Image.all_modules/).extra_volumes_modules/).f641_pei_modules/).Keiner dieser Marker wurde irgendwo gefunden. Nur SetupXtuBufferAddress
(CVE-2025-7027) und generische OverClock-UI-Textstrings (unzusammenhängende
BIOS-Setup-Menübezeichnungen) stimmten überein.
SetupXtuBufferAddress musste als literaler String erscheinen, weil es ein
echter NVRAM-Variablenname ist, der an GetVariable() übergeben wird – der String ist
funktional erforderlich. CommandRcx0 OcHeader und FuncBlock lesen sich dagegen
wie Binarlys eigene interne Bezeichnungen für anonyme/gestrippte
Funktionen, die sie reverse-engineert haben, nicht wie im Binary eingebettete Bezeichner.
Ihre Abwesenheit als Strings beweist nichts darüber, ob der zugrunde liegende Code
existiert. Die magischen Konstanten $DB$/2DB$ würden als Byte-Level-
Treffer auftauchen, wenn sie vorhanden wären (sie würden als unmittelbarer Operand in der kompilierten
Vergleichsoperation erscheinen oder auch nicht) – ihre Abwesenheit ist etwas aussagekräftiger,
aber dennoch nicht schlüssig (eine andere Immediate-Kodierung, eine pro-Modell-Firmware-
Variante oder eine leicht andere Prüfreihenfolge könnten einen rohen Substring-
Scan umgehen).
FlashSmiSmm (GUID 6c289241-...)
und FlashDriverSmm (GUID 0c375a90-...) sind die stärksten Kandidaten –
ihre Namen passen fast exakt zu ReadFlash/WriteFlash/EraseFlash/GetFlashInfo.
Beide wurden extrahiert und automatisch analysiert (.i64-Datenbanken in
smm_modules_all/, Hex-Rays-bereit), aber nicht manuell nachverfolgt – das sind
jeweils 174 bzw. 243 Funktionen ohne unterscheidbare statische Marker,
was die gleiche Art von manuellem Dispatcher-Tracing erfordert wie für
CVE-2025-7027 (die SW-SMI-0xB2-äquivalente Registrierung finden, ihr zu einem
Funktionszeiger-Tabellen-Dispatch folgen, prüfen, ob der Tabellenzeiger
validiert wird).OcHeader). Gute Kandidaten:
selbst (bereits eine nachgewiesene Quelle eines
Unchecked-Pointer-Bugs in genau diesem Modul), ,
, , – noch keines manuell
nachverfolgt.Nichts davon wurde in diesem Durchgang abgeschlossen – es wird hier explizit markiert, damit die Lücke sichtbar ist, anstatt stillschweigend als „geprüft und sauber“ impliziert zu werden.
Wenn Sie dieses Board besitzen (oder eines der 240+ GIGABYTE-Modelle, die von diesem
Advisory abgedeckt werden): Aktualisieren Sie auf die aktuelle BIOS-Version von der GIGABYTE-Support-Seite.
GIGABYTE begann, gepatchte Firmware ab 2025-06-12 auszuliefern; der hier analysierte Build
(H510MKV2.F3, datiert 2023-12-20) stammt von etwa 18 Monaten davor und ist
konsistent mit einem ungepatchten Zustand. Das ist keine theoretische Empfehlung –
diese Forschung hat den tatsächlichen anfälligen Codepfad für CVE-2025-7027
in diesem spezifischen Build gefunden.
.til) war in dieser Analyseumgebung verfügbar,
daher konnten die Felder der SMM-Systemtabelle (gSmst)/Privatdaten-Strukturen
von Hex-Rays nicht automatisch zugeordnet werden; einige Strukturoffset-
Interpretationen in der Analyse basieren auf manuellem Tracing statt auf
angewendeten Typinformationen.region-me.fd region-gbe.fd region-pdr.fd (Intel ME / GbE /
Descriptor-Regionen) wurden nicht untersucht – außerhalb des Rahmens (separate Firmware-
Komponenten, kein GIGABYTE/OEM-SMM-Code).CVE_ANALYSIS.md für den vollständigen technischen
Deep-Dive auf Code-Ebene, den dieses README zusammenfasst.| Mainboard | GIGABYTE H510M K V2 (H510MKV2) |
| BIOS-Datei | H510MKV2.F3 |
| Dateigröße | 16777216 Bytes (16 MB) |
| Dateidatum | 2023-12-20 |
| MD5 | a9bca8aeb55061824af1c3eedfb5c846 |
| SHA-256 | 934a935e5faba8d2cea4e1d51e9edb6aed86b32f412d0da5bae602bd9fd8f9f3 |
| Chipsatz | Intel H510 |
| Vendor-Patch verfügbar seit | 2025-06-12 (dieser Build ist ~18 Monate älter) |
GetVariable()0xB2| Volume (Container-FFS-GUID) | Inhalt | Extrahierte Dateien |
|---|
file-9e21fd93-... → volume-ee4e5898-... | Haupt-DXE/SMM-Treiber-Volume – alle Smm*-Treiber, Platform-DXE-Treiber | 302 |
file-f641ac56-... → volume-ee4e5898-... | Duplikat/PEI-Phasen-Kopie des Obigen (kleinere Teilmenge: PiSmmCommunicationPei IT8728FSmmFeaturesPei usw.) | 22 |
file-3417f275-... → volume-3417f275-... | Frühes PEI/DXE-Bring-up-Volume (DxeIpl FspS3Notify ...) | 21 (2 mit Images) |
file-05ca020b-... → volume-05ca020b-... | Kleines Hilfs-Volume, keine ausführbaren Images | 2 |
| CVE | Binarly ID | CVSS | Öffentliche Root-Cause-Zusammenfassung |
|---|
| CVE-2025-7026 | BRLY-2025-008 | 8.2 | SW-SMI-Handler (SwSmiInputValue 0xB2) vertraut dem RBX-Register als ungeprüftem Zeiger innerhalb einer Funktion, die Binarly CommandRcx0 nennt; wenn *RBX mit '$DB$'/'2DB$' übereinstimmt, führt der Handler einen beliebigen SMRAM-Schreibvorgang aus. |
| CVE-2025-7027 | BRLY-2025-009 | 8.2 | Doppelte Zeigerdereferenzierung: eine unvalidierte NVRAM-Variable (SetupXtuBufferAddress) kombiniert mit einem vom Angreifer kontrollierten, von RBX abgeleiteten Zeiger → beliebiger SMRAM-Schreibvorgang. |
| CVE-2025-7028 | BRLY-2025-010 | 8.2 | Fehlende Validierung von Funktionszeiger-Strukturen (FuncBlock), die aus RBX/RCX abgeleitet und über ReadFlash/WriteFlash/EraseFlash/GetFlashInfo erreichbar sind. |
| CVE-2025-7029 | BRLY-2025-011 | 8.2 | Ungeprüfte Verwendung von RBX steuert einen vom Angreifer beeinflussbaren OcHeader-Zeiger in der Power-/Thermal- (Overclock-) Konfigurationslogik → beliebiger SMRAM-Schreibvorgang. |
GenericComponentSmmEntryPowerMgmtSmmRealTimePowerSmmThermalFanCtrSmmPpamPlatformSmm$DB$/2DB$-Signaturprüfung). Da SwSmiInputValue 0xB2 laut Binarlys Analysen mindestens für CVE-2025-7026 und CVE-2025-7027 gemeinsam ist
und dieser Dump bewiesen hat, dass 0xB2 ein echter, aktiv genutzter
Dispatch-Wert in GenericComponentSmmEntry ist, besteht der nächste Schritt darin,
jeden Treiber im Hauptvolume aufzulisten, der einen Callback gegen
0xB2 registriert (nicht nur den bereits gefundenen), und jeden auf ein
Muster aus ungeprüftem Zeiger plus magischem Wert zu prüfen.