How to obfuscate mobile .NET applications

Step 1: Add the Data Theorem NuGet feed

Add our repository as a new package source:

dotnet nuget add source https://mobile-protect-repos.securetheorem.com/mobileprotect-dotnet/feed/index.json --username "DOTNET" --password "INSERT YOUR API KEY HERE" --store-password-in-clear-text

And add the API credentials, leave the username as “DOTNET”. Mac/Linux only supports ClearTextPassword, on Windows, you can add it as an encoded password via NuGet CLI.

 

Step 2: Install Data Theorem obfuscator as a global tool

dotnet tool install --global datatheorem.obfuscator

Step 3: Configure your project

In order to add the obfuscation step you will need to add a new task in your csproj that will modify the DLL created by your project. Add the following new target at the end of your csproj:

<Target Name="Obfuscate" AfterTargets="AfterBuild"> <PropertyGroup> <ObfuscationConfigXml><![CDATA[ <?xml version='1.0'?> <Obfuscator> <Var name="InPath" value="$(TargetDir)" /> <Var name="OutPath" value="ObfuscatedOutputFiles" /> <Var name="KeepPublicApi" value="true" /> <Var name="HidePrivateApi" value="true" /> <AssemblySearchPath path="$(MonoAndroidIntermediateAssemblyDir)"/> <Module file="$(TargetDir)$(AssemblyName).dll" /> </Obfuscator> ]]></ObfuscationConfigXml> </PropertyGroup> <!-- write the config to an xml file --> <WriteLinesToFile File="$(IntermediateOutputPath)obfuscation_config.xml" Lines="$(ObfuscationConfigXml)" Overwrite="true" /> <!-- Android debug, write to the mono android folder --> <WriteLinesToFile Condition="'$(Configuration)' == 'Debug' And $(TargetFramework.Contains('android'))" File="$(MonoAndroidIntermediateAssemblyDir)obfuscation_config.xml" Lines="$(ObfuscationConfigXml)" Overwrite="true" /> <!-- Execute the obfuscation task for debug --> <Exec Condition="'$(Configuration)' == 'Release'" WorkingDirectory="$(IntermediateOutputPath)" Command="datatheorem.obfuscate obfuscation_config.xml" /> <!-- Debug executions, iOS is the same, Android is execture in the Mono android folder --> <Exec Condition="'$(Configuration)' == 'Debug' And $(TargetFramework.Contains('android'))" WorkingDirectory="$(MonoAndroidIntermediateAssemblyDir)" Command="datatheorem.obfuscate obfuscation_config.xml" /> <Exec Condition="'$(Configuration)' == 'Debug' And $(TargetFramework.Contains('ios'))" WorkingDirectory="$(IntermediateOutputPath)" Command="datatheorem.obfuscate obfuscation_config.xml" /> <!-- Define where the obfuscated files are --> <ItemGroup> <ObfuscatedOutputFiles Include="$(IntermediateOutputPath)ObfuscatedOutputFiles\*.*" /> </ItemGroup> <!-- Copy the obfuscated files to the build folders --> <Copy DestinationFolder="$(IntermediateOutputPath)" SourceFiles="@(ObfuscatedOutputFiles)" /> <Copy DestinationFolder="$(TargetDir)" SourceFiles="@(ObfuscatedOutputFiles)" /> </Target>

That’s it, this new task will run, obfuscate your project and the packaged dll will be obfuscated.

Note:

As seen in the example config, KeepPublicApi is set to true, which means that public methods will be kept as is. It can be set to false for better obfuscation but please note that it is likely to break the app because of .NET bindings not being able to interact with native iOS/Android APIs.