.NET アプリを公開する
このサンプルでは、Babel タスクを使用して、.NET アプリケーションのビルドプロセスの中でアセンブリ間のリネームを設定する方法を示します。具体的には、MathNet.Numerics パッケージのパブリックインターフェイスを難読化し、難読化されたアセンブリを使用する難読化されたアプリケーションを公開する方法を紹介します。なお、このサンプルを進めるには Babel.Obfuscator NuGet パッケージが必要で、その使用には Ultimate または Server エディションのライセンスが必要です。このサンプルでは、アセンブリ間のリネームを設定してアプリケーションの難読化の効果を高め、リバースエンジニアリングをより難しくする方法を紹介します。
サンプルの完全なソースコードは GitHub で公開しており、次のコマンドでダウンロードできます。
git clone https://github.com/babelfornet/cross-assembly-reference-example.gitサンプルコードは、MathNet.Numerics ライブラリを使って基本的な統計処理を行う、単純な .NET コンソールアプリケーションです。
アセンブリ間のリネームの設定を始めるには、まず Babel Obfuscator の NuGet パッケージを参照する必要があります。Visual Studio の NuGet パッケージマネージャーを使うか、次の MSBuild の記述をプロジェクトファイルに追加します。
<PackageReference Include="Babel.Obfuscator" Version="10.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>これにより、ターゲットアセンブリ Math.dll は、アセンブリ間のリネームを有効にしない状態で難読化されます。
パッケージを追加したら、Babel タスクを使用して、参照している NuGet パッケージのライブラリ MathNet.Numerics のパブリックインターフェイスをリネームし、ビルドプロセスの中でアセンブリ間のリネームを設定できます。
<!-- Obfuscate the public interface of MathNet.Numerics reference -->
<Target Name="BeforeObfuscate">
<PropertyGroup>
<MathNetNumerics Condition="'%(filename)' == 'MathNet.Numerics'">@(ReferencePathWithRefAssemblies->'%(fullpath)')</MathNetNumerics>
<MathNetRules>
<Rules>
<Rule name="rename public" feature="renaming" exclude="false">
<Access>Public</Access>
<Pattern>*</Pattern>
</Rule>
</Rules>
</MathNetRules>
</PropertyGroup>
<Message Text="MathNet.Numerics: $(MathNetNumerics)" Importance="high" />
<Babel InputFile="$(MathNetNumerics)" OutputFile="$(TargetDir)MathNet.Numerics.dll"
FlattenNamespaces="true" XmlRules="$(MathNetRules)"
GenerateMapOutFile="true" />
</Target>具体的には、アプリケーションのビルドに使われる参照の一覧から、参照されているコンポーネントの完全パスを取得する必要があります。
<MathNetNumerics Condition="'%(filename)' == 'MathNet.Numerics'">@(ReferencePathWithRefAssemblies->'%(fullpath)')</MathNetNumerics>これが Babel タスクの入力になり、あわせて、コンポーネントのパブリックインターフェイスをリネームするように Babel を設定する XML ルールを指定します。また、プロパティ GenerateMapOutFile="true" を設定して、ターゲットアセンブリを難読化するときに使用するマップファイルを生成する必要もあります。
ターゲットの名前を BeforeObfuscate に設定している点に注意してください。これは Babel Obfuscator の NuGet パッケージが定義するエントリポイントで、ターゲットアセンブリを難読化する前に追加のタスクを実行できます。
ターゲットアセンブリ「Math.dll」でアセンブリ間のリネームを有効にするには、参照ライブラリ「MathNet.Numerics.dll」用に生成された XML マップファイルを、ターゲットアセンブリの難読化タスクに追加する必要があります。これには、Babel Obfuscator の NuGet パッケージ用に定義されたプロパティを使用します。プロパティはパッケージリファレンスで説明しています。
<!-- Target assembly obfuscation settings -->
<ItemGroup>
<MapInFile Include="$(TargetDir)MathNet.Numerics.dll.map.xml" />
</ItemGroup>
<PropertyGroup>
<StringEncryption>true</StringEncryption>
<ValueEncryption>array=true;true;</ValueEncryption>
<ControlFlowObfuscation>goto=on;if=on;switch=on;case=on;call=on</ControlFlowObfuscation>
<CopyOutputSymbolsToPublishDirectory>false</CopyOutputSymbolsToPublishDirectory>
</PropertyGroup>難読化されたコードの解析に使える追加情報を攻撃者が取り出せないように、次の設定で PDB ファイルの公開を無効にしています。
CopyOutputSymbolsToPublishDirectory=false
PDB ファイルには、ソースコードのファイル名や行番号などのデバッグ情報が含まれており、攻撃者が難読化されたコードを理解しやすくなるおそれがあります。
プロジェクトをビルドすると、アセンブリ間で難読化されたアプリケーションがターゲットディレクトリに生成されます。デプロイ可能なパッケージを作成するには、NuGet パッケージの MathNet.Numerics.dll へのファイル参照を、難読化されたバージョンのファイルパスに置き換える必要があります。Visual Studio が正しい難読化されたアセンブリをパッケージ化するために、この手順は欠かせません。
<!-- Replace the deployed MathNet.Numerics.dll assembly reference with the obfuscated one -->
<Target Name="UpdateFilesToPublish" AfterTargets="ComputeFilesToPublish">
<ItemGroup>
<ResolvedFileToPublish Remove="$(MathNetNumerics)" />
<ResolvedFileToPublish Include="$(TargetDir)MathNet.Numerics.dll">
<RelativePath>MathNet.Numerics.dll</RelativePath>
</ResolvedFileToPublish>
</ItemGroup>
</Target>上の MSBuild XML の断片は UpdateFilesToPublish という名前のターゲットで、ターゲット ComputeFilesToPublish の後に実行されます。このターゲットは、デプロイパッケージの中で、NuGet パッケージに含まれる元の MathNet.Numerics.dll アセンブリへの参照を難読化されたものに置き換えます。
このターゲットは、まず項目グループを定義し、Remove 属性で元のファイルパスを保持するプロパティを参照して、「MathNet.Numerics.dll」ファイルへの元の参照を取り除きます。
次に、Include 属性でターゲットディレクトリ内の難読化されたファイルのパスを参照して、難読化されたバージョンの「MathNet.Numerics.dll」ファイルを項目グループに追加します。RelativePath 要素は、デプロイディレクトリのルートからファイルへの相対パスを指定します。
このターゲットが実行されると、元のファイル参照が取り除かれ、難読化されたファイルへの参照がデプロイパッケージに追加されます。これにより、元のアセンブリの代わりに難読化されたアセンブリがデプロイされます。
完全に難読化されたアプリケーションを公開するには、プロジェクトフォルダーに移動して、次のコマンドを実行します。
dotnet publish全体として、このサンプルは、Babel による難読化を .NET のビルドパイプラインに統合し、アセンブリ間の難読化でコードを保護したい開発者にとっての出発点になります。あわせて、難読化されたアセンブリを含めるためにデプロイパッケージを変更する方法についても、補足的な助言を示しました。