
セッションごとに固有のRISC-V ISA — 起動するたびに異なる方言を話す。古いバイナリは無効になる。マルウェアは永続化できない。
すべてのブートが異なる言語を話す。昨日のバイナリは今日の死んだコードである。
セッション固有のRISC-V ISA再マッピングシステム。システムが起動するたびに、命令セットの新しい暗号学的置換を生成する。あるセッション用にコンパイルされたバイナリは、次のセッションでは暗号学的に拒否される。再起動後も生存するマルウェアは実行できない——死んだ方言を話すからだ。
標準ISAは固定された契約である。すべてのプログラム、すべてのライブラリ、すべてのマルウェアは、0x13が何を意味するか、syscall 64が何をするか、どのレジスタがスタックポインタかを合意している。DeadDialectは、その契約をセッションごとに破る。
Boot A: addi = 0x13, write = syscall 64, t0 = x5
Boot B: addi = 0x33, write = syscall 178, t0 = x19
Boot C: addi = 0x67, write = syscall 291, t0 = x23
Boot A用にコンパイルされたバイナリはBoot Bでは意味をなさない。誤った命令を実行するか、間違ったカーネル関数を呼び出すか、あるいは暗号学的フィンガープリントチェックに失敗する——最初に起こるものから順に。
256ビットのセッションシード (os.urandom)
│
├─── オペコード置換 → /etc/isa/map 12! ≈ 2²⁹
├─── レジスタ置換 → /etc/isa/register_keyring 21! ≈ 2⁶⁵
└─── システムコール置換 → /etc/isa/syscall_keyring 436! ≈ 2³⁰⁰⁰⁺
─────────────
複合エントロピー: 2³⁰⁹⁴⁺
3つの独立した層。攻撃者が1つを突破しても、残る2つに直面する。
┌──────────────────────────────────────────────────────────────┐
│ バイナリ (.text) │
│ isa_integrate.pyによりコンパイル時に書き換え │
│ フィンガープリントNOPが.text+0に埋め込まれる │
└─────────────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ パッチ適用済み QEMU 8.2.0 │
│ │
│ translate.c ← register_mapping.h │
│ ├── 24ビットSHA-256フィンガープリントの検証 │
│ │ 不一致 → 最初の命令の前にSIGILL │
│ └── シャッフル可能な21個のレジスタを再マッピング │
│ │
│ syscall.c ← syscall_mapping.h │
│ └── 置換されたシステムコール番号を標準に変換 │
│ │
│ [フェーズ1/2] ← isa_mapping.h │
│ └── 12個のプライマリオペコードを再マッピング │
└──────────────────────────┬───────────────────────────────────┘
│
▼
Alpine Linux RISC-V (通常通り起動)
OSは再マッピングに気付かない
コンパイルされたすべてのバイナリは、.textの先頭に2つの無害なaddi x0,x0,N NOPとして埋め込まれた24ビットの暗号学的フィンガープリントを持つ。これらは実際のRISC-V NOPであり、ゼロレジスタに書き込むためアーキテクチャ上の効果はないが、セッションの証明を符号化する。
QEMUがフィンガープリントNOP + 一致するキーリングを検出 → 実行
QEMUがフィンガープリントNOP + 間違ったキーリングを検出 → SIGILL
QEMUがフィンガープリントなし + アクティブなキーリングを検出 → SIGILL ← 標準バイナリがブロックされる
QEMUがフィンガープリントNOP + 空のキーリングを検出 → SIGILL ← 再マッピングされたバイナリがブロックされる
フィンガープリントはSHA-256(seed)から導出される。テストした最初の100,000シードでは衝突は見つかっていない。
DeadDialect/
├── opcode-remapping/ フェーズ1 — 12オペコードシャッフル
├── trigger-remapping/ フェーズ2 — ライブトリガー、再起動不要
│ └── alpine/ Alpine Linuxデモ
├── syscall-remapping/ フェーズ3 M1 — 436システムコールシャッフル
├── register-remapping/ フェーズ3 M2 — 21レジスタシャッフル + フィンガープリント
└── integration/ フェーズ3 M3 — すべての層を同時に
├── isa_integrate.py 統一リライター
├── register_mapping.h
├── syscall_mapping.h
├── isa_remap_ldso.h musl ld.soパッチ(動的バイナリ用)
├── trigger/
│ └── trigger_demo.sh 1つのトリガーで両方の層をアトミックにローテート
├── alpine/
│ ├── boot_alpine.sh パッチ適用済みQEMUでAlpineを起動
│ ├── alpine_demo.sh Alpine内部での完全なISAデモ
│ ├── full_alpine_test.sh
│ └── setup_alpine.sh 新しいマシンのセットアップ
├── build.sh QEMU 8.2.0をダウンロードしパッチ適用
├── demo.sh
└── audit.sh 51/51チェック
必要条件: Ubuntu 22.04, clang, lld, python3, wget, ninja-build, libglib2.0-dev, libpixman-1-dev, libslirp-dev
git clone https://github.com/engrbilal992/DeadDialect.git
cd DeadDialect/integration
# パッチ適用済みQEMU 8.2.0をビルド(初回は約10分)
bash build.sh
# セキュリティデモ
bash demo.sh
# 1つのトリガーで両方の層を同時にローテート
bash trigger/trigger_demo.sh
# パッチ適用済みQEMUでAlpine Linuxを起動
cd alpine
bash setup_alpine.sh # 初回のみ — カーネル+rootfsをダウンロード
bash boot_alpine.sh # 約30秒で ~ # プロンプトまで起動
# Alpine ISAデモ
bash alpine_demo.sh
bash full_alpine_test.sh
T1: 標準バイナリ、空のキーリング → 実行 ✓
T2: 統合バイナリ、正しいキーリング → 実行 ✓
T3: 標準バイナリ、アクティブなキーリング → SIGILL ✗
T4: 統合バイナリ、空のキーリング → SIGILL ✗
T5: 間違ったシードのバイナリ → SIGILL ✗
T6: 正しいシードのバイナリ → 実行 ✓
セッションA バイナリ実行 成功 ✓
セッションA マルウェア実行 実行済み(期待通り — 同じセッション)
── トリガー発動 ──
セッションB 古いバイナリ ブロック ✓
セッションB マルウェア ブロック ✓
セッションB B用にコンパイルされた新しいバイナリ 成功 ✓
100,000シード — 衝突ゼロ
シード999999999 → 異なるセッションでブロック ✓
シード2²⁵⁶-1(最大256ビット) → 異なるセッションでブロック ✓
実行中にキーリングが破損 → 破損したキーリングでブロック ✓
| マイルストーン | チェック数 | ステータス |
|---|
レジスタ置換の推測: 1/21! ≈ 1/51 京
システムコール置換の推測: 1/436! ≈ 1/10^(1000+)
両方を同時に推測: 実行可能な攻撃ではない
-march=rv64g必須(RVC圧縮命令は未対応)isa_remap_ldso.h経由)register_mapping.h)32個のRISC-Vレジスタのうち21個をシャッフル。ABIレジスタは固定。QEMUフックはOPCODE_FIELDSテーブルを使用——実際のレジスタフィールドのみ再マッピングし、即値は決して触らない(Curtisの修正)。
| 固定 | シャッフル可能 |
|---|---|
| x0 x1 x2 x10-x17 | x3-x9, x18-x31(21個) |
syscall_mapping.h)436個のLinux RISC-Vシステムコールを置換。do_syscall()内の1行。mtimeリロード——QEMU再起動なしでキーリング更新。
isa_mapping.h)12個のプライマリオペコードをシャッフル。translate.cのデコードフックがデコーダの前に標準オペコードを復元。
isa_remap_ldso.h)musl動的リンカパッチ——ロード時にすべてのELFの.textを再マッピング。LD_PRELOADでは回避不可。Alpine muslの再ビルドが必要。
.text再マッピングCurtis Cole
Muhammad Bilal
"自分のアイデアが本物だとわかっていたけど、周りはみんな僕が狂ってると思っていたんだろうな。" — Curtis Cole
| トリガー再マッピング | 37/37 | ✓ |
| システムコール再マッピング | 40/40 | ✓ |
| レジスタ再マッピング | 43/43 | ✓ |
| 統合 | 51/51 | ✓ |