PSPTool是一个处理AMD二进制blob的工具
psptool的Python项目详细描述
PSPTool公司
PSPTool是一把瑞士军刀,用于处理AMD安全处理器的固件(以前称为Platform Security Processor或PSP)。它将AMD固件定位在UEFI映像中作为针对AMD平台的BIOS更新的一部分。在
它基于AMD的专有文件系统的逆向工程工作,用于将固件blob打包到UEFI固件映像中。这些文件的大小通常为16MB,可以方便地由UEFITool解析。但是,AMD的所有二进制blob都位于UEFITool无法处理的填充卷中。在
PSPTool与通过BIOS更新获得的UEFI图像一起工作。在
安装
您可以通过pip安装PSPTool
pip install psptool
或来自GitHub:
^{pr2}$CLI使用
PSPTool提供了命令行中的一系列功能。在
示例1:列出给定BIOS ROM的所有固件条目。
$ psptool Lenovo_Thinkpad_T495_r12uj35wd.iso
+-----------+----------+---------+-------+---------------------+
| Directory | Addr | Type | Magic | Secondary Directory |
+-----------+----------+---------+-------+---------------------+
| 0 | 0x28bb20 | PSP_NEW | $PSP | 0x138000 |
+-----------+----------+---------+-------+---------------------+
+---+-------+----------+---------+---------------------------------+-------+------------+------------------------------------+
| | Entry | Address | Size | Type | Magic | Version | Info |
+---+-------+----------+---------+---------------------------------+-------+------------+------------------------------------+
| | 0 | 0x28bf20 | 0x240 | AMD_PUBLIC_KEY~0x0 | 60BB | | |
| | 1 | 0x382f20 | 0xc300 | PSP_FW_BOOT_LOADER~0x1 | $PS1 | 0.8.2.59 | signed(60BB), encrypted |
| | 2 | 0x28c220 | 0xb300 | PSP_FW_RECOVERY_BOOT_LOADER~0x3 | $PS1 | 0.8.2.59 | signed(60BB), encrypted |
| | 3 | 0x297520 | 0x22770 | 0x208 | | | |
| | 4 | 0x2b9d20 | 0x71b0 | 0x212 | | | |
| | 5 | 0x2c0f20 | 0x20830 | PSP_SMU_FN_FIRMWARE~0x108 | | | |
| | 6 | 0x2e1820 | 0x5010 | !SMU_OFF_CHIP_FW_3~0x112 | | | |
| | 7 | 0x2e6920 | 0x10 | WRAPPED_IKEK~0x21 | | | |
| | 8 | 0x2e6b20 | 0x1000 | TOKEN_UNLOCK~0x22 | | | |
| | 9 | 0x2e7b20 | 0x1860 | 0x224 | $PS1 | A.2.3.27 | signed(60BB), encrypted |
| | 10 | 0x2e9420 | 0x1760 | 0x124 | $PS1 | A.2.3.1A | signed(60BB), encrypted |
| | 11 | 0x2eac20 | 0xdd0 | ABL0~0x30 | AW0B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 12 | 0x2eba20 | 0xcbb0 | ABL1~0x31 | AW1B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 13 | 0x2f8620 | 0x8dc0 | ABL2~0x32 | AW2B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 14 | 0x301420 | 0xbb90 | ABL3~0x33 | AW3B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 15 | 0x30d020 | 0xcca0 | ABL4~0x34 | AW4B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 16 | 0x319d20 | 0xc910 | ABL5~0x35 | AW5B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 17 | 0x326720 | 0x9ef0 | ABL6~0x36 | AW6B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 18 | 0x330620 | 0xc710 | ABL7~0x37 | AW7B | 18.12.10.0 | compressed, signed(60BB), verified |
| | 19 | 0x382b20 | 0x0 | !PL2_SECONDARY_DIRECTORY~0x40 | | | |
+---+-------+----------+---------+---------------------------------+-------+------------+------------------------------------+
[...]
示例2:从给定的BIOS ROM中提取所有唯一的固件条目,解压缩压缩条目并将公钥转换为PEM格式。
$ psptool -Xunk ASUS_PRIME-A320M-A-ASUS-4801.CAP
ll ASUS_PRIME-A320M-A-ASUS-4801.CAP_unique_extracted/
[...]
17007195 64 -rw-r--r-- 1 cwerling staff 32K 14 Aug 15:32 PSP_AGESA_RESUME_FW~0x10
17007235 8 -rw-r--r-- 1 cwerling staff 451B 14 Aug 15:32 PSP_BOOT_TIME_TRUSTLETS_KEY~0xd
17007244 224 -rw-r--r-- 1 cwerling staff 112K 14 Aug 15:32 PSP_BOOT_TIME_TRUSTLETS~0xc_0.7.0.1
17007237 64 -rw-r--r-- 1 cwerling staff 32K 14 Aug 15:32 PSP_FW_BOOT_LOADER~0x1
17007197 104 -rw-r--r-- 1 cwerling staff 49K 14 Aug 15:32 PSP_FW_BOOT_LOADER~0x1_0.8.0.5E
17007196 112 -rw-r--r-- 1 cwerling staff 55K 14 Aug 15:32 PSP_FW_BOOT_LOADER~0x1_0.D.0.1A
17007223 48 -rw-r--r-- 1 cwerling staff 24K 14 Aug 15:32 PSP_FW_RECOVERY_BOOT_LOADER~0x3
17007224 96 -rw-r--r-- 1 cwerling staff 45K 14 Aug 15:32 PSP_FW_RECOVERY_BOOT_LOADER~0x3_0.8.0.5E
17007232 288 -rw-r--r-- 1 cwerling staff 144K 14 Aug 15:32 PSP_FW_TRUSTED_OS~0x2
17007180 128 -rw-r--r-- 1 cwerling staff 61K 14 Aug 15:32 PSP_FW_TRUSTED_OS~0x2_0.8.0.5E
17007247 128 -rw-r--r-- 1 cwerling staff 60K 14 Aug 15:32 PSP_FW_TRUSTED_OS~0x2_0.D.0.1A
17007205 256 -rw-r--r-- 1 cwerling staff 128K 14 Aug 15:32 PSP_NV_DATA~0x4
17007182 24 -rw-r--r-- 1 cwerling staff 12K 14 Aug 15:32 PSP_S3_NV_DATA~0x1a
17007226 160 -rw-r--r-- 1 cwerling staff 80K 14 Aug 15:32 PSP_SMU_FN_FIRMWARE~0x108
17007202 8 -rw-r--r-- 1 cwerling staff 451B 14 Aug 15:32 SEC_DBG_PUBLIC_KEY~0x9
17007216 32 -rw-r--r-- 1 cwerling staff 14K 14 Aug 15:32 SEC_GASKET~0x24_11.3.0.8
17007206 16 -rw-r--r-- 1 cwerling staff 5,8K 14 Aug 15:32 SEC_GASKET~0x24_A.2.3.27
17007176 264 -rw-r--r-- 1 cwerling staff 129K 14 Aug 15:32 SMU_OFFCHIP_FW~0x8
17007217 520 -rw-r--r-- 1 cwerling staff 256K 14 Aug 15:32 SMU_OFFCHIP_FW~0x8_0.2E.16.0
[...]
示例3:从给定的BIOS ROM的目录索引1条目索引8(PSP_BOOT_TIME_TRUSTLETS
)处提取固件条目,并显示长度为8的字符串。
$ psptool -X -d 1 -e 8 MSI_X399_E7B92AMS.130 | strings -n 8
AMD_TL_UTIL: Hashing the message: %p
AMD_TL_UTIL: ProcessCmd_Hash(), UTIL_ERR_INVALID_BUFFER, exit
RSA: Calling tlApiRandomGenerateData
RSA: Calling DbgUnlockRsaKeyGen
RSA: Done Calling DbgUnlockRsaKeyGen
DbgUnlockRsaKeyGen failed
AMD_TL_UTIL: Deriving AES key
AMD_TL_UTIL: ProcessCmd_Hmac(), UTIL_ERR_INVALID_BUFFER, exit
AMD_TL_UTIL: Deriving HMAC key
HMAC Signature Key for PSP Data saved in DRAM
AMD_TL_UTIL: Computing HMAC of payload
AMD_TL_UTIL: running
AMD_TL_UTIL: invalid TCI
TCI buffer: %p
TCI buffer length: %p
sizeof(tciMessage_t): %p
AMD_TL_UTIL: waiting for notification
RSA: Calling generateKeyPair and RSA signing
RSA: Calling DbgUnlockKeyVerfiy
AMD_TL_UTIL: Unknown command ID %d, ignore
AMD_TL_UTIL: notify TLC
一般用法:
usage: psptool [-E | -X | -R] file
Display, extract, and manipulate AMD PSP firmware inside BIOS ROMs.
positional arguments:
file Binary file to be parsed for PSP firmware
optional arguments:
-E, --entries Default: Parse and display PSP firmware entries.
[-n]
-n: list unique entries only ordered by their offset
-j: output in JSON format instead of tables
-X, --extract-entry Extract one or more PSP firmware entries.
[-d idx [-e idx]] [-n] [-u] [-c] [-k] [-o outfile]
-d idx: specifies directory_index (default: all directories)
-e idx: specifies entry_index (default: all entries)
-n: skip duplicate entries and extract unique entries only
-u: uncompress compressed entries
-c: try to decrypt entries
-k: convert pubkeys into PEM format
-o file: specifies outfile/outdir (default: stdout/{file}_extracted)
-R, --replace-entry Copy a new entry (including header and signature) into the
ROM file and update metadata accordingly.
-d idx -e idx -s subfile -o outfile
-d idx: specifies directory_index
-e idx: specifies entry_index
-s file: specifies subfile (i.e. the new entry contents)
-o file: specifies outfile
Python用法
PSPTool可以用作Python模块,例如在交互式IPython会话中:
> from psptool import PSPTool
> psp = PSPTool.from_file('original_bios.bin')
> psp.blob.directories
[Directory(address=0x77000, type=PSP_NEW, count=16),
Directory(address=0x149000, type=secondary, count=20),
Directory(address=0x117000, type=BHD, count=14),
Directory(address=0x249000, type=secondary, count=17)]
> psp.ls_dir(0)
+---+-------+----------+---------+------+-----------------------------+-------+------------+-----------------------+
| | Entry | Address | Size | Type | Type Name | Magic | Version | Signed by |
+---+-------+----------+---------+------+-----------------------------+-------+------------+-----------------------+
| | 0 | 0x77400 | 0x240 | 0x0 | AMD_PUBLIC_KEY | | | |
| | 1 | 0x149400 | 0x10000 | 0x1 | PSP_FW_BOOT_LOADER | $PS1 | 0.7.0.52 | AMD_PUBLIC_KEY |
| | 2 | 0x77700 | 0xcf40 | 0x3 | PSP_FW_RECOVERY_BOOT_LOADER | $PS1 | FF.7.0.51 | AMD_PUBLIC_KEY |
| | 3 | 0x84700 | 0x1e550 | 0x8 | SMU_OFFCHIP_FW | SMUR | 4.19.64.0 | AMD_PUBLIC_KEY |
| | 4 | 0xa2d00 | 0x340 | 0xa | OEM_PSP_FW_PUBLIC_KEY | | | |
| | 5 | 0xa3100 | 0x3eb0 | 0x12 | SMU_OFF_CHIP_FW_2 | SMUR | 4.19.64.0 | AMD_PUBLIC_KEY |
| | 6 | 0xa7000 | 0x10 | 0x21 | | | | |
| | 7 | 0xa7100 | 0xcc0 | 0x24 | | $PS1 | 12.2.0.9 | AMD_PUBLIC_KEY |
| | 8 | 0xa7e00 | 0xc20 | 0x30 | | 0BAR | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 9 | 0xa8b00 | 0xbc50 | 0x31 | 0x31~ABL_ARM_CODE~ | AR1B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 10 | 0xb4800 | 0xb5c0 | 0x32 | | AR2B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 11 | 0xbfe00 | 0xdb00 | 0x33 | | AR3B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 12 | 0xcd900 | 0xefd0 | 0x34 | | AR4B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 13 | 0xdc900 | 0xf020 | 0x35 | | AR5B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 14 | 0xeba00 | 0xbd60 | 0x36 | | AR6B | 17.9.18.12 | OEM_PSP_FW_PUBLIC_KEY |
| | 15 | 0x149000 | 0x400 | 0x40 | !PL2_SECONDARY_DIRECTORY | | | |
+---+-------+----------+---------+------+-----------------------------+-------+------------+-----------------------+
> psp.blob.directories[0].entries[0]
PubkeyEntry(type=0x0, address=0x77400, size=0x240, len(references)=1)
> psp.blob.directories[0].entries[0].get_bytes()
b'\x01\x00\x00\x00\x1b\xb9\x87\xc3YIF\x06\xb1t\x94V\x01\xc9\xea[\x1b\xb9\x87\xc3YIF\x06\xb1t\x94V\x01\xc9\xea[\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
[...]
> my_stuff = [...]
> psp.blob.directories[0].entries[1].move_buffer(0x60000, 0x1000)
> psp.blob.set_bytes(0x60000, 0x1000, my_stuff)
> psp.to_file('my_modified_bios.bin')
pstrace软件
PSPTrace可用于将用Saleae逻辑分析仪记录的引导过程的SPI捕获与UEFI映像的PSP固件关联起来。SPI捕获必须通过Analyzers>;SPI>;Export as text/csv file从Saleae逻辑软件导出。请确保以适当的采样率进行采样,并且SPI分析器设置为Hex
。在
它与PSPTool一起安装(参见上面的安装说明),并且只提供命令行界面。在
usage: psptrace [-h] [-o] [-n] [-c] [-t] [-l LIMIT_ROWS] [-v] csvfile romfile
Read in an SPI capture created by a Saleae Logic Analyzer and a ROM file
resembling the flash contents and display an access chronology. On first load,
psptrace needs to parse a lot of raw data which will be saved on disk. All
other loads will then be much faster.
positional arguments:
csvfile CSV file of SPI capture
romfile ROM file of SPI contents
optional arguments:
-h, --help show this help message and exit
-o, --overview-mode aggregate accesses to the same firmware entry
-n, --no-duplicates hide duplicate accesses (e.g. caused by multiple PSPs)
-c, --collapse collapse consecutive reads to the same PSP entry type
(denoted by [c] and sometimes by ~ if collapsing was
fuzzy)
-t, --normalize-timestamps
normalize all timestamps
-l LIMIT_ROWS, --limit-rows LIMIT_ROWS
limit the processed rows to a maximum of n
-v, --verbose increase output verbosity
示例用法
在记录了带有AMD Epyc CPU的Supermicro服务器系统的引导过程后,pstrace以概述模式输出以下引导(-o
):
$ psptrace -o spi_trace.txt flash.bin
Info: Creating database in spi_trace.txt.pickle ...
Info: Parsed and stored a database of 14028942 rows.
+---------+---------------+----------+-----------------------------+------+
| No. | Lowest access | Range | Type | Info |
+---------+---------------+----------+-----------------------------+------+
| 0 | 0x820000 | 0x780007 | Unknown area | |
| 22 | 0x020000 | 0x00001c | Firmware Entry Table | |
| 33 | 0x077000 | 0x00012a | Directory: $PSP | |
| 70 | 0x077000 | 0x000100 | Directory: $PSP | CCP |
| 107 | 0x077400 | 0x000240 | AMD_PUBLIC_KEY | CCP |
| 177 | 0x149400 | 0x00d780 | PSP_FW_BOOT_LOADER | CCP |
| | | | | |
| | | | ~ 3410 µs delay ~ | |
| | | | | |
| 7084 | 0x149000 | 0x000180 | Directory: $PL2 | CCP |
| 7090 | 0x000000 | 0x020046 | Unknown area | |
| 7091 | 0x020000 | 0x000024 | Firmware Entry Table | |
| | | | | |
| | | | ~ 66 µs delay ~ | |
| | | | | |
| 7095 | 0x117000 | 0x000160 | Directory: $BHD | |
| 7096 | 0x149000 | 0x000152 | Directory: $PL2 | |
| 7554 | 0x000000 | 0x117280 | Unknown area | |
| 7581 | 0x020000 | 0x000022 | Firmware Entry Table | |
| 7859 | 0x249000 | 0x0001c0 | Directory: $BL2 | CCP |
| 7880 | 0x1170c0 | 0x000080 | Directory: $BHD | CCP |
| 7909 | 0x2491c0 | 0x000240 | Unknown area | CCP |
| 8017 | 0x249010 | 0x00019a | Directory: $BL2 | |
| 8560 | 0x17c100 | 0x001932 | DEBUG_UNLOCK | |
| 8939 | 0x17c200 | 0x001800 | DEBUG_UNLOCK | CCP |
| 10144 | 0x177a00 | 0x0001c0 | SEC_DBG_PUBLIC_KEY | |
| 10576 | 0x177bc0 | 0x000180 | SEC_DBG_PUBLIC_KEY | CCP |
| | | | | |
| | | | ~ 178 µs delay ~ | |
| | | | | |
| 10582 | 0x17e000 | 0x000080 | TOKEN_UNLOCK | CCP |
[...]
- 项目
标签: