VMProtectのdevirtualization研究を支援するトレースベースのプラットフォーム:バージョン別フロントエンドが共有のRemill/LLVMバックエンドにハンドラを渡し、データフローを復元してネイティブオブジェクトを出力します。
トレース支援によるVMProtect devirtualization研究:バージョン別フロントエンド (1.xゲート / 2.xテーブル / 3.x FDJ)が単一の共有バックエンド (Remillリフト → LLVM最適化 → セマンティックカード → データフロー → ネイティブオブジェクト)に供給する。
複数の保護モードにわたる自作VMP 3.9.4バイナリに対して検証済み。 VMP 3.8.x/3.10.xの互換性は実験的であり、 サンプルに依存する。
これは所有している、またはリバースエンジニアリングのライセンスを持つVMProtect保護バイナリを 分析するための研究プラットフォームであり、万能な プッシュボタン式devirtualizerではない:
src/
lib.rs crate root, data_dir()
pe_loader.rs PE parsing / VA reads
opcode_map.rs legacy handler-type labels (oracle only, see module docs)
frontend/
mod.rs VmFrontend trait (detect/fetch_stream/handler_addrs)
fetch_finder.rs movzx-byte FDJ scan + watchset/snapshot helpers
cryptor_miner.rs per-site ValueCryptor mining (branch-following)
site_emulator.rs sample-specific oracle decoders (legacy)
handler_classifier.rs handler classification via legacy patterns
classifier_legacy.rs first-bytes patterns (weak; fallback only)
v1_gate.rs VMP 1.x gate-scan front-end
v2_walker.rs VMP 2.x dispatch-table front-end
v3_fdj.rs VMP 3.x FDJ front-end
backend/
value_cryptor.rs ADD/SUB/XOR/ROL/ROR/NOT/NEG/... chains
lifter.rs iced-x86 text lift + Remill subprocess backend
llvm_pipeline.rs opt -O3 over Remill IR (real passes)
harness/
snapshot.rs Unicorn snapshots: sections+scratch mapping,
IN hooks, import stubs, watch hits, memlog,
zero-slide fast-forward
tests/
smoke.rs synthetic PE64 + hand-built fetch chain (no fixtures)
tools/ (analysis drivers; each documents its inputs)
scripts/ Triton/angr/Ghidra helpers (external deps)
# Debian/Ubuntu (LLVM 22 for optional llvm feature)
sudo apt install llvm-22-dev libclang-22-dev clang-22
cargo build --release # pure Rust (no LLVM link)
cargo build --release --features llvm # llvm-sys link check
pip install triton-library capstone pefile # python helpers
# Remill (optional lifter backend): build upstream, export REMILL_LIFT=<path>/remill-lift
# Souper (optional MBA superoptimizer): external only, wire its `souper` CLI
# to scripts/triton_handlers.py output if desired; not vendored.
Dockerfile は完全な環境を再現します。CI は cargo build/test --release を実行します
(デフォルト機能、LLVM リンクなし、商用フィクスチャなし、サンプル依存の
テストはスキップ、tests/smoke.rs は常に実行)。オプションの --features llvm
リンクチェックは非ブロッキングの CI ジョブとして実行されます(LLVM 22 が必要)。
| 変数 | デフォルト | 意味 |
|---|---|---|
DATA_DIR | ./data | すべてのツール成果物 |
WATCH_FILE | $DATA_DIR/watch.txt | 監視する VA を取得 |
CARDS | open_cards3.json | Remill カードキャッシュファイル |
BIN_PATH | 対象バイナリのパス(ツールのデフォルト: ./target.exe プレースホルダ) | 対象バイナリ |
IAT_JSON | — | {api_name: iat_va} インポートスタブマップ |
VMP_TEST_BIN / VMP_ORACLE | tests/fixtures/… | ライセンス済みサンプルのテスト |
REMILL_LIFT | PATH 上の remill-lift-22 | Remill lift バイナリ |
DEVIRT / FORCE_EDGE / REPO_ROOT | ./target/… / . | スクリプトから呼ばれるバイナリ + リポジトリルート |
VMP_WORK_DIR | システムの一時ディレクトリ | lift の作業領域 |
EFLAGS / IN_RET / DLL_MAIN | — | スナップショット状態のバリアント |
ret、インポートスタブ、IN フック)。reg が供給しているかを監視する。ニーモニックに
よらない。静的な movzx パターンはフォールバックのシードにすぎない —
静的のみのヒットはハードニングされた対象で実行率 0% と測定された。
フェッチ形状のカバレッジ: movzx ✓、movsx ✓(実行途中で SMC が
両者を切り替える。マイナーは両方を受け入れる)、and ゲート/co-byte フェッチ ✓
はライブキャプチャ経由。測定されたバイアス(3.9.4、devirt fetch
のディスパッチアンカー付きバックスライス vs 静的厳密スキャン): 互いに素な
母集団 — センサーはパターン+mov-imm32 ゲートが決して提案しなかった
フェッチ形状のバイトサイトを 8 個発見し(movzx edx,[r9+riz-1] のような
インデックス/スケール形式)、1 個は検証済みのチェーン
(Rol→Inc→Xor52→Ror、キー r10l)をマイニングした。残りは VM コンテキストの
ロードであり、マイナーが正しく拒否する。その他の形状(例: 文字列
演算): バイトを持ち込み、マイナーケースを得る — フェッチ周辺のオペコード
バイトを添えて issue を立てる。パターン固定のフェッチはここでは文書化された
非手法である。opt -O3、カード/データフローを
出力し、llc で再コンパイルする(ld -r が合成可能性を証明する)。synth に移植(simplify_chain、コード内に帰属表示)。リフターは
Remill+LLVM のまま。IR の差し替えはなし。devirt brighten として移植(プールは 3.9 では発火しない — 文書化済み)。backend/mba.rs として移植(論文由来、ベンダーコードなし)。MIT(LICENSE 参照)、依存関係の注記あり(特に Unicorn GPL-2.0)。 研究/教育目的のみ、所有または解析許可のあるバイナリに対して使用すること。
AI 支援で構築(設計、コード、ドキュメント — 人間が指示し、
機械が検証: docs/coverage.md のすべての数値は隣のコマンドから
再現可能)。