BIOS写保护机制原理及访问寄存器方法。
PCI总线配置空间
CPU通过PCI设备的设备号以及配置空间中的寄存器编号来访问配置空间寄存器。
PCI有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空间。
配置空间是PCI所特有的一个物理空间。由于PCI支持设备即插即用,所以PCI设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统决定其映射的基址。系统加电时,BIOS检测PCI总线,确定所有连接在PCI总线上的设备以及它们的配置要求,并进行系统配置。所以,所有的PCI设备必须实现配置空间,从而能够实现参数的自动配置,实现真正的即插即用。
要访问PCI总线设备的配置空间,必须先查找该设备。查找的基本根据是各PCI设备的配置空间里都存有特定的设备号(Device ID)及销售商号(Vendor ID),它们占用配置空间的00h地址。而查找的目的是获得该设备的总线号和设备号。
查找的基本过程如下:用I/O命令写配置空间的地址寄存器(CONFIG_ADDRESS)CF8h,使其最高位为1,总线号及设备为0,功能号及寄存器号为0,即往I/O端口CF8h80000000h;然后用I/O命令读取配置空间的数据寄存器(CONFIG_DATA) 0xCFC。如果该寄存器值与该PCI设备的Device ID及Vendor ID不相符,则依次递增设备号/总线号,重复上述操作直到找到该设备为止。如果查完所有的设备号/总线号(1~5)仍不能找到该设备,则应当考虑硬件上的问题。对于多功能设备,只要设备配置寄存器相应的功能号值,其余步骤与单功能设备一样。
Intel® 7 Series / C216 Chipset Family Platform Controller Hub datasheet的13章《LPC Interface Bridge Registers (D31:F0)》:
PCH的LPC bridge函数位于PCI Device 31:Function 0中。该函数包含许多函数单元,如DMA、中断控制器、计时器、电源管理、系统管理、GPIO、RTC和LPC配置寄存器。
LPC接口PCI寄存器地址映射表(LPC I/F – D31:F0)如下:
SPI(Serial Peripheral Interface)
SPI位于内存映射空间中,其包含允许对SPI接口上的设备进行设置和编程的寄存器,所有寄存器(包括内存映射寄存器)必须按byte、word和DWord进行寻址。
SPI Host接口寄存器在基址(SPIBAR)为3800h的RCRB(Root Complex Register Block)芯片组寄存器空间中进行内存映射,位于3800h-39FFh范围内。
RCRB的地址可以在RCBA寄存器中找到,通过SPIBAR + Offset可以访问各个寄存器,偏移表如下:
写保护机制
英特尔硬件提供两种主要机制来保护位于主板上的SPI ROM芯片不被操作系统上的软件写入:
- 通过PCI配置空间访问的平台控制器集线器(PCH)中
BIOS_CNTL
寄存器的BIOS Write Enable (BIOSWE
) 和、BIOS Lock Enable (BLE
)位和SMM BIOS Write Protect Disable(SMM_BWP) - SPI保护区域寄存器
PR0-PR5
。同时,PCH中HSFS
寄存器的FLOCKDN
位用于保护PR寄存器不被覆盖。
Intel® 7 Series / C216 Chipset Family Platform Controller Hub datasheet的13.1.33
节对BIOS_CNTL
寄存器的描述如下图:
BIOSWE
位用于控制对闪存芯片的写访问, 置零后只允许读取访问。BLE
位用于保护BIOSWE
位不被SMM代码进行未经授权的修改:
- 在早期引导阶段,系统固件将
BIOSWE
位置零并设置BLE
位,一旦BLE
位被设为1——直到下一次平台重置,它都不能被修改。 - 当
BLE
= 1时,每次尝试设置BIOSWE位都会引发系统管理中断(SMI) —— 最高优先级的中断,将挂起操作系统的执行并将CPU切换到系统管理模式。 - 在SMI调度期间,SMM代码将
BIOSWE
位清零,并恢复OS执行,因此,在OS下运行的攻击者代码可以重新设置BIOSWE
。
当SMM_BWP
位设置后,仅当所有内核在系统管理模式(SMM)中运行且BIOSWE
位设置为1时,SMM BIOS写保护禁用(SMM_BWP)才允许BIOS固件可写。
BIOS_CNTl
寄存器位于LPC I/F – D31:F0的0xDC偏移处,默认值为0x20(未开启写保护的默认值),大小为8字节。
Intel® 7 Series / C216 Chipset Family Platform Controller Hub datasheet的22.1.2
节对HSFS
寄存器的描述如下图:
FLOCKDN
位用于保护SPI保护区域寄存器PR0-PR5不被修改,一旦设置为1,则只能通过硬件复位来清除此位。
用Chipsec 访问寄存器
使用chipsec.utilcmd.pci_cmd模块访问PCI配置空间寄存器,用法:
chipsec_util pci enumerate #枚举PCI/PCIe设备
chipsec_util pci <bus> <device> <function> <offset> [width] [value] #读写PCI配置寄存器
chipsec_util pci dump [<bus> <device> <function>] #dump PCI配置空间数据
chipsec_util pci xrom [<bus> <device> <function>] [xrom_address] #枚举PCI/PCIe ROM
chipsec_util pci cmd [mask] [class] [subclass]
使用命令python chipsec_util.py pci enumerate
对PCI设备进行枚举,可以看到设备号为1F处为LPC控制器:
读取LPC控制器的数据,偏移为0xDC处为BIOS_CNTL
寄存器的值:
python chipsec_util.py pci dump 0 0x1f 0
用python chipsec_main.py -m common.bios_wp
命令读取出来的BIOS_CNTL
寄存器值实际上也是0x2A:
用chipsec.utilcmd.mmio_cmd模块访问SPI寄存器:
>>> chipsec_util mmio list
>>> chipsec_util mmio dump <MMIO_BAR_name>
>>> chipsec_util mmio read <MMIO_BAR_name> <offset> <width>
>>> chipsec_util mmio write <MMIO_BAR_name> <offset> <width> <value>python chipsec_util.py mmio dump SPIBAR #dump SPIBAR基址及对应偏移寄存器的值
对应0x4偏移处为HSFS
寄存器,其值为0xE008,用python chipsec_main.py -m chipsec.modules.common.spi_lock
检查HSFS
寄存器各位的值:
chipsec用不了
chipsec官网找安装说明,windows下需要禁用驱动签名校验的
我这也用不了,提示ERROR: Message: “‘NoneHelper’ is not implemented”
仔细看安装文档,你没安装chipsec_hlpr.sys驱动
驱动在哪下
请去看官方说明文档,我这里不提供基础教学
文章中提到了使用chipsec模块访问PCI配置空间寄存器和SPI寄存器,那么用chipsec能否关闭BIOS刷写保护
chipsec有write参数可以修改寄存器值,但是能否关闭写保护则需要根据实际情况来判断,仔细看了这几个寄存器的描述应该就知道,它设置了多层保护位,在SMM_BWP位和BLE位开启的情况下是无法修改BIOSWE的。
这个软件可以用来备份主板bios文件吗
可以用SPI模块来读取部分数据,使用方式复杂不推荐
那有不有软件可以关闭BIOS写保护?
常用的关闭写保护方法可以参考这两篇文章:
《Unlock Intel Flash Descriptor Read/Write Access Permissions for SPI Servicing》
《AMI Setup – IFR Extractor AMISetupWriter》
微软surfacepro的BIOS芯片写保护有办法禁用吗?
微软surface pro4的BIOS芯片写保护有办法禁用吗?用英特尔的flash programming tool无法刷新BIOS提示无法禁用芯片写保护。
按照上面发的第二篇文章的方法,读取bios固件,找到bios lock变量值,进uefi shell禁用就行
所有品牌的主板都可以吗
这只是最基础的写保护机制,有些品牌的主板会设置更复杂更难绕过的机制,不能一概而论
大佬你好,我的电脑主板有写保护机制,无法写入bios文件,这是提取的主板BIOS文件 https://wwuz.lanzouk.com/iPR8w292l5id 能不能帮忙看下有没有办法关掉这个保护机制来刷入BIOS(在不使用编程器的情况下)
有写入时的报错截图吗
fptw64.exe -f 1.bin
Intel (R) Flash Programming Tool. Version: 11.8.55.3510
Copyright (c) 2007 – 2017, Intel Corporation. All rights reserved.
Reading HSFSTS register… Flash Descriptor: Valid
— Flash Devices Found —
W25Q128FV ID:0xEF4018 Size: 16384KB (131072Kb)
Error 368: Failed to disable write protection for the BIOS space.
FPT Operation Failed.
固件文件里找不到任何UEFI变量配置信息,你试试下载RU.efi文件,用Fat32格式的U盘,把RU.efi文件名修改为bootx64.efi,放到/efi/boot/目录下,然后从U盘启动。
进入RU界面,按ALT-=,看看UEFI变量列表。
你可以自己找找看有没有类似bios lock之类的变量,将它的值修改为0即可。
(另外我看固件里有开BIOSGuard,如果你是要修改BIOS然后写入的话,可能还需要考虑绕过BIOSGuard)
那有办法绕过BIOSGuard吗
不好弄,真要绕的话最好还是能用编程器刷固件,多做几次测试
https://wwuz.lanzoup.com/i1qlf2fhp1hi
这个能解吗(除了用编程器之外),可以备份出BIOS固件但无法刷入bios,提示无法禁用写保护,用ru.efi也没找到bios lock之类的变量