code-obfuscation-deobfuscation
難読化されたコードの解析・復号化に特化したプレイブック。ジャンクコード、不透明述語、自己書き換えコード、制御フロー平坦化、VM保護、文字列暗号化などで保護されたバイナリをリバースエンジニアリングする際に使用します。
description の原文を見る
>- Code obfuscation analysis and deobfuscation playbook. Use when reversing binaries protected by junk code, opaque predicates, self-modifying code, control flow flattening, VM protection, or string encryption.
SKILL.md 本文
SKILL: コード難読化・難読化解除 — エキスパート分析プレイブック
AI LOAD INSTRUCTION: ネイティブバイナリ内のコード難読化を識別、分類、および解除するエキスパート手法。ジャンクコード、不透明述語、SMC、制御フロー平坦化、movfuscator、VM保護プロテクタ(VMProtect/Themida/Code Virtualizer)、文字列暗号化、インポート隠蔽、およびアンチディスアセンブリトリックをカバーします。ベースモデルはしばしばパッキングと難読化を混同し、静的難読化解除と動的難読化解除戦略の違いを見落とします。
0. 関連ルーティング
anti-debugging-techniques— 難読化されたバイナリがアンチデバッグレイヤーも持っている場合symbolic-execution-tools— 自動難読化解除に angr/Z3 を使用する場合vm-and-bytecode-reverse— VM保護プロテクタのバイトコード解析に深く掘り下げる場合
迅速な識別チェックリスト
| IDA/Ghidra での症状 | 可能性のある難読化 | はじめに |
|---|---|---|
| フラットなCFG、単一の巨大スイッチ | 制御フロー平坦化 | シンボリック実行でCFGを復元 |
mov 命令のみ | movfuscator | demovfuscation / トレースベース変換 |
| pushad/pushfd → VM エントリ | VM保護プロテクタ | ハンドラテーブル抽出 |
| 実行前の XOR ループ | SMC / 文字列暗号化 | 動的解析、復号後にブレークポイント |
| 不可能な条件(不透明述語) | ジャンクコード挿入 | パターンベース削除 |
| すべての文字列が読み取り不可 | 文字列暗号化 | 復号ルーチンをフック、またはエミュレート |
| IAT にインポートなし | インポート隠蔽 | GetProcAddress / ハッシュ解決をトレース |
1. ジャンクコード & 不透明述語
1.1 ジャンクコード挿入
プログラム出力に影響しない無効なコード。分析時間を増やすために追加されます。
識別方法:
- その後に読み取られないレジスタ/メモリに書き込む命令
- 戻り値が破棄され、副作用がない関数呼び出し
- 不変な境界を持つループで未使用の結果を計算
除去戦略:
- 定義使用チェーンを計算(IDA/Ghidra データフロー解析)
- ダウンストリーム使用のない命令を無効としてマーク
- 除去がプログラム動作を変更しないことを検証(トレース比較)
1.2 不透明述語
条件が常に真または常に偽だが、それが明確でない条件付き分岐。
| タイプ | 例 | 常に評価される値 |
|---|---|---|
| 算術 | x² ≥ 0 | True |
| 数論 | x*(x+1) % 2 == 0 | True(連続整数の積) |
| ポインタベース | エイリアス後の ptr == ptr | True |
| ハッシュベース | CRC32(constant) == known_value | True |
難読化解除:
- 抽象解釈:条件が定数であることを証明
- シンボリック実行:Z3 が
∀x: predicate(x) = Trueを証明 - パターンマッチング:既知の不透明述語ファミリーを認識
- 動的:トレースして分岐が決して実行されない/常に実行されることを観察
import z3
x = z3.BitVec('x', 32)
s = z3.Solver()
s.add(x * (x + 1) % 2 != 0)
print(s.check()) # unsat → 常に true
2. 自己変更コード(SMC)
実行時コードパッチング:暗号化されたコードは実行直前に復号されます。
2.1 XOR 復号ループ(最も一般的)
lea esi, [encrypted_code]
mov ecx, code_length
mov al, xor_key
decrypt_loop:
xor byte [esi], al
inc esi
loop decrypt_loop
jmp encrypted_code ; 復号済み
2.2 解析戦略
1. 復号ルーチンを識別(.text セクションに書き込むループ内の XOR/ADD/SUB を探す)
2. ループ完了後にブレークポイントを設定
3. ブレークポイントで:復号されたメモリ領域をダンプ
4. ダンプされたコードを IDA/Ghidra で再解析
5. 複数レイヤーの場合:各復号ステージで繰り返す
2.3 エミュレーションによる自動アンパック
from unicorn import *
from unicorn.x86_const import *
mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0x400000, 0x10000)
mu.mem_write(0x400000, binary_code)
mu.emu_start(decrypt_entry, decrypt_end)
decrypted = mu.mem_read(code_start, code_length)
3. 制御フロー平坦化(CFF)
3.1 構造
元の順序付きブロックはディスパッチャループに変換されます:
元の形式: A → B → C → D
平坦化形式: ┌──────────────────┐
│ dispatcher │
│ switch(state) │◄─────┐
├──────────────────┤ │
│ case 1: block A │──────┤
│ case 2: block B │──────┤
│ case 3: block C │──────┤
│ case 4: block D │──────┘
└──────────────────┘
各ブロックはディスパッチャに戻るジャンプの前に state = next_state を設定します。
3.2 復元技術
| 技術 | ツール | 効果 |
|---|---|---|
| シンボリック実行 | angr、Triton、miasm | 高 — すべての状態遷移をトレース |
| トレースベース復元 | Pin/DynamoRIO トレース → CFG 再構成 | 中 — 実行パスのみをカバー |
| パターンマッチング | カスタム IDA/Ghidra スクリプト | 中 — 既知のフラッタナー用 |
| D-810(IDA プラグイン) | IDA Pro | 高 — CFF 専用に設計 |
3.3 シンボリック平坦化解除(angr アプローチ)
import angr, claripy
proj = angr.Project('./obfuscated')
cfg = proj.analyses.CFGFast()
# ディスパッチャブロックを検出(最高入次数の基本ブロック)
dispatcher = max(cfg.graph.nodes(), key=lambda n: cfg.graph.in_degree(n))
# 各ケースブロックについて、シンボリックに次の分岐を決定
for block in case_blocks:
state = proj.factory.blank_state(addr=block.addr)
# ... 状態変数を解決して実際の次の分岐を検出
4. MOVFUSCATOR
4.1 概念
すべての計算は mov 命令のみに削減されます(メモリマップ計算テーブルを使用してチューリング完全)。Christopher Domas によって作成されました。
4.2 識別
- 関数には
mov命令のみが含まれます(add、sub、xor、jmp、call なし) - データセクション内の大規模ルックアップテーブル
- メモリマップフラグレジスタ
4.3 Demovfuscation
| アプローチ | 説明 |
|---|---|
| demovfuscator(ツール) | 静的解析、movパターンから元の操作を復元 |
| トレース + 汚染解析 | Pin/DynamoRIO で実行、入力に汚染をマーク、計算を観察 |
| シンボリック実行 | 関数全体を制約システムとして扱う |
5. VM 保護(VMProtect / Themida / Code Virtualizer)
5.1 VM アーキテクチャ
保護されたコード → バイトコードコンパイラ → カスタムバイトコード
ランタイム:VM エントリ(pushad/pushfd) → フェッチ → デコード → 実行 → VM 終了(popad/popfd)
5.2 VM エントリポイント識別
; 典型的な VMProtect エントリ
pushad ; すべてのレジスタを保存
pushfd ; フラグを保存
mov ebp, esp ; VM スタックフレーム
sub esp, VM_LOCALS_SIZE ; VM コンテキストを割り当て
mov esi, bytecode_addr ; バイトコード命令ポインタ
jmp vm_dispatcher ; VM ループを入力
5.3 ハンドラテーブル抽出
1. ディスパッチャを検出(大規模スイッチまたはテーブル経由の間接ジャンプ)
2. 各ケース/エントリ = 1 つの VM ハンドラ(1 つの VM オペコードを実装)
3. 各ハンドラを解析してハンドラアドレスを操作にマップ:
- ハンドラがバイトコードストリームからオペランドを読み取る(esi)
- VM レジスタ/スタックで操作を実行
- バイトコードポインタを進める
- ディスパッチャに返す
5.4 仮想化解除アプローチ
| 方法 | 説明 | ツール |
|---|---|---|
| 手動ハンドラマッピング | 各ハンドラをリバース、ISA仕様を構築 | IDA + スクリプティング |
| トレース記録 | すべてのハンドラ実行を記録、プログラムを再構成 | REVEN、Pin |
| シンボリック変換 | ハンドラをシンボリック実行、IR に変換 | Triton、miasm |
| パターンマッチング | ハンドラパターンを既知の VM ファミリーと照合 | カスタムスクリプト |
5.5 VMProtect 仕様
- ディスパッチャで不透明述語を使用
- ハンドラミューテーション:同じオペコード、ビルドごとに異なるハンドラコード
- 複数の VM レイヤー(VM 内の VM)
- アンチデバッグと整合性チェックを統合
6. 文字列暗号化
6.1 一般的なパターン
| パターン | 例 | 復元 |
|---|---|---|
| XOR ループ | for (i=0; i<len; i++) s[i] ^= key; | XOR 関数をフック、またはエミュレート |
| スタック文字列 | mov [esp+0], 'H'; mov [esp+1], 'e'; ... | IDA FLIRT / Ghidra スクリプトで再構成 |
| RC4 暗号化 | 暗号化ブロブ + バイナリ内の RC4 キー | キーを抽出、オフラインで復号 |
| AES 暗号化 | 暗号化ブロブ + 実行時に派生する AES キー | 復号後にフック |
| カスタムエンコーディング | Base64 + XOR + リバース | デコード関数をトレース、複製 |
6.2 自動文字列復号
# Ghidra スクリプト:XOR 復号呼び出しを検出、エミュレート
from ghidra.program.model.symbol import SourceType
decrypt_func = getFunction("decrypt_string")
refs = getReferencesTo(decrypt_func.getEntryPoint())
for ref in refs:
call_addr = ref.getFromAddress()
# 引数を抽出(暗号化バッファポインタ、キー、長さ)
# 復号をエミュレート、プレーンテキストでコメントを追加
7. インポート隠蔽
7.1 GetProcAddress + ハッシュルックアップ
FARPROC resolve(DWORD hash) {
// PEB を歩く → LDR → InMemoryOrderModuleList
// 各 DLL について、エクスポートテーブルを歩く
// 各エクスポート名をハッシュ化、ターゲットハッシュと比較
// マッチする関数ポインタを返す
}
7.2 復元
- ハッシュアルゴリズムを識別(一般的:CRC32、djb2、ROR13+ADD)
- すべての既知 API 名のハッシュを計算
- ハッシュ → API 名ルックアップテーブルを構築
- IDA/Ghidra で解決された呼び出しに注釈を付ける
7.3 一般的なハッシュアルゴリズム
| 名前 | アルゴリズム | 使用者 |
|---|---|---|
| ROR13 | hash = (hash >> 13 | hash << 19) + char | Metasploit シェルコード |
| djb2 | hash = hash * 33 + char | 各種マルウェア |
| CRC32 | 関数名の標準 CRC32 | 高度なパッカー |
| FNV-1a | hash = (hash ^ char) * 0x01000193 | モダンマルウェア |
8. アンチディスアセンブリトリック
8.1 技法
| トリック | メカニズム | 修正 |
|---|---|---|
| 重なる命令 | jmp $+2; db 0xE8(偽の呼び出しプリフィックス) | 正しいオフセットから手動で再解析 |
| ミスアライン跳び | マルチバイト命令の途中へのジャンプ | ターゲットで再解析を強制 |
| 条件付きジャンプペア | jz $+5; jnz $+3(常にジャンプ、線形逆アセンブルを混乱) | 無条件 jmp に変換 |
| 戻りアドレス操作 | jmp addr の代わりに push addr; ret | push+ret をジャンプとして認識 |
| 例外ベースフロー | 例外をトリガー、実際のコードはハンドラにあり | 例外ハンドラチェーンを解析 |
| Call + add [esp] | call $+5; add [esp], N; ret(計算されたジャンプ) | 実際のターゲットを計算 |
8.2 IDA 修正
右クリック → Undefine(U)
右クリック → 正しいオフセットで Code(C)
Edit → Patch → Assemble(永続的な修正)
9. 決定木
難読化されたバイナリ — どのように対処するか?
│
├─ 実行できるか?
│ ├─ はい → 動的解析を最初に
│ │ ├─ 興味深い API(ファイル、ネットワーク、暗号)にブレークポイントを設定
│ │ ├─ 実行をトレースして実際の動作を理解
│ │ └─ 実行時に復号されたコード/文字列をダンプ
│ │
│ └─ いいえ(組み込み/ファームウェア/異種アーキテクチャ) → 静的のみ
│ └─ 以下のパターンから難読化タイプを識別
│
├─ コードはどのように見えるか?
│ │
│ ├─ 巨大なフラットスイッチ/ディスパッチャループ?
│ │ ├─ 状態変数が制御フローを駆動 → CFF
│ │ │ └─ D-810 またはシンボリック平坦化解除を使用
│ │ └─ バイトコードフェッチ-デコード-実行 → VM 保護
│ │ └─ ハンドラを抽出、逆アセンブラを構築
│ │
│ ├─ mov 命令のみ?
│ │ └─ movfuscator → demovfuscator ツール
│ │
│ ├─ XOR/ADD ループが .text セクションに書き込み?
│ │ └─ SMC → 復号後にブレークポイント、ダンプ
│ │
│ ├─ ブランチに不可能な条件?
│ │ └─ 不透明述語 → Z3 証明またはパターン除去
│ │
│ ├─ 逆アセンブリが間違った / 関数が重なっている?
│ │ └─ アンチディスアセンブリ → 正しいオフセットで手動再解析
│ │
│ ├─ 読み取り可能な文字列なし?
│ │ └─ 文字列暗号化 → 復号関数をフック、またはエミュレート
│ │
│ ├─ IAT にインポートなし?
│ │ └─ インポート隠蔽 → ハッシュを識別、ルックアップテーブルを構築
│ │
│ └─ pushad/pushfd → 複雑なコード → popad/popfd?
│ └─ VM プロテクタエントリ/終了 → 完全な VM 解析
│
└─ どのツールを使用するか?
├─ 既知のプロテクタ(VMProtect/Themida) → 特定の除去ガイド
├─ カスタム難読化 → 組み合わせ:IDA スクリプティング + Triton + 手動
├─ CTF チャレンジ → angr シンボリック実行が最速
└─ マルウェア解析 → 動的(デバッガ + API モニタ)を最初に
10. ツールボックス
| ツール | 目的 | 最適用途 |
|---|---|---|
| IDA Pro + Hex-Rays | 逆アセンブル、逆コンパイル、スクリプティング | 全般的解析 |
| Ghidra | 無料の代替品、スクリプティング対応(Java/Python) | 予算重視の RE |
| D-810(IDA プラグイン) | 自動 CFF 平坦化解除 | OLLVM スタイルの難読化 |
| miasm | IR ベース解析フレームワーク | シンボリック難読化解除 |
| Triton | 動的シンボリック実行 | 不透明述語解決、CFF |
| REVEN | 全システムトレース記録と再生 | VM プロテクタ解析 |
| demovfuscator | movfuscator リバース | mov のみのバイナリ |
| x64dbg + プラグイン | スクリプティング機能付き動的解析 | Windows RE |
| Unicorn Engine | CPU エミュレーション | SMC アンパック、シェルコード |
| Capstone | 逆アセンブルライブラリ | カスタムツーリング |
| IDA FLIRT | 関数シグネチャマッチング | ストリップされたバイナリ内のライブラリコード識別 |
| Binary Ninja | 代替逆アセンブラ(MLIL/HLIL付き) | 自動解析 |
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。