dotnet-inspect-decompiler について
dotnet-inspect で .NET アセンブリを調べるスキルです。逆コンパイルした C#、注釈付きソース、IL、API 検索を使い、出力の忠実度とソースの由来も確認できます。
主な機能
- 01逆コンパイルした C#、注釈付きソース、IL の確認
- 02C# 構文の種類によるメソッド本体の検索
- 03IL オフセットによるメンバーの特定
- 04忠実度の原因と診断情報の確認
- 05ソース選択とネットワークアクセスの制御
- 06出力名とコードスタイルの調整
活用シーン
- 01ソースコードのないアセンブリの調査
- 02特定の C# 構文を含むメソッドの検索
- 03IL 命令からメンバーのコンテキストを追跡
- 04逆コンパイル結果と PDB 対応ソースの比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ richlander/ dotnet-inspect --skill dotnet-inspect-decompilerインストール後、Claude Code で/dotnet-inspect-decompilerを入力して読み込まれたか確認します。
詳細
dotnet-inspect:逆コンパイルと IL
手元にあるアセンブリから、コードが実際にどのように動作するかを理解するには、このスキルを使用してください。
逆コンパイラーは取得済みのアセンブリに対してローカルで実行され、IL ビューや注釈付きビューからは、PDB にマップされたソースにはない事実が明らかになることがあります。パッケージや PDB の取得にはネットワークを使用する場合があります。ネットワークアクセスを禁止するには、--offline を追加してください。
PDB にマップされたソースについては、sourcelink スキルを使用し、取得したコンテンツを解釈する前に、そのチェックサムと来歴の境界に従ってください。
dnx dotnet-inspect -y -- <command>
逆コンパイルされたソースと IL
選択した Type または厳密に指定した Member では、作成者のソースを優先する -S Source を明示的に指定できます。
検証済みの作成者のソースを優先し、そのソースが利用できない場合は、プロバイダーとフォールバックのコンテキストを保持したまま、共通のフォールバックポリシーを使用します。Portable-PDB で選択されたプロバイダーのみが必要な場合は PDB Source を、ローカルで再構築された C# のみが必要な場合は Decompiled Source を使用してください。
選択したオーバーロードは、デフォルトで範囲を限定した Signature の概要を表示します。明示的に要求するには -S Signature を使用してください。実装に関する証拠が必要な場合は、Decompiled Source を明示的に選択してください。ネットワークアクセスを一切使わずに証拠をすべて確認するには、-S "Decompiled Source,Annotated Source,IL" --offline を使用してください。
Decompiled Source— 高水準化および低水準化された C#(可読性はベストエフォート)。PDB に名前がないローカル変数には、デフォルトでバイト列を保持する型/役割由来の名前が使われます。Annotated Source— 隠れた事実を示すコメントと、インターリーブされた IL を含む C#。IL— 生の IL。最も忠実度の高いビューです。
正確なオペコード、オフセット、分岐、トークン、呼び出しが重要な場合は、Annotated Source または IL を使用してください。選択した Type または Member のソースペイロードは、デフォルトでネイティブソースを書き出します。ドキュメント形式の枠組みが必要な場合は --markdown を追加してください。
-S @Source は対象範囲が広く、SourceLink が利用可能な場合はネットワークから PDB Source のコンテンツを取得することがあります。取得時にはホストが許可するリダイレクトに従い、PDB のチェックサムと一致した場合にのみ本文を返します。最終的な取得先をソースの来歴として扱うことはありません。
--project は既存の復元済みアセットを読み込みます。依存関係が変更されている場合は、先に restore/build を実行してください。
dnx dotnet-inspect -y -- type JsonSerializer --package System.Text.Json -S Source
dnx dotnet-inspect -y -- member JsonSerializer --package System.Text.Json \
Serialize:1 -S Source
dnx dotnet-inspect -y -- member JsonSerializer --platform System.Text.Json \
Serialize:1 -S "Decompiled Source,Annotated Source,IL" --offline
dnx dotnet-inspect -y -- member JsonSerializer --platform System.Text.Json Serialize:1 -S "Annotated Source"
dnx dotnet-inspect -y -- type JsonSerializer --platform System.Text.Json -S "Decompiled Source"
dnx dotnet-inspect -y -- member Command --project ./src/App Add:1 -S "Decompiled Source,Annotated Source,IL"
レンダリングされた本体形状を検索する
質問が「この C# 構文を含むパブリック API メソッドはどれですか?」の場合は、ライブラリの Body Shapes セクションを使用します。クエリは厳密で、アセンブリのスコープに限定されます。
Kind には、IR クラス名やテキストパターンではなく、ObjectCreationExpression、
TryStatement、
ElementAccessExpression などの安定した ID を指定します。推測せずに ID を確認してください:
dnx dotnet-inspect -y -- explain vocabularies/csharp.body-kinds .hal --json
dnx dotnet-inspect -y -- library MyLib.dll \
--where "Kind=ObjectCreationExpression" --jsonl
dnx dotnet-inspect -y -- library System.Text.Json \
--where "Kind=TryStatement" --columns "Member;Token;Match" -n 10
dnx dotnet-inspect -y -- library MyLib.dll \
--where "Kind=InvocationExpression" \
--where "Finding=analysis.call-site" \
--where "Shape=sync-call-in-async" --jsonl
dnx dotnet-inspect -y -- type JsonDocument \
--platform System.Text.Json \
--where "Kind=ObjectCreationExpression" --jsonl
dnx dotnet-inspect -y -- member JsonDocument RootElement:1 \
--platform System.Text.Json \
--where "Kind=ObjectCreationExpression" --jsonl
-S による選択がない場合、Kind=... は明示のみのセクションを自動選択します。結果には、ラウンドトリップ可能な修飾メンバーセレクター、MethodDef トークン、メソッドのレンダリング済み C# 本体における 1 始まりの開始/終了範囲、選択されたテキストそのものが含まれます。これらは IL オフセットでも、元のソースファイル上の位置でもありません。
Full
より低い忠実度の本体はスキップされ、その旨が報告されます。メンバーごとの詳細を表示するには、--verbose を追加してください。
ライブラリのスコープでは、Performance Triage のフィールドを指定して --where を繰り返し、逆コンパイル前にそれらの述語を AND で適用します。このクエリは、一致する候補を型付きソース所有者に対応付け、その MethodDef の本体のみを検索します。正規のエビデンスレシートを表示するには、Performance セクションを別途選択してください。
Performance の --top と --order-by は併用できません。Body Shapes の出力を制限するには --rows を使用してください。絞り込みを行わない場合、検索では API サーフェス候補の各本体に対して逆コンパイラーが実行されるため、大規模なライブラリでは処理に時間がかかることがあります。
件数の概要を確認するには、同じ Kind 述語を指定して -S "Body Shape Summary" を選択します。行数制限の適用前に、同一のレンダリング済み Kind/Match 値がグループ化されます。--columns "Match;Count" を指定すると、コンパクトなテーブルになります。既存の Body Shapes セクションは、該当箇所を特定できる出現箇所ビューです。列の射影では行はグループ化されず、--count は、概要ビューではグループ数を、詳細ビューでは行ウィンドウ適用後の出現箇所数を数えます。どちらのビューも、ライブラリ、型、メンバーの各スコープで利用できます。
型のスコープでは、型を 1 つ正確に指定する必要があり、その MethodDef とアクセサーの本体のみが逆コンパイルされます。メンバーのスコープでは、メンバー名またはセレクターを 1 つ正確に指定する必要があり、そのメンバーの MethodDef 本体のみが逆コンパイルされます。曖昧さのないメソッドと、アクセサーが 1 つだけのメンバーは自動選択されます。オーバーロードされた名前には Name:N または Name~digest が必要です。複数の本体アクセサーを持つプロパティまたはイベントでは、アクセサーセレクターが必要です。所有者がオーバーロードされている場合は、Name~digest:1/Name~digest:2 を使用してください。非パブリック型メンバーを含める場合、または非パブリックメンバーを選択する場合は、--all を使用してください。
可読性とスタイル
--readable-names は、本体に安定した読みやすい代替名がある場合、V_0 のようなコンパイラー形式のローカル名を置き換えます。これは C# のスタイルオプションとは独立しています。作業ディレクトリから上位へたどって検出される、ツールが管理する .dotnet-inspectconfig によって、設定済みの表記が選択されます。1 回の呼び出しでオラクルが推奨するスタイルセットを要求するには、--taste を使用します。Applied Taste には、実際にレンダリング済みの本体を変更した選択肢が報告されます。
ローカル型は明示するのがデフォルトです。csharp_style_var_for_built_in_types = true、
csharp_style_var_when_type_is_apparent = true、または
csharp_style_var_elsewhere = true を指定すると、独立した var カテゴリを有効にできます。これらのバイト列に影響しないオプトインは、--taste には含まれません。オブジェクト生成では、デフォルトでターゲット型が推論されます。明示的に構築型を保持するには、csharp_style_implicit_object_creation_when_type_is_apparent = false を設定します。var 宣言では、var x = new() にターゲット型がないため、new T(...) が保持されます。コンパイラー形式の long 定数では、デフォルトで大文字の L が使用されます。明示的な (long)N キャストを保持するには、
dotnet_inspect_style_prefer_long_literal_suffix = false を設定します。
dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
-S "Decompiled Source,Applied Taste" --taste --readable-names
アノテーションに注目する
デフォルトでは、すべての非表示の事実が末尾の // コメントとして表示されます。詳細が長い事実は、そのコメントが右端を大きく超えてしまうことがあります。--focus を指定すると、一致する事実が文の下に ^^^^ の下線として表示され、読みやすいブロックに折り返されます。
dnx dotnet-inspect -y -- member Cache --project ./src/App Pump:1 -S "Annotated Source" --focus allocation
値には、アノテーションカテゴリ、完全一致する ID、またはセグメント境界で区切られたドット付き ID のプレフィックスを指定します(alloc は alloc.box に一致しますが、allocator.x には一致しません)。昇格はしますが、フィルタリングはしません。一致しない事実は末尾の形式のまま残るため、--focus は何も隠さずに注目対象を絞り込みます。一致するものがない場合はその旨を示し、対象メンバーが持つファミリーを列挙します。
忠実度モデル
逆コンパイラーは忠実度の低下を正直に示します。忠実な C# 表記ができない IL は、もっともらしいものの誤ったソースを出力するのではなく、見えるコメントとして表示し、安定した DEC#### 診断を各低下に付けて、結果の忠実度レベルを下げます(Full -> Partial -> StructuredOnly -> IlOnly -> Failed)。Decompiled Source は低忠実度の C# であり、生の IL またはアノテーション付きの IL が最も忠実度の高い形式です。
逆コンパイルされた出力が正しくないように見える場合は、Decompiled Source、Annotated Source、PDB Source、Source Diff(sourcelink スキル経由)、および IL をまとめて取得してください。メンテナーは DecompilerHarness を使ってパイプラインの状態を診断します。
忠実度の評価の根拠となる、型付きの DEC#### 原因の集計を確認するには、Fidelity Causes を選択します。これにより、完全なメソッドで原因がないもの、本文がないメソッド(欠落)、および検査に失敗したものを区別できます。
dnx dotnet-inspect -y -- member MyType MyMethod:1 --library MyLib.dll -S "Fidelity Causes"
IL オフセットからコードを特定する
dnx dotnet-inspect -y -- library coordinate 0x06000001+0x5 --library Foo.dll
library coordinate 0x06000001+0x5 --library Foo.dll(MethodDef トークンと IL オフセット)を使うと、デフォルトのソース位置、メンバー、命令、例外、呼び出しサイト、および戻りアドレスの各セクションをまとめて取得できます。アロケーション、安全性、コストはオプションです。-S "Context: Allocation,Context: Safety,Context: Cost" を指定して取得してください。最大 1,024 件の重要なレコードを含む疎なファイルには、library coordinate --file coordinates.txt --library Foo.dll を使います。空行とコメント行は件数に含まれず、不正な行もソースファイル内の順序のまま表示されます。呼び出しエッジ(メソッドが呼び出す相手、およびそのメソッドを呼び出す相手)については、relationships スキルを参照してください。