
AMD navi31(RX 7900)GPU向けのPSPエクスプロイトで、ファームウェアの署名チェックを無効化し、カードが署名なしのSMU、SDMA、MEC、IMU、RLCファームウェアを読み込めるようにします。コールドブート後は永続しません。
AMD navi31 カード(RX 7900 シリーズ)向けの PSP(Platform Security Processor)エクスプロイト。 隣接する他の製品ファミリーにも適応できる可能性が高い。
これは PSP のファームウェア署名チェックを無効化するため、カードは本来なら拒否する 署名されていない IP ファームウェア(SMU、SDMA、MEC、IMU、RLC)をロードするようになる。 カスタムの電力管理、クロック制限、あるいはベンダーが署名していてあなたがしていないファームウェアに存在するその他あらゆるものを考えてほしい。
何もフラッシュされない。パッチは PSP メモリ内に存在し、ウォームブート中に適用される。コールド電源サイクルでそれは消去され、カードは再び純正状態に戻る。そのウォームブートこそが「Wake and Break」である。カードが目を覚まし、我々はカードを説得して即座に本当にハイにさせ、署名チェックを無効化するよう強要する。:-)
RX 7900 XTX でカードテスト済み。Status を参照。
python3 wakebreak.py 25=/path/to/firmware.bin
これによりパッチが適用され、カードがウォームブートされ、イメージがファームウェアタイプ25として送信されます。accepted と表示されれば、PSPは通常なら拒否するはずのイメージを受け入れたことになります。
試すためのものが必要ですか?ipfw_images.py は、ドライバが実際にロードするファームウェアを一覧表示し、テスト用のペアを書き出します — 本物のイメージと、その署名の1ビットを反転させたコピーで、ファームウェア自体はバイト単位で同一です:
python3 ipfw_images.py # what does this card load?
python3 ipfw_images.py 25 # -> /tmp/fw_25_{ok,bad}.bin
python3 wakebreak.py 25=/tmp/fw_25_bad.bin
Stockファームウェアは fw_25_bad.bin を拒否します。パッチを適用すると、これが受け入れられます。
これがデモンストレーションのすべてです。
python3 -m venv venv
venv/bin/pip install -r requirements.txt
make verify # are the shipped artifacts intact?
make selftest # offline sanity checks, no card touched
tinygrad の AMD ドライバ(PCIe またはその USB ブリッジ)経由でカードにアクセスできる Linux ホストが必要です。ホストに必要な tinygrad パッチについては requirements.txt を参照してください。
既知の navi31 ファームウェアビルドは 4 種類あり、パッチはそれに一致する必要があります。プロファイル a がデフォルトで、最も一般的なものをカバーしています。カードの SPI フラッシュのダンプがある場合、identify.py がそれを判別します:
python3 identify.py FLASH.bin
# -> sos-build c: wakebreak.py --sos-build c
それ以外の場合は、ただ試してみてください。間違って推測しても無害です: パッチは変更しようとしている対象を確認し、認識できないものを見つけると何も書き込まず、カードは正常に起動します。
python3 wakebreak.py --sos-build c 25=/tmp/fw_25_bad.bin
テスト済みのカード(RX 7900 XTX、プロファイル a)で確認済み:
| 改ざんされたファームウェア、純正カード | 拒否 |
| 改ざんされたファームウェア、パッチ適用済み | 受理 |
| コールド電源サイクル後 | 再び拒否 — カードは純正状態 |
注記: プロファイル b、c、d はビルドおよびオフラインでのチェックは済んでいますが、ハードウェア上では一度も実行されていません。プロファイル b、c、d に一致するカードをお持ちの場合は、動作するかどうか報告してください!
パッチ自体は hook/*.S にある数百バイトの ARM アセンブリです。
ビルド済みの blob はリポジトリに同梱されているため、これを使用するのにクロスコンパイラは不要です。
それでも再ビルドしたい場合は:
make rebuild # needs arm-none-eabi binutils
make rebuild CROSS=/path/to/arm-none-eabi-
ビルドは、カード上でテストされたバイト列とハッシュが一致しないもののインストールを拒否するため、異なるツールチェーンがPSPに書き込まれる内容を密かに変更することはできません。
wakebreak.py the exploit
identify.py which --sos-build does this card need?
ipfw_images.py build a signed/tampered firmware pair to test with
selftest.py offline checks
hook/ the patch: ARM sources and built blobs
firmware/ two stock AMD firmware images the exploit needs to get in
firmware/ には、未改変のまま公開出荷された AMD のイメージが入っています。これらは古いバージョンですが、侵入経路がそれらを経由するため保持されています。
ここで意図的に説明していないこと: コードを読んでください。wakebreak.py はコメント付きの約600行で、コメントには仕組み、安全チェック、そして各ステップがその順序である理由が説明されています。TL;DR: AMD の純正トラステッドアプリケーションが2つロードされ、そのうちの1つが PSP メモリに書き込めるチェーンを実行するよう仕向けられ、パッチがブートローダーの常駐コピーに配置され、その後カードがそれへウォームブートされます。
MIT、LICENSE を参照してください。好きに使ってください。
この作品の制作には大規模な LLM の支援が使われました。だからといって、作者がここで実際に何が起きているのかを全く理解していないわけではありません。ここまで到達するだけでも 大量の 反論と手作業が伴いました。出来の悪い Python の産物などが気に入らないかもしれませんが、あなたの Navi31 カードが突然、署名されていないファームウェアコンポーネントのブロブをロードするようになったという事実には反論できないでしょう。ご清聴ありがとうございました。