Zentool – AMD Zen Microcode Manipulation Utility
Zentool:AMD Zen 微代码操作实用工具
该软件包提供了一套用于分析、操作和生成 AMD Zen 处理器微代码补丁的工具。
zentool
命令是各种实用程序的前端。 还有一个简单的汇编器 mcas
和一个简单的反汇编器 mcop
。
用法
命令的一般格式是:
$ zentool [GLOBALOPTIONS] CMD [COMANDOPTIONS] [FILE...]
键入 zentool help
可查看可用命令的列表。
示例
你可以使用 print
命令检查微代码更新文件的标头:
$ zentool print data/cpu00860F01_ver0860010F_2024-11-18_785D74AB.bin
Date: 11182024 (Mon Nov 18 2024)
Revision: 0860010f
Format: 8004
Patchlen: 00
Init: 00
Checksum: 00000000
NorthBridge: 0000:0000
SouthBridge: 0000:0000
Cpuid: 00008601 AMD Ryzen (Grey Hawk, Renoir)
Stepping 1
Model: 0
Extmodel: 6
Extfam: 8
BiosRev: 00
Flags: 00
Reserved: 0000
Signature: 9c... (use --verbose to see) (GOOD)
Modulus: c7... (use --verbose to see)
Check: 5a... (use --verbose to see) (GOOD)
Autorun: false
Encrypted: false
Revision: 0860010f (Signed)
让我们使用 edit
命令修改该修订号,并将结果保存到 modified.bin
:
$ zentool --output modified.bin edit --hdr-revision 0x8600141 data/cpu00860F01_ver0860010F_2024-11-18_785D74AB.bin
$ zentool print modified.bin | grep -m1 ^Revision:
Revision: 08600141
这有效,但现在签名将不正确:
$ zentool verify modified.bin
modified.bin: BAD
你可以使用 resign
命令来补偿你所做的更改:
$ zentool resign modified.bin
$ zentool verify modified.bin
modified.bin: GOOD
现在,你可以使用 load
命令将该更新应用于你的处理器,这需要 root 权限:
$ sudo zentool load --cpu=2 modified.bin
现在,我们可以通过查询微代码版本来验证它是否有效:
$ sudo rdmsr -c -a 0x8b
0x8608103
0x8608103
0x8608141 <---
0x8608103
0x8608103
0x8608103
0x8608103
0x8608103
我们指定的内核接受了微代码更新。
高级用法
你可以使用 print
命令检查微代码文件中的大多数结构,例如匹配寄存器和指令四元组。
$ zentool print --match-regs modified.bin
; Patch 0x8600141 Match Registers (22 total)
; (use --verbose to see empty slots)
[0 ] 07CE
[1 ] 092D
[2 ] 1129
[3 ] 12E9
[4 ] 08F6
[5 ] 0940
[6 ] 0545
[7 ] 08A5
[8 ] 0BF8
[9 ] 124D
[10] 0526
[11] 111A
[12] 107D
[13] 1026
你也可以使用 edit
更改其中的任何一个,例如:
$ zentool edit --match 0=0x1234 modified.bin
指定匹配寄存器的一般格式是 range=value
,其中 range 可以是单个值 12
、值列表 1,2,0x12
、跨度 1,2,3-9
或特殊名称 all
。
你还可以使用一些符号名称,方法是在它们前面加上 @
。
例如,--match 0=@rdtsc
将尝试将第一个匹配寄存器设置为 rdtsc
的地址(如果处理器适用于此补丁)。
注意:这些符号名称存储在
data
目录中的json
文件中。
反汇编
你还可以尝试反汇编指令四元组,如下所示:
$ zentool print --disassemble modified.bin
; Patch 0x8600141 OpQuad Disassembly (64 total)
; (use --verbose to see further details)
.quad 2, 0x04021ff3
shr reg12, reg12, reg11
mov.b reg10, reg10, reg17
nop.q
nop.q
.quad 4, 0x00221ffa
mov reg9, reg9, 0x0006
ld vs:[reg9+reg1], reg0
ld.w reg9, 1:[reg1+reg1]
sreg.w reg9, reg9, reg1
.quad 5, 0x00400001
mov reg9, reg9, 0x1ff0
sreg.w reg9, reg9, reg1
mov reg9, reg9, 0x0305
nop.q
补丁指令
edit
命令可用于替换指令,从而有效地创建自定义微代码补丁。 一般格式为 --insn range=op
。 range
可以使用与匹配寄存器相同的格式指定(参见上文)。
注意:你也可以使用语法
q3i1
来引用 quad 3, instruction 1
op
是一个数值常量,或一个符号指令。
例如:
$ zentool edit --insn q0i0="xor rax, rax, rax" modified.bin
这将把第一个四元组的第一个指令设置为 xor rax, rax, rax
。
还有一个特殊的快捷方式 --nop
,它将使指定的指令成为空操作。
把它们放在一起,下面是一个使 fpatan
指令在 rax
中放入一个常量的命令:
$ zentool edit --nop all \
--match all=0 \
--match 0,1=@fpatan \
--seq 0,1=7 \
--insn q1i0="xor rax, rax, rax" \
--insn q1i1="add rax, rax, 0x1337" \
--hdr-revlow 0xff \
modified.bin
当然,你还需要签署该文件然后加载它:
$ zentool resign modified.bin
$ sudo zentool load --cpu=2 modified.bin
然后你可以尝试使用 gcc 执行 fpatan
(例如 asm volatile ("fpatan" : "=a"(result))
)
注意:记住使用
taskset
选择具有新微代码的内核! 例如,taskset -c 2 ./a.out
。
反汇编
你已经看到 print
命令包含一个反汇编程序,但是你可能会发现简单的 mcop
实用程序更方便调试。
你只需给它一个十六进制的操作码,它就会描述每一位:
$ ./mcop 382E9C1108081337
; 382E9C1108081337 0011100000101110100111000001000100001000000010000001001100110111
; .imm16 : 1337 0001001100110111
; .isig : 0 0
; .mode3 : 1 1
; .reg0 : 0 00000
; .reg1 : 2 00010
; .reg2 : 2 00010
; .rmod : 1 1
; .cc : 0 0000
; .ss : 0 0
; .size : 3 11
; .sizemsb : 1 1
; .pada : 0 00
; .type : 5D 01011101
; .ext : 0 0000
; .class : 7 111
add rax, rax, 0x1337
此外,mcop
可以为你更改命名字段:
$ ./mcop --set type=0x41 --set reg2=2 0x382E9C1108081337
汇编
mcop
命令的逆运算是 mcas
:
$ ./mcas "ld ls:[rax], rsi"
; 204BDC3188009800 0010000001001011110111000011000110001000000000001001100000000000
; .imm : 0 0000000000
; .segment : 6 0110
; .unkn1 : 0 0
; .nop3 : 1 1
; .unkn2 : 0 0
; .mode : 0 00
; .wordsz : 0 0
; .unknf : 0 0
; .reg0 : 0 00000
; .reg1 : 2 00010
; .reg2 : 3 00011
; .rmod : 1 1
; .op3 : 1 1
; .unkn6 : 0 0000
; .size : 3 11
; .width : 1 1
; .ldst : 0 0
; .unkn3 : 2F 101111
; .unknx : 4 100
; .type : 0 0000
; .class : 4 100
ld [rax], rsi
mcas
命令也可以接受来自 stdin 的指令。
开发
有几个脚本用于添加对新处理器的支持。
TODO: 描述
作者
该工具基于 Google 硬件安全团队成员的工作构建。 特别是,Josh Eads、Matteo Rizzo、Kristoffer Janke、Eduardo Vela Nava、Tavis Ormandy、Sophie Schmieg 等人。 这项工作还受到了《高性能微处理器解剖》一书(ISBN 0818684003)以及 Ruhr-Univeritat Bochum 研究人员 Koppe 等人在论文《逆向工程 x86 处理器微代码》中的工作的影响。