SlimeASM-rev — Linux ELF x86_64 binary → ASM + C 逆変換
tag 無しバイト列の native ELF を、NASM ソースと C ソースに bit-exact で復元。
銀行・防衛・組込で「source-lost / vendor-lost」となった Linux x86_64 native binary を、
NASM intel ソース + C ソースの双方 に bit-exact で逆変換します。
出力 NASM は nasm + ld で再 assemble して原 binary と同じ動作を、
出力 C は gcc -O0 -nostdlib -static で本物の native ELF を生成して同じ動作を、
それぞれ 実機で再生成 + 実行 + stdout 完全一致 という最も厳しい round-trip 軸で証明します。
- Phase A: ELF64 minimal parser + x86_64 命令デコーダ (整数 hot-loop subset 約 14 種) + NASM intel emitter + 直線 C emitter
- Phase B 入口: CFG 復元 (Cooper-Harvey-Kennedy iterative dominator + Aho/Sethi natural loop body) + 構造化 C (
do { ... } while (R[1] != 0);+if/elsediamond) - Phase B (b): 関数境界復元 (prologue/epilogue + call/ret + 自己再帰)。各関数を独立 C function として emit、call → C 呼出、ret → return; に翻訳
- Phase B (d): inter-procedural Slot IR — 関数 = Slot ノード、call graph を first-class IR edge として昇華、JSON deterministic round-trip、自己再帰も自然表現
- S9 bench で 全 8 軸 64/64 PASS(2026-05-11 実測)、再帰 fact(4) = 24 含む 8 sample で ASM/C 両方の round-trip 全 PASS
銀行 IBM Linux x86_64 / 防衛 ELF binary 系の 「source 喪失 native binary」 を、
決定論的変換 + 8 軸 round-trip 自動回帰 + 監査 chain で扱う逆変換器。
SlimeNENC ファミリーで初めての 逆方向 製品 — 既存の forward 系 (COBOL/HLASM/MASM/MUMPS/PL/I/RPG/FORTRAN/Natural) と対をなします。
主要計測値 (2026-05-11 実測)
= ALL AXES PASS (Phase A + B 入口 + (b) + (d))
NASM emit → nasm + ld → 実行 → 原 ELF と stdout 完全一致
C emit → gcc -nostdlib -static → 実行 → 原 ELF と stdout 完全一致
CFG 復元 + do-while/if-else + 関数単位 → gcc → 実行 → 一致
ASM (NASM 経由) + C (GCC 経由)、両方とも実 ELF + 実行検証
call graph を first-class edge、自己再帰自然表現
市場文脈 — source 喪失 native binary が残る場所
| 銀行 (Linux x86_64) | 移行プロジェクトで「source code が見つからない / 保守ベンダー消滅」した native ELF / .so library。Heirloom / Astadia 等は HLASM mainframe 専門で Linux native binary は対象外。 |
|---|---|
| 防衛・宇宙 | 10-30 年無修正の closed binary (組込 Linux ELF / 計測機 daemon)。発注元から source 提供を受けられないが C ソース化 + 監査 chain が要求される。 |
| 組込・医療機器 | FDA / PMDA / IEC 62304 認証で「ソフトウェアの完全な記述」が義務化されている領域。binary しかないコンポーネントを C 化して 監査人が再現可能なドキュメント に。 |
| レガシー documentation | 「動いているが誰も触れない」 daemon を C 化して static analysis / SBOM / CVE 監査の対象に。 |
| 競合状況 | Ghidra (NSA OSS) / IDA Pro / Hex-Rays / RetDec などが既存。SlimeASM-rev は 決定論 + 5 軸 round-trip 自動回帰 で「変換が情報を捨てていない」ことを bench harness で証明する点が差別化軸。 |
S9 bench 全 8 軸 (8 sample 全 PASS)
| 軸 1a dialect-detect | ELF magic + ELFCLASS64 + EM_X86_64 (e_machine = 0x3E) を tokenizer が認識。8/8 PASS。 |
|---|---|
| 軸 1b opcode-recover | .text セクション全 177 命令 (8 sample 計) で db 0xNN fallback ゼロ。8/8 PASS。 |
| 軸 2 mutation-detect | .text 1 bit 反転 5 trial × 8 sample = 40 trial、40/40 全検出。disasm 出力に必ず差分が出る不変条件。 |
| 軸 3 determinism | NASM 出力を 2 回 emit して byte-equal を全 8 sample で確認。8/8 PASS。 |
| 軸 4 ASM round-trip | emit NASM → nasm + ld → 実行 → 原 ELF と stdout 完全一致。実 native binary を 2 系統 (オリジナル / 我々が再生成) で実行して比較する最も厳しい軸。8/8 PASS (再帰 fact(4) = 24 含む)。 |
| 軸 5 C round-trip | emit C → gcc -O0 -nostdlib -static → 実行 → 原 ELF と stdout 完全一致。直線 PC dispatch + STK 経由で call/ret/push/pop も bit-faithful。8/8 PASS。 |
| 軸 6 構造化 C round-trip | CFG 復元 + 構造化 C (do-while + if/else + 関数単位 + call → C call + ret → return;) → gcc → 実行 → stdout 完全一致。8/8 PASS。 |
| 軸 7 Slot IR round-trip | SlotImage → JSON → SlotImage → 構造的 equality + JSON byte-equal の二重チェック。関数 = Slot ノード、call graph も含めて完全保持。8/8 PASS。 |
サンプル一覧 (8 本、すべて NASM 直書き → ELF)
| 01 hello | syscall write で "Hello, ELF!\n" 出力。1 BB / 8 命令の最小 ELF。 |
|---|---|
| 02 arith | 17 + 25 = 42 を 2 桁 ASCII で出力。idiv + add al + mov [rip+disp] 等。 |
| 03 loop | loop sum_loop 命令で 1+2+3+4+5 = 15。CFG に back edge、構造化 C は do { ... } while (R[1] != 0); で復元。 |
| 04 branch | cmp + jge diamond。構造化 C は if (cond) { ... } else { ... } で復元、共通 join BB に合流。 |
| 05 compute | imul rax, rbx で 6 × 7 = 42。 |
| 06 call_simple | _start → do_print。prologue (push rbp; mov rbp, rsp) + epilogue (pop rbp; ret) を関数境界として認識、独立 C function に分離。 |
| 07 two_funcs | 3 関数 (_start → add_two + print_dec)。call graph に 2 inter-procedural edge。 |
| 08 recursion | factorial(4) = 24 を自己再帰で計算。call graph に self-loop edge (fact → fact)、push rbx / pop rbx で caller-saved spill を STK[] 経由で bit-faithful 保持。 |
変換例 1 — ループの構造化 C 復元 (sample 03)
原 NASM の loop sum_loop 命令で 1+2+3+4+5 を計算する自己ループ。CFG に back edge が現れ、SlimeASM-rev は natural loop body 検出 + 単一 BB self-loop with `loop` 命令 → do { ... } while (R[1] != 0); パターンで構造化 C を復元します:
; Original NASM (sample 03, ループ部のみ抜粋)
xor rax, rax
mov rcx, 5
sum_loop:
add rax, rcx
loop sum_loop ; dec rcx; jnz sum_loop
// SlimeASM-rev 復元 C (構造化)
R[0] = R[0] ^ R[0]; // xor rax, rax
R[1] = 0x5; // mov rcx, 5
do {
R[0] = R[0] + R[1]; // add rax, rcx
/* e2 fb loop sum_loop (terminator absorbed) */
R[1] = R[1] - 1;
} while (R[1] != 0);
loop 命令の back edge を Cooper-Harvey-Kennedy iterative dominator が検出、Aho/Sethi natural loop body 解析が単一 BB self-loop と認識し、構造化 do-while で復元 — goto 不要。
変換例 2 — if/else 分岐の構造化 C 復元 (sample 04)
原 NASM の cmp + jge で分岐し、両 arm が共通 join BB に合流する diamond パターン。SlimeASM-rev は cond BB + 2 succs → 共通 join → if (cond) { ... } else { ... } として構造化:
; Original NASM (sample 04, 分岐部)
mov rax, 7
cmp rax, 5
jge is_big
; small branch
... write "small\n" ...
jmp done
is_big:
... write "big\n" ...
done:
... exit ...
// SlimeASM-rev 復元 C (構造化、共通 join に合流)
R[0] = 0x7; // mov rax, 7
{ int64_t _diff = (int64_t)R[0] - (int64_t)5;
ZF = (_diff == 0); SF = (_diff < 0); }
OF = 0;
/* 7d 1a jge is_big (terminator absorbed) */
if (SF == OF) { // jge 条件
/* big arm */
... write "big\n" ...
} else {
/* small arm */
... write "small\n" ...
}
/* done: 共通 join BB → exit */
diamond 検出は intra-function dominator + post-dominator 同居判定。jmp による合流は emitter 側で吸収、goto 不要で純粋な C if/else に復元。
変換例 3 — 関数単位 + 自己再帰のショーケース (sample 08)
factorial(4) = 24 を自己再帰で計算する 6 BB の関数。CFG 的に純粋なループでも単純 diamond でもない (cond + 各 arm が独立 ret) ため、構造化 C 内には goto BB_xxxx; ラベル参照が残りますが、これは 関数境界復元 + call → C call + ret → return; + caller-saved spill (push rbx / pop rbx) を STK[] 経由で bit-faithful 保持 + 自己再帰 の同梱ショーケースとして掲載:
; Original NASM (sample 08, fact 関数)
fact:
push rbp
mov rbp, rsp
cmp rbx, 1
jg recurse
mov rax, 1 ; base: 1! = 1
pop rbp
ret
recurse:
push rbx ; spill rbx across recursive call
sub rbx, 1
call fact ; rax := (rbx-1)!
pop rbx ; restore rbx
imul rax, rbx ; rax := rbx * (rbx-1)!
pop rbp
ret
// SlimeASM-rev 復元 C (関数単位、自己再帰、caller-saved spill 保持)
static void func_401060(void) { // fact()
BB_401060:;
STK[--RSP_IDX] = R[5]; // push rbp
R[5] = R[4]; // mov rbp, rsp
/* cmp rbx, 1 */
if (ZF == 0 && SF == OF) goto BB_401071; // jg recurse
BB_40106a:;
R[0] = 1; // mov rax, 1
R[5] = STK[RSP_IDX++]; // pop rbp
return; // ret → C return
BB_401071:;
STK[--RSP_IDX] = R[3]; // push rbx
R[3] -= 1; // sub rbx, 1
func_401060(); // call fact → C 呼出 (自己再帰)
R[3] = STK[RSP_IDX++]; // pop rbx
R[0] = R[0] * R[3]; // imul rax, rbx
R[5] = STK[RSP_IDX++]; // pop rbp
return;
}
この C を gcc -O0 -nostdlib -static でコンパイルして実行すると、原 ELF と 同じ stdout (FACT=24) を出力 — 軸 6 構造化 C round-trip PASS。複雑 CFG (cond + 各 arm 独立終端) は Phase B 残工程の多 BB ループ + tail duplication 拡張で goto 排除予定。
関数 = Slot ノード、call graph IR 昇華 (Phase B (d))
SlimeNENC ファミリー共通の Slot IR (Core64 + Ext32 固定 bit、請求項 11) を逆方向にも適用。各関数が SlotFunction ノードとして第一級オブジェクトになり、call edges も first-class IR 構造 として保持されます (callee 関数名のリスト)。自己再帰も自然に self-loop edge として表現:
| sample | functions | call edges |
|---|---|---|
| 01-05 (linear) | 1 | 0 |
| 06 call_simple | 2 | 1 (_start → func_40100f) |
| 07 two_funcs | 3 | 2 (_start → func_401014, _start → func_401027) |
| 08 recursion | 2 | 2 (_start → func_401060, func_401060 → func_401060) |
SlotImage 全体は deterministic な JSON に encode/decode 可能 (軸 7 round-trip)。これにより、call graph と関数構造を保持したまま 外部ツールチェーン (audit DB / SBOM / static analysis) と連携 できます。
監査適合性 (金融・防衛・医療機器)
- Bit-exact同一 ELF 入力 → 同一 sha256 NASM/C 出力。CFG / 関数境界 / 命令列すべて含めて完全決定論。
- Native ELF round-trip出力 NASM を nasm + ld で再 assemble、出力 C を gcc -nostdlib で compile、2 系統の native ELF を実行して原 binary と stdout 完全一致。シミュレーションでなく実機検証。
- Mutation 検出.text 1 bit 反転で disasm が必ず差分を出す。8 sample × 5 trial = 40/40 検出、改ざん即発覚。
- 決定論同一 ELF を 2 回 disasm + emit → byte-equal を毎 sample で確認。並列実行・GPU 環境でも結果がブレない。
- Slot IR audit関数 = Slot ノード、call graph も保持して JSON で外部に永続化可能。SBOM / 監査 DB との結合点。
- Build-time LLMLLM は decoder rule の構築段階のみ。ランタイムは決定論ルールベース、銀行・防衛 audit 要件に整合。
サポート命令カバレッジ (Phase A、整数 hot-loop subset 約 14 種)
| データ移動 | mov reg, imm/reg (B8+r / 89 /r / C7 /0 / 88 /r) / lea reg, [rip+disp32] (8D /r mod=00 r/m=101) |
|---|---|
| 算術 | add r/m64, r64 (01 /r) / add al, imm8 (04) / add r/m8, imm8 (80 /0) / sub r/m64, imm8 (83 /5) / imul r64, r/m64 (REX.W 0F AF) / idiv r/m64 (F7 /7) |
| 論理 | xor r/m64, r64 (31 /r、idiom xor reg, reg はゼロ初期化として認識) |
| 比較 | cmp r/m64, r64 (39 /r) / cmp r/m64, imm8 (83 /7) |
| 分岐 | Jcc rel8 (70-7F、je/jne/jge/jg/jl/jle/...) / Jcc rel32 (0F 80-8F) / jmp rel8/32 (EB/E9) / loop rel8 (E2) |
| 呼出 | call rel32 (E8) / ret (C3) / push/pop r64 (50-5F) / push imm (6A/68) |
| システム | syscall (0F 05) — sys_write (rax=1) / sys_exit (rax=60) を heuristic 認識 |
Phase B 以降で multi-BB loop / loop nest tree、libc-linked binary (printf/malloc 等、PLT/GOT 動的リンク)、SSE2/SSE4 (XMM レジスタ) 対応を順次拡張予定。30+ sample / `gcc -O0` でビルドした C ソースから出発し reverse → C 出力が原 C と意味同等を本番ベンチ化します。
License モデル
| 課金対象 | WASM/WASI converter ツール (開発者側) |
|---|---|
| 非課金 | 変換結果の NASM / C ソース (顧客資産、永久無償デプロイ) |
| 方式 | Ed25519 署名 144B license + 3-hop air-gap activation (金融・防衛 audit 対応) |
| 並列化 (PSDP) | 本製品には含まれません。SlimeNENC 配下の独立 SKU として PSDP を別途。 |
関連資料
- 技術解説SlimeNENC Technical Overview (逆方向 ASM/C 章を準備中)
- 出願明細特願 2026-046620 v15b の請求項 11 / 14d で COBOL / MUMPS / PL/I / RPG / アセンブラ / native binary 逆方向等のレガシー方言処理を明示射程化
- 兄弟製品 (forward 系対)SlimeASM (HLASM + Win x64 MASM forward) と対 — forward + reverse の双方向で SlimeNENC ファミリーが native コード領域を完全カバー
- 兄弟製品 (Slot IR 共有)SlimeCOBOL / SlimePL/I / SlimeRPG / SlimeMUMPS と Slot IR (Core64+Ext32 固定 bit) を共有
- ベンチマークS9 bench harness (8 軸 correctness)、`s9_bench/bench.py` で 8 sample × 8 軸 = 64/64 自動回帰
逆変換 PoC・資料請求 SlimeNENC ファミリーへ戻る SlimeASM (forward 対) を見る SlimeCOBOL を見る
