Skip to Content
新しいバージョン 12 を公開しました 🎉

動的プロキシによる呼び出しグラフの隠蔽

デコンパイラーは、メソッド呼び出しから多くのことを再構築します。使用しているフレームワークの API、自分のメソッド同士のつながり、さらには(呼び出す型から推測される)ローカル変数の元の名前までです。このサンプルでは、Babel Obfuscator の NuGet パッケージを使って動的プロキシを有効にします。動的プロキシは、直接呼び出しを、生成されたプロキシデリゲートを経由する呼び出しに置き換えるため、呼び出しグラフをメタデータから読み取れなくなります。

このサンプルを使用するには、Babel Obfuscator のサイトライセンス(Ultimate、Server、Data Center のいずれかのエディション)が必要です。ソースコードは GitHub で公開しています。

git clone https://github.com/babelfornet/dynamic-proxy-nuget-example.git

隠したいビジネスロジックは、互いを呼び出し、.NET ライブラリも呼び出す、ごく普通のメソッド群です(src/PricingEngine/Pricing.cs)。

internal static class Pricing { public static decimal Quote(string sku, int quantity, string tier) { decimal unit = BasePrice(sku); // internal call decimal discounted = ApplyTierDiscount(unit, tier); decimal volume = ApplyVolumeBreak(discounted, quantity); return Math.Round(volume * quantity, 2); // external (BCL) call } // BasePrice / ApplyTierDiscount / ApplyVolumeBreak … }

難読化後は、これらの呼び出しはどれも直接呼び出しではなくなり、それぞれが生成されたプロキシを経由します。

PricingEngine コンソールプロジェクトは、Release で、プロパティ 1 つだけで動的プロキシを有効にします。

<ItemGroup Condition="'$(Configuration)' == 'Release'"> <PackageReference Include="Babel.Obfuscator" Version="12.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <PropertyGroup Condition="'$(Configuration)' == 'Release'"> <DynamicProxy>external=true;internal=true;true</DynamicProxy> <FlattenNamespaces>true</FlattenNamespaces> <OverloadedRenaming>true</OverloadedRenaming> <BabelWarningsAsErrors>W00000</BabelWarningsAsErrors> </PropertyGroup>

external=true を指定すると、.NET の基本クラスライブラリと参照アセンブリへの呼び出しが隠されます。これだけで、デコンパイラーが呼び出す型から変数の元の名前を復元する手口は通用しなくなります。internal=true を指定すると、自分の型同士の呼び出しも隠され、アプリケーションのロジックがわかりにくくなります。動的プロキシは、静的、インスタンス、仮想、インターフェイス、ジェネリック(LINQ を含む)の呼び出しを対象とし、呼び出し元に依存する少数の呼び出しは直接呼び出しのまま残すため、動作が変わることはありません。

サンプルを Release でビルドすると、出力は変わらないまま、価格エンジンの元の直接呼び出しが、生成されたプロキシデリゲート型に置き換えられます。デコンパイラーが再構築する呼び出しの流れは、もはや自分が書いたものではありません。また、動的プロキシは自動の難読化解除にも耐性があります。

Last updated on