
ARM64 ELF 仮想マシン保護システム
ARM64 ELF 仮想マシン保護システム
ARM64 ネイティブ命令をカスタム VM バイトコードに変換し、関数レベルのコード保護を実現します
🇨🇳 中文文档 • 機能 • アーキテクチャ • クイックスタート • 使い方 • ライセンス
VMPacker は、ARM64 (AArch64) Linux ELF バイナリ向けの 仮想マシン保護 (VMP) システムです。対象関数の ARM64 ネイティブ命令を中間表現にデコードし、カスタム VM バイトコードに変換して、ELF ファイル内に組み込み VM インタプリタを注入します。実行時、保護された関数はネイティブ実行ではなく VM インタプリタによって実行されます。
ARM64 ネイティブコード → デコード → 変換 → カスタム VM バイトコード
↓
元の ELF <-- 注入 <-- VM インタプリタスタブ
| 層 | 技術 | 説明 |
|---|---|---|
| VM 保護 | カスタム ISA | ランダムにマッピングされたオペコード — リバースエンジニアは命令セマンティクスを直接識別できない |
| OpcodeCryptor | 命令ごとのオペコード暗号化 | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| バイトコード反転 | 実行順序の反転 | 命令が逆順に格納され、インタプリタは逆方向に走査 |
| トークンエントリ | 3 命令のトランポリン | 元の関数をトークン化されたエントリに置き換え、実際のバイトコード位置を隠蔽 |
| 間接ディスパッチ | 関数ポインタのジャンプテーブル | 実行時にスタック上に展開され、IDA のクロスリファレンスを破壊 |
![]() |
![]() |
![]() |
| 関数一覧 | 解析と選択 | 保護オプション |
![]() |
![]() |
|
| リアルタイムログ | 保護完了 |
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
| オプション | デフォルト | 説明 |
|---|---|---|
-func | — | 保護する関数名 (カンマ区切り) |
-addr | — | アドレスで保護 (0xSTART-0xEND[:name]) |
-o | input.vmp | 出力ファイルパス |
-v | false | 詳細出力 (逆アセンブリ表示) |
-strip | true | シンボルテーブルの削除 |
-debug | false | ARM64 → VM バイトコードデバッグマッピングファイルの生成 |
-token | true | トークンベースのエントリモード |
-info | false | 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) を定義し、リバースエンジニアリングの難易度を高めます。
📖 エンコード詳細を含む完全なオペコードテーブルについては、中国語ドキュメント を参照してください。