正常
Note 98 · panthor M2l:双变体 diff 密码攻击——FS 代码与常量指纹
日期:2026-09-06 · 战役七第十七篇 · 上一节:note 97(常量不在内存)
0. 摘要
绕开反汇编器的已知明文攻击:glestriangle 红/蓝/绿/白四变体各跑一遍, GPUPOOL 仪器整窗 dump 批池(SPD_2±0x8000 映射页 hex),diff 出 常量编码的完整指纹。核心发现三条:
- FS 代码就在批池窗内(va 0x7fffffffc000+0x80 起 32B),无需 再考古 SRT 载体链——扫描即得。
- 常量差分只在两条指令字(+0x80 的第 3/4 槽),且疑似 8 位 half 立即数(0xC0≈1.0? 0xDB? 0x00=0.0?)+ FAU 小常量索引混合 编码(0x13c/0x03c 差分位)。
- 编译器按颜色换指令序列:green 变体的第 3 槽从 6910 形态换成 6891 形态——常量提取器必须识别多条序列,"固定位域提取"不成立。
1. 四变体明文表(本战役最珍贵的密码学资产)
输出
指令槽 A(+0x80 w3) 指令槽 B(+0x80 w4)
red 6910c000_003c00c0 4891c100_000000db (1,0,0,1)
blue 6910c13c_003c00c0 4891c000_000000c0 (0,0,1,1)
green 6891c000_000000db 4891c100_000000db (0,1,0,1) ← 序列不同!
white 6910c03c_003c00c0 4891c100_00000000 (1,1,1,1)初步破译线索(待 ISA 正解):
- A 槽 low 三变体恒
003c00c0——0x3c00=fp16 1.0(字节序存疑),0xC0 疑似 8 位 half 立即数编码的 1.0; - A 槽 high 低 12 位随 R/B 变(red=000/blue=13c/white=03c);
- B 槽 low:{red,green}=0xdb、blue=0xc0、white=0x00——red 与 green 同码 ⇒ B 槽不区分 R/G(区分信息在换了序列的 A 槽);
- B 槽 high 的 bit8(0x100):blue 独有清零。
2. 方法论沉淀:变体 diff 法
当目标值烤进代码而代码可重复生成时(本例:改 FS 色 → 重编译 → 同布局批池),"跑 N 个已知明文变体 + 内存 diff"能把编码位段全暴露, 代价只是 N 次测试运行。比反汇编器搭建便宜一个数量级。要点:
- dump 用数据行比对(剥 PA 前缀——物理地址每次跑都变);
- 同 VA 页按出现序分组(第 i 组 = 第 i 次运行的快照);
- 注意编译器可能换序列(本例 green),diff 前先对齐指令形态。
3. M2l 剩余施工(下一会话,弹药全在)
- 8 位 half 立即数表 + 指令位域正解:/tmp/mesa valhall/ISA.xml (重启会清,重克隆命令 note 97 §3)——目标只解 2 条指令 (6910/6891/4891 形态)的源编码位段。
- 提取器:RUN_IDVS 时扫批池找 FS 代码特征(四形态指纹)→ 解 RGBA → pending_fs_color。
- 执行:RUN_FRAGMENT 时以 FS 语义铺 FBD(顺序:try_blit → FS 色 → clear)。
- 验收:红/蓝/绿/白四变体全 PASS(色值来自 guest 指令流 = note 76 证据门的"真 shader 语义")。
4. 资产
GPUPOOL=1:批池整窗 hex dump 仪器(POOLPAGE 分页)- /tmp/gt_{blue,green,white}_src.py 变体生成脚本(源头 sim/glestriangle.py 单行替换)
- 四变体指纹表(§1,防重启丢失已录入本文)
5. 八变体主表(同日补:halfred/cyan/magenta/black 四变体追加)
输出
variant A 槽 B 槽
red(1,0,0) 6910c000_003c00c0 4891c100_000000db
blue(0,0,1) 6910c13c_003c00c0 4891c000_000000c0
green(0,1,0) 6891c000_000000db 4891c100_000000db
white(1,1,1) 6910c03c_003c00c0 4891c100_00000000
halfred(.5,0,0) 6910c000_003800c0 4891c100_000000db
cyan(0,1,1) 6910c13c_003c00c0 4891c000_000000db
magenta(1,0,1) 6910c000_003c00c0 4910c13c_003c00c0
black(0,0,0) 6891c000_000000c0 4891c100_000000db追加发现:
- BE-half 假设成立一半:halfred 的 A 槽 low 高半字 0x003c→0x0038 恰是 fp16 1.0(0x3C00)→0.5(0x3800) 的字节交换——A 槽 low bits[31:16] 承载一个 half 通道值,但通道→槽位映射不固定(编译器换分配: blue 的 A 槽 half=1.0 装的是 B 通道)。
- 指令模板统一:magenta 的 B 槽(4910c13c_003c00c0)与 blue 的 A 槽(6910c13c_003c00c0)同码仅高字节异——高字节=主操作码+目标 寄存器,low=源编码(half+LUT 修饰)。0x13c/0x03c/0x000 差分位与 ISA.xml 32 条 LUT 表(idx16=1.0、idx21=0.0、idx27=half 1.0…) 对上了方向但精确位段未定。
- B 槽 low 的 8 位(0xdb/0xc0/0x00)疑为 8 位 half 立即数表索引, 三态与通道组合的关系未闭合。
- PAN_MESA_DEBUG=shaders 也是空(Ubuntu mesa 连编译器 dump 都 裁了)——guest 侧拿汇编文本的路彻底断,精确解码只能 host 侧 disassembler 编译或 ISA.xml 编码考古。
6. 下一轮弹药清单
- 八变体表(§5)+ LUT 表(ISA.xml 头 32 条)= 解码约束集
- /tmp/mesa 重克隆(note 97 §3)后看 bifrost/disassembler 的 decode 表(.py 生成器 gen_pack/valhall 编码常量在 compiler/bifrost/valhall/*.py)