.NET / C# 逆向作業規範
ACTION REQUIRED(読んですぐ実行)
NOW: DIE/file/CLR ヘッダで対象が .NET マネージドか確認(そうでない場合はida-reverse//reverse-engineering/に SWITCH)NOW: 難読化が疑われる場合 → 先にde4dotで脱難読化し、*-clean.exeを出力、元のサンプルは保持NEXT: dnSpyEx(または dnSpy MCP /ilspycmd)静的解析:C# ブラウズ + IL ビューで重要な判定を確認ACT: 平文/C2 が必要な場合は動的デバッグ;ロジック変更が必要な場合は IL patch を C# 再コンパイルより優先- フェーズ終了時にユーザに 3~6 項目の次のメニューを提示(レポート出力を含む)
適用範囲
以下のシナリオに該当する場合、本スキルを優先して使用:
- .NET / C# コンパイル成果物(マネージド PE / .exe / .dll)の識別とリバースエンジニアリング
- レッドチーム Sharp* ツールチェーン(Rubeus、SharpHound、SharpShell など)の解析
- ConfuserEx / SmartAssembly / Babel / Eazfuscator / .NET Reactor 等の難読化除去
- .NET loader / info-stealer / RAT の復号と C2 ロジックのリバースエンジニアリング
- C# プログラムへのパッチ(判定変更、定数変更、keygen)
- IL2CPP 前の Mono/Unity マネージド層の解析(注意:IL2CPP コンパイル後はネイティブとなり
reverse-engineering/+ seed-014 を利用)
対象が純粋なネイティブバイナリ(C/C++/Go/Rust コンパイル、CLR なし)の場合は、reverse-engineering/、ida-reverse/、radare2/ を使用してください。
コア原則
- まず識別、次に着手:.NET マネージドプログラムであることを確認(PE ヘッダの CLR +
#~/#Stringsストリーム + mscoree_CorExeMain)してから、dnSpy か IDA かを決定 - C# よりも IL を優先:dnSpyEx の C# 逆コンパイラは情報を失ったり歪めたりする(コンパイラ生成のステートマシン、async/await、yield)。重要な判定やパッチは必ず IL エディタで行い、C# ビューはクイックブラウズ専用
- de4dot を先に:難読化ツールに遭遇したら、まず
de4dotで一度脱難読化してから静的解析を開始。さもないと文字列や制御フローがすべて乱れたまま - MCP 連携:環境に dnSpy MCP(
dnspy_*ツール)が登録されている場合、decompile / IL inspection は MCP 経由で行い、GUI の行き来を減らす - 証拠化出力:脱難読化成果物、抽出した設定/C2/key、patch diff はすべてファイルに保存
ツールチェーンマッピング
| 能力 | 推奨ツール | 備考 |
|---|---|---|
| 逆コンパイル + デバッグ + patch | dnSpyEx | 最強、唯一の IL エディタ付き GUI。旧 dnSpy は更新停止中、Ex ブランチを使用 |
| 軽量 CLI / headless 逆コンパイル | ILSpy (ilspycmd) | バッチ処理、スクリプト、Linux/macOS に最適 |
| 脱難読化 | de4dot | ConfuserEx ファミリー、SmartAssembly など主要シェルのデフォルト解除ツール |
| 難読化ツール識別 | Detect It Easy (DIE) / file | シェルの種類を先に判断してから de4dot パラメータを決定 |
| プログラマブルな IL 操作 | dnlib | C# スクリプトでメタデータ/文字列復号器を一括変更 |
| AI 直接操作 | dnSpy MCP | dnspy_decompile / dnspy_inspect_il などのツール面 |
前提:Windows ホストに dnSpyEx + de4dot をインストール(choco またはリリース版);Linux/macOS では
ilspycmd+dotnet runtimeを使用。詳細はreferences/sharp-tools.mdのインストールマトリックスを参照。
六段階ワークフロー
1. Identify(.NET の識別)
対象がマネージドプログラムであることを確認し、ネイティブ PE を .NET として解析しない:
# Windows
file target.exe # "PE32 executable ... for MS Windows" だけでは不十分
# 重要:CLR の有無を確認
powershell -c "[System.Reflection.AssemblyName]::GetAssemblyName('target.exe')"
# または
dnSpyEx に直接ドラッグ&ドロップ ―― 開ければマネージド
# 汎用
strings target.exe | grep -iE "mscoree|_CorExeMain|mscorlib|System\."
.NET 識別のシグナル:
- PE ヘッダ
Data Directory[14](CLR Runtime Header) が非ゼロ mscoree.dllのインポート /_CorExeMainエントリポイント#~、#Strings、#US、#GUID、#Blobメタデータストリームmscorlib/System.Private.CoreLib文字列
NativeAOT の例外: ネイティブにコンパイルされ、CLR ヘッダはないが、System.Private.CoreLib 文字列と再構築された型メタデータを持つ。これらは reverse-engineering/(IDA/r2)で扱い、本スキルでは識別のヒントのみ提供。
2. Detect(難読化ツールの検出)
# DIE で高速識別
diec target.exe # Detect It Easy CLI
# または dnSpyEx にドロップし、クラス名の乱れや制御フローの変形が多いか確認
よくある難読化ツール → 脱難読化戦略(詳細は references/obfuscators.md):
| 難読化ツール | 特徴 | de4dot 処理 |
|---|---|---|
| ConfuserEx (1.0.0 / 2.x) | <module> anti-tamper、制御フロー変形、文字列暗号化 | de4dot target.exe で通常自動識別 |
| SmartAssembly | circular/string encoding、リソース圧縮 | de4dot target.exe |
| Babel.NET | メソッド本文の暗号化、制御フロー | de4dot target.exe |
| Eazfuscator.NET | 文字列/リソースの暗号化 | de4dot、一部のバージョンでは手動対応が必要 |
| .NET Reactor | anti-tamper + necrobit | de4dot、新バージョンでは失敗する可能性あり、手動対応が必要 |
3. Deobfuscate(脱難読化)
# de4dot はほとんどのシェルを自動識別
de4dot target.exe -o target-clean.exe
# タイプ指定(自動識別失敗時)
de4dot --type cfze target.exe # ConfuserEx
de4dot --type sa target.exe # SmartAssembly
# 多層難読化 / de4dot が unknown の場合
de4dot --detect target.exe # 何と認識されるか確認
# 場合によっては先に anti-tamper パッチを当ててから de4dot(references/obfuscators.md 参照)
出力:target-clean.exe、以後の解析ではこれを使用。元のサンプルは比較用に保持する。
4. Static Analyze(静的解析)
dnSpyEx で脱難読化後のサンプルをロード:
- C# ビュー:クラス構造、メソッドシグネチャ、文字列を素早くブラウズ(位置特定用)
- IL ビュー:重要な判定、暗号化ロジック、ステートマシンは必ず IL で確認(右クリック → Edit IL または IL ビュー)
- エントリポイントを探す:
Main/Startup/ モジュール初期化子 (Module .cctor) - 重要なロジックを探す:
flag、password、verify、check、encrypt、http、Configなどで検索
文字列を特定 → 逆参照 → そのメソッドを特定 → IL ビューで判定ロジックを確認
5. Dynamic(動的デバッグ)
dnSpyEx デバッガ:プロセスへのアタッチ / デバッグ開始、重要なメソッドにブレークポイントを設定し、実行時に観察:
- 復号後の平文文字列(多くの難読化ツールは実行時に文字列を復号する)
- C2 アドレス、設定の復号結果
- 例外駆動の制御フロー(アンチデバッグでは
try/catchで真のパスを隠すことが多い)
.NET の動的デバッグはネイティブよりもはるかに親しみやすい ―― オブジェクトの値や文字列を直接見ることができる。静的解析にこだわらず動的解析を優先する。
6. Patch(必要に応じて変更)
dnSpyEx → メソッドを右クリック → Edit Method (C#) または Edit IL
- 判定の変更:ldc.i4.0 → ldc.i4.1(false→true)
- 定数の変更:文字列/数値を直接編集
- チェックの削除:該当ブロックを nop に
File → Save Module → 元のファイルを置き換え
IL patch の信頼性 > C# patch:C# の再コンパイルは失敗することがある(参照不足、構文エラー)が、IL 編集はほぼ歪みがない。詳細は references/common-workflow.md を参照。
トリガーシナリオルーティング
ユーザが以下のような発言をした場合、本スキルに移行:
- ".NET / C# バイナリリバースエンジニアリング" / "C# プログラムの逆コンパイル"
- "dnSpy 解析" / "dnSpyEx patch"
- "ConfuserEx / SmartAssembly / Babel の脱難読化 / 脱シェル"
- "Sharp* ツール解析"(Rubeus / SharpHound / SharpShell)
- ".NET malware / loader / info-stealer のリバースエンジニアリング"
- "C# プログラムの patch / keygen / 判定変更"
切り替えタイミング
- IL2CPP コンパイルされた Unity ゲーム →
reverse-engineering/+seed-014_unity-il2cpp-reverse.md(IL2CPP はネイティブ、dnSpy は使わない) - NativeAOT 成果物 →
reverse-engineering/(同上、ネイティブ) - 純粋なネイティブ PE(CLR なし)→
reverse-engineering//ida-reverse/ - シンボル/関数の一括移行が必要 →
binary-diff/ - 攻撃パス/コールチェーン図の作成が必要 →
diagram-generator/
ルーティングコンテキスト
上流エントリ: skills/SKILL.md(全体制御)、routing.md
下流出口:
- IL2CPP / NativeAOT(ネイティブ)→
reverse-engineering/ - 深いネイティブ .so/.dll セグメント解析 →
ida-reverse//radare2/ - AI が dnSpy を直接操作する必要がある場合 → dnSpy MCP を登録し連携(
references/sharp-tools.md参照)
同一階層の関連モジュール:
reverse-engineering/languages-compiled.md(.NET 概要から本モジュールを参照)apk-reverse/(Xamarin/MAUI Android リバースから C# 層を見るために本モジュールに切り替え可能)
参考ドキュメント
- references/obfuscators.md — ConfuserEx / SmartAssembly / Babel / Eazfuscator / .NET Reactor の脱難読化詳細 + anti-tamper バイパス
- references/common-workflow.md — 完全ワークフロー、IL patch の信頼性、文字列復号器の抽出、ステートマシン識別
- references/sharp-tools.md — レッドチーム Sharp* ツール解析、ツールインストールマトリックス、dnSpy MCP 統合、コミュニティリソースインデックス
タスク完了セルフチェック
- CLR / マネージドの身分を確認したか(または本スキルから SWITCH したか)?
- 難読化サンプルは最初に de4dot / 同等の脱難読化を行ってから深い解析をしたか?
- 重要なロジックは IL ビューで検証したか(C# 疑似コードだけを見ていないか)?
- 成果物(クリーンサンプル / 設定 / patch diff)はファイルに保存され、再現可能か?
- 次のメニューまたはレポート出力を提供したか?