
ARM64 ELF 仮想マシン保護システム
ARM64 ELF 仮想マシン保護システム
ARM64 ネイティブ命令をカスタム VM バイトコードに変換し、関数レベルのコード保護を実現します
🇨🇳 中文文档 • 機能 • アーキテクチャ • クイックスタート • 使い方 • ライセンス
VMPacker は、ARM64 (AArch64) Linux ELF バイナリ向けの 仮想マシン保護 (VMP) システムです。対象関数の ARM64 ネイティブ命令を中間表現にデコードし、カスタム VM バイトコードに変換して、ELF ファイル内に組み込み VM インタプリタを注入します。実行時、保護された関数はネイティブ実行ではなく VM インタプリタによって実行されます。
ARM64 ネイティブコード → デコード → 変換 → カスタム VM バイトコード
↓
元の ELF <-- 注入 <-- VM インタプリタスタブ
vmp/
├── cmd/vmpacker/ # CLI エントリポイント
│ ├── main.go # CLI 引数解析 + オーケストレーション
│ └── vm_interp.bin # コンパイル済み VM インタプリタ (GCC, go:embed)
│
├── pkg/ # Go コアライブラリ
│ ├── arch/arm64/ # ARM64 アーキテクチャサポート
│ │ ├── decoder.go # テーブル駆動型命令デコーダ (vm.Decoder を実装)
│ │ ├── decode_*.go # デコードパターンテーブル (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # ARM64 → VM バイトコード変換器
│ │ ├── tr_alu.go # ALU 命令変換
│ │ ├── tr_branch.go # 分岐命令変換
│ │ ├── tr_loadstore.go # メモリ命令変換
│ │ ├── tr_bitfield.go # ビットフィールド命令変換
│ │ └── tr_special.go # 特殊命令 (ADRP/ADR)
│ ├── vm/ # VM ISA 定義
│ │ ├── types.go # 共有型 + インターフェース (Decoder/Translator/Packer)
│ │ ├── opcodes.go # 58+ の VM オペコード定義 (ランダムマッピング値)
│ │ └── disasm.go # VM バイトコード逆アセンブラ
│ └── binary/elf/ # ELF バイナリ操作
│ ├── packer.go # ELF VMP 注入 (PT_NOTE ハイジャック、トランポリン生成)
│ └── trampoline.go # トランポリンコード生成
│
├── stub/ # C VM インタプリタ (PIC フラットバイナリにコンパイル)
│ ├── vm_interp_clean.c # インタプリタメインループ + エントリポイント
│ ├── vm_types.h # VM CPU コンテキスト (vm_ctx_t)
│ ├── vm_opcodes.h # C 側オペコード定義 (opcodes.go と同期)
│ ├── vm_decode.h # バイトコード読み取りユーティリティ
│ ├── vm_token.h # トークンエンコード/デコード + ディスクリプタテーブル
│ ├── vm_dispatch.h # 間接ディスパッチジャンプテーブル
│ ├── vm_crc.h # CRC32 整合性チェック
│ ├── vm_sections.h # ハンドラセクション散乱マクロ
│ ├── vm_interp.lds # リンカスクリプト
│ └── vm_handlers/ # モジュール式命令ハンドラ
│ ├── h_alu.h # 算術/論理演算
│ ├── h_mem.h # メモリアクセス
│ ├── h_branch.h # 分岐/ジャンプ
│ ├── h_cmp.h # 比較/条件
│ ├── h_mov.h # データ移動
│ ├── h_stack.h # スタック (PUSH/POP)
│ └── h_system.h # システム (SVC/MRS/BLR/BR/RET)
│
├── vmp-gui/ # Wails GUI フロントエンド
│ ├── frontend/ # Vue 3 + Element Plus
│ └── backend/ # Go バックエンドバインディング
│
└── build/ # プリコンパイル済みツール + テストアーティファクト
プロジェクトはインターフェース駆動型のモジュラーアーキテクチャを採用しており、新しい ISA やバイナリ形式への拡張が容易です。
// アーキテクチャデコーダインターフェース — x86、RISC-V に拡張可能
type Decoder interface {
Decode(raw uint32, offset int) Instruction
InstName(op int) string
}
// バイトコード変換器インターフェース
type Translator interface {
Translate(instructions []Instruction) (*TranslateResult, error)
}
// バイナリ形式インジェクタインターフェース — PE、Mach-O に拡張可能
type Packer interface {
Process() error
}
graph LR
A[入力 ELF] --> B[対象関数の特定]
B --> C[ARM64 命令の抽出]
C --> D[ARM64 デコード]
D --> E[VM バイトコードに変換]
E --> F[XOR 暗号化バイトコード]
F --> G[VM インタプリタ注入]
G --> H[トランポリン生成]
H --> I[関数エントリの置換]
I --> J[保護済み ELF 出力]git clone https://github.com/LeoChen-CoreMind/VMPacker.git
cd VMPacker
make all
# 単一関数の保護
./vmpacker -func check_license -v -o protected.elf original.elf
# 複数関数の保護
./vmpacker -func "check_license,verify_token" -v -o protected.elf original.elf
# アドレス範囲の指定
./vmpacker -addr "0x4006AC-0x400790:main" -v -o protected.elf original.elf
# 混合モード
./vmpacker -addr "0x4006AC-0x400790:main" -func verify -o protected.elf original.elf
./vmpacker -info input.elf
# 標準ビルド (GCC)
aarch64-linux-gnu-gcc -Os -nostdlib -fPIC -ffreestanding \
-o stub.elf stub/vm_interp_clean.c \
-T stub/vm_interp.lds
aarch64-linux-gnu-objcopy -O binary stub.elf vm_interp.bin
go build -o vmpacker ./cmd/vmpacker/
cd vmpacker
make gui
VMPacker は、ランダムにマッピングされたオペコード値を持つカスタム命令セットアーキテクチャ (ISA) を定義し、リバースエンジニアリングの難易度を高めます。
📖 エンコード詳細を含む完全なオペコードテーブルについては、中国語ドキュメント を参照してください。
コントリビューションを歓迎します。以下のガイドラインに従ってください。
git checkout -b feature/new-archgit commit -m 'feat: add x86_64 decoder'git push origin feature/new-archConventional Commits に従います。
feat: 新機能fix: バグ修正refactor: コードリファクタリングdocs: ドキュメントtest: テストこのプロジェクトは AGPL-3.0 ライセンス の下で提供されています。
なぜ AGPL-3.0 なのか:
本ソフトウェアは「現状のまま」提供され、明示的または黙示的な一切の保証 (商品性、特定目的への適合性、権利非侵害を含むがこれに限らない) を負いません。いかなる場合においても、著作者または著作権保持者は、契約行為、不法行為、その他一切の行為に基づく如何なる請求、損害、その他の責任も負いません。
このプロジェクトは、ソフトウェア開発者に正当な知的財産保護を提供し、商用ソフトウェアにおけるコアアルゴリズムや重要なコードを不正なリバースエンジニアリングや盗難から保護することを目的としています。
利用者への注意:
- 本ソフトウェアを使用する際は、管轄区域のすべての適用される法律および規制を遵守する必要があります
- 本ソフトウェアを違法な目的 (マルウェア開発、セキュリティ監査の回避、他者の知的財産権の侵害、コンピュータシステムのセキュリティ侵害を含むがこれに限らない) に使用することを固く禁じます
- 著作者は、本ソフトウェアの使用に起因する直接的または間接的な結果について一切の責任を負いません
- 本ソフトウェアをダウンロード、使用、または配布することにより、上記の条件を読んで同意したものとみなされます
LeoChen — @LeoChen-CoreMind
Copyright © 2026 LeoChen. All rights reserved.
| 層 | 技術 | 説明 |
|---|
| VM 保護 | カスタム ISA | ランダムにマッピングされたオペコード — リバースエンジニアは命令セマンティクスを直接識別できない |
| OpcodeCryptor | 命令ごとのオペコード暗号化 | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| バイトコード反転 | 実行順序の反転 | 命令が逆順に格納され、インタプリタは逆方向に走査 |
| トークンエントリ | 3 命令のトランポリン | 元の関数をトークン化されたエントリに置き換え、実際のバイトコード位置を隠蔽 |
| 間接ディスパッチ | 関数ポインタのジャンプテーブル | 実行時にスタック上に展開され、IDA のクロスリファレンスを破壊 |
![]() | ![]() | ![]() |
| 関数一覧 | 解析と選択 | 保護オプション |
![]() | ![]() | |
| リアルタイムログ | 保護完了 |
| オプション | デフォルト | 説明 |
|---|
-func | — | 保護する関数名 (カンマ区切り) |
-addr | — | アドレスで保護 (0xSTART-0xEND[:name]) |
-o | input.vmp | 出力ファイルパス |
-v | false | 詳細出力 (逆アセンブリ表示) |
-strip | true | シンボルテーブルの削除 |
-debug | false | ARM64 → VM バイトコードデバッグマッピングファイルの生成 |
-token | true | トークンベースのエントリモード |
-info | false | ELF 情報のみ表示 |
| カテゴリ | 個数 | 説明 |
|---|
| データ移動 | 3 | MOV_IMM64, MOV_IMM32, MOV_REG |
| 算術/論理 | 21 | ADD, SUB, MUL, XOR, AND, OR, SHL, SHR, ASR, NOT, ROR, UMULH + _IMM バリアント |
| メモリアクセス | 8 | LOAD/STORE 8/16/32/64 |
| 分岐/ジャンプ | 13 | JMP, JE, JNE, JL, JGE, JGT, JLE, JB, JAE, JBE, JA, TBZ, TBNZ |
| 比較 | 6 | CMP, CMP_IMM, CCMP_REG, CCMP_IMM, CCMN_REG, CCMN_IMM |
| スタック | 2 | PUSH, POP |
| システム/特殊 | 8 | NOP, HALT, RET, CALL_NATIVE, CALL_REG, BR_REG, SVC, MRS |
| SIMD | 2 | VLD16, VST16 |
| 合計 | 63 |