
Eine sitzungseinmalige RISC-V ISA — jeder Boot spricht einen anderen Dialekt. Alte Binärdateien werden ungültig. Malware kann nicht bestehen.
Jeder Systemstart spricht eine andere Sprache. Die Binärdatei von gestern ist der tote Code von heute.
Ein sitzungs-eindeutiges RISC-V-ISA-Umordnungssystem. Bei jedem Systemstart wird eine neue kryptografische Permutation des Befehlssatzes erzeugt. Für eine Sitzung kompilierte Binärdateien werden in der nächsten kryptografisch abgelehnt. Schadsoftware, die einen Neustart überlebt, kann nicht ausgeführt werden – sie spricht einen toten Dialekt.
Standard-ISAs sind feste Verträge. Jedes Programm, jede Bibliothek, jedes Stück Schadsoftware stimmt darin überein, was 0x13 bedeutet, was der Syscall 64 tut, welches Register der Stack-Pointer ist. DeadDialect bricht diesen Vertrag bei jeder Sitzung.
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
Eine für Boot A kompilierte Binärdatei ist auf Boot B sinnlos. Sie führt entweder die falschen Befehle aus, ruft die falschen Kernel-Funktionen auf oder besteht die kryptografische Fingerabdruck-Prüfung nicht – je nachdem, was zuerst eintritt.
256-Bit-Sitzungs-Seed (os.urandom)
│
├─── Opcode-Permutation → /etc/isa/map 12! ≈ 2²⁹
├─── Register-Permutation → /etc/isa/register_keyring 21! ≈ 2⁶⁵
└─── Syscall-Permutation → /etc/isa/syscall_keyring 436! ≈ 2³⁰⁰⁰⁺
─────────────
Kombinierte Entropie: 2³⁰⁹⁴⁺
Drei unabhängige Schichten. Ein Angreifer, der eine bricht, steht immer noch vor den anderen beiden.
┌──────────────────────────────────────────────────────────────┐
│ Binärdatei (.text) │
│ zur Compilezeit von isa_integrate.py umgeschrieben │
│ Fingerabdruck-NOPs eingebettet bei .text+0 │
└─────────────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────┐
│ Gepatchter QEMU 8.2.0 │
│ │
│ translate.c ← register_mapping.h │
│ ├── 24-Bit-SHA-256-Fingerabdruck prüfen │
│ │ Nichtübereinstimmung → SIGILL vor erstem Befehl │
│ └── 21 mischbare Register umordnen │
│ │
│ syscall.c ← syscall_mapping.h │
│ └── permutierte Syscall-Nummer → Standard übersetzen │
│ │
│ [Phase 1/2] ← isa_mapping.h │
│ └── 12 primäre Opcodes umordnen │
└──────────────────────────┬───────────────────────────────────┘
│
▼
Alpine Linux RISC-V (startet normal)
Das BS ist sich der Umordnung nicht bewusst
Jede kompilierte Binärdatei trägt einen 24-Bit-kryptografischen Fingerabdruck, eingebettet als zwei harmlose addi x0,x0,N-NOPs am Anfang von .text. Dies sind echte RISC-V-NOPs – sie schreiben in das Nullregister und haben keinen architektonischen Effekt – aber sie kodieren den Sitzungsnachweis.
QEMU sieht Fingerabdruck-NOPs + passenden Keyring → AUSFÜHREN
QEMU sieht Fingerabdruck-NOPs + falschen Keyring → SIGILL
QEMU sieht keinen Fingerabdruck + aktiven Keyring → SIGILL ← Standard-Binärdatei blockiert
QEMU sieht Fingerabdruck-NOPs + leeren Keyring → SIGILL ← umgeordnete Binärdatei blockiert
Der Fingerabdruck wird abgeleitet von SHA-256(Seed). Keine Kollisionen in den ersten 100.000 getesteten Seeds gefunden.
DeadDialect/
├── opcode-remapping/ Phase 1 — 12 Opcodes mischen
├── trigger-remapping/ Phase 2 — Live-Trigger, kein Neustart nötig
│ └── alpine/ Alpine Linux Demo
├── syscall-remapping/ Phase 3 M1 — 436 Syscalls mischen
├── register-remapping/ Phase 3 M2 — 21 Register mischen + Fingerabdruck
└── integration/ Phase 3 M3 — alle Schichten gleichzeitig
├── isa_integrate.py einheitlicher Umschreiber
├── register_mapping.h
├── syscall_mapping.h
├── isa_remap_ldso.h musl ld.so-Patch (dynamische Binärdateien)
├── trigger/
│ └── trigger_demo.sh Ein Trigger dreht beide Schichten atomar
├── alpine/
│ ├── boot_alpine.sh Alpine unter gepatchtem QEMU starten
│ ├── alpine_demo.sh Vollständige ISA-Demo innerhalb von Alpine
│ ├── full_alpine_test.sh
│ └── setup_alpine.sh Einrichtung einer neuen Maschine
├── build.sh Lädt QEMU 8.2.0 herunter + patcht
├── demo.sh
└── audit.sh 51/51 Prüfungen
Voraussetzungen: 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
# Gepatchten QEMU 8.2.0 bauen (~10 Min. beim ersten Mal)
bash build.sh
# Sicherheitsdemo
bash demo.sh
# Ein Trigger dreht beide Schichten gleichzeitig
bash trigger/trigger_demo.sh
# Alpine Linux unter gepatchtem QEMU starten
cd alpine
bash setup_alpine.sh # nur beim ersten Mal – lädt Kernel + rootfs herunter
bash boot_alpine.sh # startet in ~30 Sek. zur ~ # Eingabeaufforderung
# Alpine ISA-Demos
bash alpine_demo.sh
bash full_alpine_test.sh
T1: Standard-Binärdatei, leere Keyrings → läuft ✓
T2: Integrierte Binärdatei, korrekte Keyrings → läuft ✓
T3: Standard-Binärdatei, aktive Keyrings → SIGILL ✗
T4: Integrierte Binärdatei, leere Keyrings → SIGILL ✗
T5: Binärdatei mit falschem Seed → SIGILL ✗
T6: Binärdatei mit korrektem Seed → läuft ✓
Sitzung A Binärdatei läuft ERFOLG ✓
Sitzung A Schadsoftware läuft AUSGEFÜHRT (erwartet – gleiche Sitzung)
── Trigger wird ausgelöst ──
Sitzung B alte Binärdatei BLOCKIERT ✓
Sitzung B Schadsoftware BLOCKIERT ✓
Sitzung B neue Binärdatei für B kompiliert ERFOLG ✓
100.000 Seeds – null Kollisionen
Seed 999999999 → BLOCKIERT unter anderer Sitzung ✓
Seed 2²⁵⁶-1 (max. 256-Bit) → BLOCKIERT unter anderer Sitzung ✓
Keyring während der Laufzeit korrumpiert → BLOCKIERT bei korruptem Keyring ✓
| Meilenstein |
|---|
Register-Permutation erraten: 1 zu 21! ≈ 1 zu 51 Trillionen
Syscall-Permutation erraten: 1 zu 436! ≈ 1 zu 10^(1000+)
Beide gleichzeitig erraten: kein praktikabler Angriff
-march=rv64g erforderlich (RVC-komprimierte Befehle werden noch nicht behandelt)isa_remap_ldso.h)register_mapping.h)21 von 32 RISC-V-Registern werden gemischt. ABI-Register sind eingefroren. QEMU-Hook verwendet OPCODE_FIELDS-Tabelle – nur tatsächliche Registerfelder werden umgeordnet, Immediate werden nie angefasst (Curtis' Fix).
| Eingefroren | Mischbar |
|---|---|
| x0 x1 x2 x10-x17 | x3-x9, x18-x31 (21 Register) |
syscall_mapping.h)436 Linux RISC-V-Syscalls werden permutiert. Eine Zeile in do_syscall(). mtime-Reload – Keyring-Updates ohne QEMU-Neustart.
isa_mapping.h)12 primäre Opcodes werden gemischt. Decode-Hook in translate.c stellt den Standard-Opcode vor dem Decoder wieder her.
isa_remap_ldso.h)musl-Dynamic-Linker-Patch – ordnet beim Laden den .text jedes geladenen ELF um. Kann nicht über LD_PRELOAD umgangen werden. Erfordert Neukompilierung von Alpine musl.
.text-Umordnung vor dem BootenCurtis Cole
Muhammad Bilal
"Ich wusste, dass meine Idee real war, aber ich bin mir ziemlich sicher, dass alle dachten, ich wäre verrückt." — Curtis Cole
| Prüfungen |
|---|
| Status |
|---|
| Trigger-Umordnung | 37/37 | ✓ |
| Syscall-Umordnung | 40/40 | ✓ |
| Register-Umordnung | 43/43 | ✓ |
| Integration | 51/51 | ✓ |