
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).
针对技嘉 H510M K V2(H510MKV2.F3)BIOS 镜像的静态逆向工程:完整地对 PI 规范 SMM Core 内存分配器进行 UEFI 固件卷提取分析,并定向搜寻 GIGABYTE/Binarly 于 2025 年披露的四个 SMM 内存破坏漏洞(CVE-2025-7026、CVE-2025-7027、CVE-2025-7028、CVE-2025-7029)。
状态:4 个 CVE 中已确认 1 个存在(CVE-2025-7027)。另外 3 个已在全部可访问固件中积极搜寻,但未找到。详见 未确认的 CVE 以了解这究竟意味着什么、不意味着什么。
这是一项 n-day 研究,而非 0-day 披露。此处引用的所有四个 CVE 均已由 GIGABYTE 公开披露并修复(修复固件于 2025-06-12 开始出货),并由 Binarly 和 CERT/CC 在本研究开始之前分配了 CVE 编号并撰写报告。本仓库中的内容并非新的漏洞发现——而是对先前已披露、已修复的漏洞类别是否存在于一个特定的、可公开下载的 BIOS 构建中的独立静态分析验证。
uefi-firmware-parser)——在 SMM/DXE 卷中枚举出 356 个 FFS 文件,其中 302 个具有可提取的 PE32/TE 镜像。PiSmmCore(PI 规范的 SMM Core),通过其硬编码的 "sphd"/"tail" 防护签名,确认并命名了真正的 SMM 池/页分配器(SmmAllocatePool/SmmFreePool/SmmAllocatePages/SmmFreePages 内部实现)——与 EDK2 开源的 MdeModulePkg/Core/PiSmmCore/Pool.c 完全匹配。GenericComponentSmmEntry 中发现并追踪了确切的易受攻击代码路径:一个 NVRAM 变量(SetupXtuBufferAddress)通过 GetVariable() 获取且未经任何验证,被直接用作可通过 SW SMI 0xB2 触达的写入指针——这与 Binarly 公开的根因描述逐点吻合。uefi_firmware(uefi-firmware-parser -e)以递归方式解包 BIOS 镜像:Intel Flash Descriptor 区域 → 固件卷 → FFS 文件 → 节(section),并解压其找到的每个 LZMA/Tiano 压缩固件卷。.ui(驱动显示名称)节和 .pe/.te 镜像节的 FFS 文件复制为独立的 PE32+/TE 二进制文件,命名为 <DriverName>__<GUID8>.<pe32|te>。ida-pro-mcp / idalib 无头工作器接口)配合 Hex-Rays 反编译器,每个模块一个数据库。仅使用自动分析 + Hex-Rays——此环境中没有可用的 FLIRT 签名或 EDK2 类型库(在下方备注为局限性)。BIOS 镜像包含四个 Intel Flash Descriptor 区域;只有 region-bios 包含 GIGABYTE/OEM 代码(region-me.fd、region-gbe.fd、region-pdr.fd 是 Intel Management Engine / GbE / 描述符固件——独立组件,超出范围,未予探索)。
在 region-bios 内发现并提取了四个固件卷:
四个卷均被提取并进行了标记扫描(参见 未确认的 CVE)。
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
这四个漏洞的共同主线是:软件 SMI 处理程序将寄存器或源自 NVRAM 的值视为指向内存的指针,却未验证其实际是否位于 SMRAM 之外,从而允许 ring-0(管理员/root)攻击者将普通的 SW SMI 触发转换为 SMM 特权(ring -2)的任意读写——固件完全沦陷、Secure-Boot 绕过以及操作系统之下的持久化。
并非漏洞——这是背景研究,通过证明工具链(提取 → PE 隔离 → IDA/Hex-Rays → 手动逆向)确实能够还原可验证源码的 EDK2 内部实现,为后续工作奠定了基础,之后才将矛头指向安全漏洞。
PiSmmCore(GUID e94f54cd-81eb-47ed-aec3-856f5dc157a9)是 PI 规范的 SMM Core:它拥有 SmmAllocatePool/SmmFreePool/SmmAllocatePages/SmmFreePages 以及 SMI 处理程序分发表。
调用链(地址位于 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)被确认为真正的 EDK2 MdeModulePkg/Core/PiSmmCore/Pool.c 分配器:它硬编码了字面 ASCII 签名 "sphd"(SMM_POOL_HEAD_SIGNATURE)和 "tail"(SMM_POOL_TAIL_SIGNATURE)——正是开源实现中的魔法常量。大小 ≤ 0x800 字节的请求通过大小类别空闲链表子分配器处理;更大的请求则遍历页面空闲链表,并在返回的块上包裹头部/尾部防护签名。释放侧对应函数(SmmInternalFreePool_sphd_tail)在将内存归还空闲链表之前会验证相同的签名。
所有重命名都已固化在 smm_modules/PiSmmCore.pe32.i64 中——在 IDA 中打开它并配合 Hex-Rays 即可直接查看。
模块: GenericComponentSmmEntry(GUID 9caa3071-3459-4c5b-bbf0-ee68fe4dd46d)
文件: smm_modules_all/GenericComponentSmmEntry__9caa3071.pe32(+ 已分析的 .i64)
对每个提取的模块(先是 51 个 Smm* 命名模块,然后是主卷中的所有 302 个,接着是辅助卷)进行了针对 SetupXtuBufferAddress 的字节/字符串扫描——这是 Binarly 的 CVE-2025-7027 报告所引用的确切 NVRAM 变量名。它在 GenericComponentSmmEntry 内部以 UTF-16LE 字符串形式匹配(其 DXE 对应物 GenericComponentDxeEntry 也可能设置/暴露该变量)。
1. GetXtuBufferAddress_FromNvram(0x1F270)调用 gRT->GetVariable(L"SetupXtuBufferAddress" &Guid NULL &Size=8 &OutBuffer)(在运行时服务风格表中的偏移 +72 处 = GetVariable)。返回存储在该 NVRAM 变量中的原始 8 字节值——未对该值实际是什么进行任何验证。
2. SUSPECTED_CVE_2025_7027_UnvalidatedXtuPtrWrite(0x18400)调用上述函数获取 v3(源自 NVRAM 的“地址”),然后循环(循环次数取自其自身输入结构 a1[3] 中的计数)执行:
*(WORD *)(v3 + 2 * v7 + 12) = v9; // v3 = raw NVRAM value v9 = attacker-influenced data
v3 在被用作写入目标之前从未被检查是否为真实的、边界内且非 SMRAM 的地址。SetupXtuBufferAddress 是一个普通的(在此构建中未受 SMM 锁定)NVRAM 变量——ring-0 攻击者可以先通过 SetVariable() 将其设置为任意选定的地址(例如 SMRAM 地址或敏感的内核/虚拟机监控程序结构),然后触发 SMI,从而产生可控的、SMM 特权的 write-what-where。
3. ComponentDispatch_KeymapOrXtu(0x18590)——分派回调:从内部组件数据库获取一个组件类型字节,如果 type == 1 则调用上述易受攻击的函数。类型 0 则进入 SetupVar_SafeKeymapWrite_bounded(0x18234),该函数——与此形成对比——确实针对真实的 Setup NVRAM 变量进行了正确的“大小 vs 容量”边界检查。正是这种对比让 XTU 路径显得异常且未受检查。
4. sub_18698 将 ComponentDispatch_KeymapOrXtu 注册到分派值 0xB2(十进制 178)——正是 Binarly 公告中为该漏洞类别命名的 SwSmiInputValue 0xB2。这把软件 SMI 触发端口直接与易受攻击的分派路径关联起来。
SetupXtuBufferAddress)——逐字匹配。0xB2)。RBX 寄存器如何将组件选择输入馈送到 ComponentDispatch_KeymapOrXtu/a1[3]——尚未一路追溯到原始 CPU 保存状态读取。这需要再对任何在调用 GenericComponentSmmEntry 注册的回调之前分派已注册 0xB2 值的逻辑做一轮追踪。这是静态分析层面的确认,表明该 CVE 中描述的易受攻击模式存在于此 BIOS 构建中——并非可用的漏洞利用或 PoC。未验证任何 SMRAM 内容、保存状态布局或运行时行为。
在 Binarly 针对这三个 CVE 的公开报告中提到的每个标记——$DB$、2DB$、SwSmi、OcHeader、FuncBlock、CommandRcx0、ReadFlash、WriteFlash、EraseFlash、GetFlashInfo——都被作为字面字节序列和(适用时)UTF-16LE 字符串进行搜索,范围包括:
flash.fd 镜像。all_modules/)。extra_volumes_modules/)。f641_pei_modules/)。这些标记在任何地方都没有被找到。 只有 SetupXtuBufferAddress(CVE-2025-7027)和通用的 OverClock UI 文本字符串(无关的 BIOS Setup 菜单标签)匹配。
SetupXtuBufferAddress 必须作为字面字符串出现,因为它是一个传递给 GetVariable() 的真实 NVRAM 变量名——该字符串在功能上是必需的。相比之下,CommandRcx0、OcHeader 和 FuncBlock 读起来更像是 Binarly 自己对匿名/剥离函数的内部标签,而非二进制中嵌入的标识符。它们作为字符串的缺失,并不能证明底层代码是否存在。$DB$/2DB$ 魔法常量如果存在,应该会以字节级匹配的形式出现(它们会以编译后比较字符串中的立即数操作数形式出现,或者不会出现)——它们的缺失多少更有意义一些,但仍不具决定性(不同的立即数编码、特定型号的固件变体,或略微不同的检查顺序,都可能绕过原始子字符串扫描)。
FlashSmiSmm(GUID 6c289241-...)和 FlashDriverSmm(GUID 0c375a90-...)是最有力的候选者——它们的名字与 ReadFlash/WriteFlash/EraseFlash/GetFlashInfo 几乎完全对应。两者都已被提取并自动分析(smm_modules_all/ 中的 .i64 数据库已可配合 Hex-Rays 使用),但尚未手动追踪——分别有 174 个和 243 个函数,且没有可区分的静态标记,需要像对 CVE-2025-7027 所做的那样进行手动分派器追踪(找到 SW SMI 0xB2 的等价注册,跟随它到函数指针表分派,检查表指针是否经过验证)。OcHeader)。 好的候选者:GenericComponentSmmEntry 本身(已证明正是在该模块中出现了未检查指针漏洞)、PowerMgmtSmm、、、——目前均未手动追踪。这些工作在本次研究中均未完成——在此明确标注,以便让这一缺口可见,而不是默默暗示已“检查并确认干净”。
如果您拥有该主板(或此公告涵盖的 240 多款技嘉型号中的任何一款):请从技嘉支持网站更新到当前 BIOS。 GIGABYTE 于 2025-06-12 开始出货修复固件;此处分析的构建(日期为 2023-12-20 的 H510MKV2.F3)早于该日期约 18 个月,与未修复状态一致。这不是一个理论上的建议——本研究在该特定构建中发现了 CVE-2025-7027 的实际易受攻击代码路径。
.til),因此 Hex-Rays 无法自动映射 SMM System Table(gSmst)/私有数据结构字段;分析中某些结构体偏移的解释基于手动追踪,而非应用类型信息。region-me.fd、region-gbe.fd、region-pdr.fd(Intel ME / GbE / 描述符区域)——超出范围(它们是独立的固件组件,并非 GIGABYTE/OEM 的 SMM 代码)。| 主板 | GIGABYTE H510M K V2 (H510MKV2) |
| BIOS 文件 | H510MKV2.F3 |
| 文件大小 | 16777216 字节(16 MB) |
| 文件日期 | 2023-12-20 |
| MD5 | a9bca8aeb55061824af1c3eedfb5c846 |
| SHA-256 | 934a935e5faba8d2cea4e1d51e9edb6aed86b32f412d0da5bae602bd9fd8f9f3 |
| 芯片组 | Intel H510 |
| 厂商补丁自 | 2025-06-12(此构建早于该日期约 18 个月) |
| 卷(容器 FFS GUID) | 内容 | 提取文件数 |
|---|
file-9e21fd93-... → volume-ee4e5898-... | 主 DXE/SMM 驱动卷——所有 Smm* 驱动、平台 DXE 驱动 | 302 |
file-f641ac56-... → volume-ee4e5898-... | 上述内容的重复/PEI 阶段副本(较小的子集:PiSmmCommunicationPei、IT8728FSmmFeaturesPei 等) | 22 |
file-3417f275-... → volume-3417f275-... | 早期 PEI/DXE 启动卷(DxeIpl、FspS3Notify ...) | 21(2 个含镜像) |
file-05ca020b-... → volume-05ca020b-... | 小型辅助卷,无任何可执行镜像 | 2 |
| CVE | Binarly ID | CVSS | 公开根因摘要 |
|---|
| CVE-2025-7026 | BRLY-2025-008 | 8.2 | SW SMI 处理程序(SwSmiInputValue 0xB2)在 Binarly 称为 CommandRcx0 的函数中将 RBX 寄存器视为未检查的指针;如果 *RBX 匹配 '$DB$'/'2DB$',该处理程序将执行任意 SMRAM 写入。 |
| CVE-2025-7027 | BRLY-2025-009 | 8.2 | 双重指针解引用:未经验证的 NVRAM 变量(SetupXtuBufferAddress)与攻击者控制的、源自 RBX 的指针结合 → 任意 SMRAM 写入。 |
| CVE-2025-7028 | BRLY-2025-010 | 8.2 | 缺乏对源自 RBX/RCX 的函数指针结构(FuncBlock)的验证,这些结构可通过 ReadFlash/WriteFlash/EraseFlash/GetFlashInfo 触达。 |
| CVE-2025-7029 | BRLY-2025-011 | 8.2 | 未检查地使用 RBX 来控制攻击者影响的 OcHeader 指针,位于电源/热(超频)配置逻辑中 → 任意 SMRAM 写入。 |
RealTimePowerSmmThermalFanCtrSmmPpamPlatformSmm$DB$/2DB$ 签名检查)。 由于根据 Binarly 的报告,SwSmiInputValue 0xB2 至少被 CVE-2025-7026 和 CVE-2025-7027 共用,且本次转储证明 0xB2 是 GenericComponentSmmEntry 中一个真实且活跃使用的分派值,下一步是枚举主卷中每一个针对 0xB2 注册回调的驱动(而不仅仅是已发现的那个),并逐一检查是否存在“未检查指针 + 魔法值”模式。