動的プロキシ
動的プロキシによる保護は、Babel Obfuscator が提供する強力な機能で、アプリケーションのコードの難読化と保護を強化します。動的プロキシクラスを生成することで、外部コードと内部コードの両方へのメソッド呼び出しを隠すことができます。
動的プロキシによる保護を有効にすると、Babel Obfuscator は、メソッド呼び出しの仲介役となるデリゲート型またはプロキシクラスを作成します。これらのプロキシクラスは、難読化の処理中に動的に構築され、コード内の元のメソッド呼び出しを置き換えるために使用されます。
動的プロキシの主な利点は、実際のメソッド呼び出しを効果的に隠し、攻撃者やリバースエンジニアリングを行う者がコードのフローを理解して解析することを、はるかに困難にする点です。動的プロキシを利用すると、機密性の高いメソッドへの直接アクセスを防ぎ、アプリケーションのロジックを見えにくくできます。
このセクションでは、次の内容を扱います。
- 動的プロキシの仕組みとプラットフォームの制限事項
- 内部呼び出しと外部呼び出し:プロキシのモードと、それぞれが保護するもの
- 対象範囲:プロキシ化される呼び出しと、直接呼び出しのまま残る呼び出し
- フィルター:選択した呼び出しだけをプロキシ化する
- 構成:CLI、MSBuild、Babel Desktop
- パフォーマンスと難読化解除への耐性
動的プロキシの仕組み
ビルド時に、Babel Obfuscator は保護する呼び出しごとに小さなプロキシデリゲート型を生成し、元の call、callvirt、newobj 命令を、そのプロキシを経由するように書き換えます。実際の呼び出し先、つまり宣言している型、メソッド、解決済みの呼び出しを保持するフィールドは、書き換えられたコードから直接参照されなくなります。代わりに、プロキシ化された各呼び出しが最初に実行されるときに、挿入された小さなリゾルバーによって復元され、その後はキャッシュされるため、以降の呼び出しはそのまま通過します。
この設計から、2 つの特性が生まれます。
- 静的解析を妨げます:書き換えられた呼び出しサイトは、呼び出し先への直接のメタデータ参照を持たなくなるため、デコンパイラーや自動難読化解除ツールは、メタデータだけから元の呼び出しグラフを再構築できません。呼び出し先のエンコード方法もビルドごとに変わるため、ツールは固定のパターンに頼れません。難読化解除への耐性を参照してください。
- 解決は遅延して行われ、キャッシュされます:プロキシ化された各メンバーへの最初の呼び出しでは、呼び出し先を解決してデリゲートを接続するための小さなコストが、1 回だけかかります。以降の呼び出しはすべてキャッシュされたデリゲートを経由し、オーバーヘッドはごくわずかです。パフォーマンスを参照してください。
プロキシ化は、ビルド時に行われる純粋なマネージド変換です。.NET Framework を必要とせず、.NET と .NET Framework で動作し、プログラムの観察可能な動作を変えません(ただし、対象範囲に示す、意図的に直接呼び出しのまま残される少数の呼び出しを除きます)。
AOT とプラットフォームの互換性に関する制限事項
動的プロキシは現在、.NET MAUI および Blazor アセンブリではサポートされていません。プラットフォームの制限とランタイムの制約が重なり、これらの環境ではプロキシを安全に、一貫して生成および実行できないためです。
プラットフォームの制約
- 事前(AOT)コンパイル:iOS(.NET MAUI が使用)や WebAssembly(Blazor WebAssembly が使用)などのプラットフォームでは、AOT コンパイルが必須です。そのため、リフレクションベースのコード出力や実行時の型生成といったランタイム機能は使用できません。Babel の DynamicProxy は実行時のコード生成を使用しませんが、生成されるプロキシのロジックは、AOT コンパイルされた環境では取り除かれるか、サポートされないメタデータや IL の構造に依存する場合があります。
IL の互換性に関する制限事項
- サポートされないメタデータトークン:動的プロキシの仕組みは、生成されたプロキシ型とデリゲートスタブを通じて、中間の呼び出し層を挿入します。これらは、一部の AOT ターゲットでは検証できない、またはまったくサポートされていないメタデータトークンと間接参照の仕組みに依存しており、実行時の検証エラーやアプリケーションのクラッシュにつながります。
Blazor/WebAssembly の制限事項
- リフレクション機能の制限:Blazor WebAssembly では、リフレクションが大幅に制限されています。DynamicProxy はメソッド呼び出しをラップまたはインターセプトすることが多いため、WebAssembly の公開ワークフローで使用されるリンクとツリーシェイキングの処理と互換性のない、間接的な呼び出し経路が生じることがあります。
推奨事項
.NET MAUI や Blazor のような AOT 環境との完全な互換性を確保するには、DynamicProxy=false に設定することをお勧めします。これにより、生成されるアセンブリは、完全に検証可能で、プラットフォームに準拠し、ネイティブリンクや実行時の起動で失敗する可能性のある機能を含まない状態に保たれます。