These defaults provide reasonably-strong protection for a minimum of effort, but significantly stronger protection is possible, including active protection while your app is running.
Customize Protection Settings
Protection is configured through the Dotfuscator Config Editor; to launch it, search for Dotfuscator Pro Config Editor in the Windows Start Menu.
To begin customizing, open your Dotfuscator config file (by default,
DotfuscatorConfig.xml in your project's directory).
The Config Editor is organized into various tabs. The initial Input tab indicates the assemblies that will be protected; this list is automatically managed by the MSBuild targets integrated into your Visual Studio project.
Note: You cannot use the Config Editor's Build command when editing a config file managed by these MSBuild targets. Instead, save your changes in the Config Editor and then use your normal build process in Visual Studio or MSBuild.
Warning: Do not uncheck Automatic Input Management. This setting is required by the MSBuild targets and the build will fail without it.
When modifying protection settings, it's important to test the protected app, because Dotfuscator's protection can change how your app behaves at runtime. To quickly test how modifying a certain setting affects your app, save the config file in the Config Editor, switch to Visual Studio, and build the project again. Visual Studio will rebuild your app with your modified protection settings.
Then, run your app locally. If it behaves as expected, you can return to the Config Editor and continue adjusting the protection. Otherwise, see Runtime Issues.
Dotfuscator can do more than just hinder code decompilation. It can also inject active measures called Checks to protect your app from unauthorized use at runtime.
For instance, a bad actor can attach a debugger, like WinDbg, to your production app in order to expose and manipulate sensitive data. Adding a Debugging Check to your Dotfuscator configuration allows your app to easily defend itself from these kinds of attacks, producing a significantly better-protected app with little effort.
Checks are configured on the Injection tab's Checks sub-tab. This page's table, which lists the configured Checks, is initially empty; to add a Check, click the appropriate Add button for a given type of Check.
Debugging Check for .NET Framework
You can add anti-debugger behavior to your app by clicking Add Debugging Check. The Config Editor opens a separate window for configuring a new Debugging Check.
This window is divided into two sections. The Check Properties section configures settings for the Check, including how it should respond to unauthorized use. This includes having the Check perform a prebuilt Action (e.g., exiting the app) and/or having the Check call into app code to provide a customized response. The Locations section allows you to choose the methods where the Check will perform its detection and response.
To configure your first Debugging Check, set the Action property to Exit, then choose the startup method for your app (e.g.,
Main) as a Location.
Checks introduce new behavior into your app, so you should test your app to ensure this behavior is what you expect, both in the case where the unauthorized use occurs and the case where it does not occur. To test your first Debugging Check, save your changes in the Config Editor and then build your project in Visual Studio. Then, test both the unauthorized case (a debugger is attached) and the nominal case:
Test the unauthorized use case by using Visual Studio's Start Debugging command. The app should exit immediately after launching.
Test the nominal case with the Start Without Debugging command. The app should behave normally.
Tamper Check for Xamarin Android
You can add a Tamper check to your app by clicking Add Tamper Check, in the Injection tab's Checks sub-tab. The Config Editor opens a separate window for configuring a new Tamper Check.
To configure your Tamper Check, set the value of the Action property to how the app should respond when tampered (e.g., exiting the app). Then choose a method from your Xamarin Android app as a Location for where the Check will perform its detection and response.
Next, you must also set the
DotfuscatorAndroidSigningCertFingerprint property in the project file (
.csproj file) of your Xamarin Android app.
The value should be the SHA-1 fingerprint of the certificate used to sign the application.
Refer to the Xamarin section on the Protect Your App page for an example of where to set the property in your project file.
Note: You may need to conditionally set the
DotfuscatorAndroidSigningCertFingerprintif you have multiple signing certificates used for different configurations of your application (e.g. different signing certificates for
For a case study that uses Checks to protect sensitive data handled by an app, see the MSDN Magazine article Securing Data and Apps from Unauthorized Disclosure and Use. (Note the article uses Dotfuscator Community, but the best practices for using Checks are the same in Dotfuscator Professional.)
Improve Renaming Obfuscation
While Dotfuscator's default configuration enables Renaming obfuscation, you can customize the protection to allow more code elements to be renamed and to allow multiple elements to share the same name.
Disable Library Mode
Dotfuscator's Library Mode preserves the public contract of assemblies it protects, allowing external code not processed by Dotfuscator to continue to reference those assemblies. However, if you know an assembly will never be referenced by external code, you can disable Library Mode for that assembly. This will increase the number of items that will be renamed, enhancing the protection.
Library Mode can be disabled for an assembly on the Input tab by expanding the assembly's node and unchecking Library.
Enable Enhanced Overload Induction
Dotfuscator's renaming obfuscation uses the patented Overload Induction™ technique to increase the number of code elements given the same new name. You can increase the effectiveness of this technique by enabling Enhanced Overload Induction.
Enhanced Overload Induction can be enabled on the Rename tab's Options sub-tab.
Improve Control Flow Obfuscation
Dotfuscator's default configuration enables Control Flow obfuscation. You can enhance this protection by configuring Dotfuscator to disable Mono compatibility and to suppress Visual Studio's decompilation feature.
Disable Mono Compatibility
If your app isn't intended to run on Mono, you can disable Mono compatibility to allow Dotfuscator to apply stronger Control Flow obfuscation.
Mono compatibility can be disabled on the Settings tab's Options screen, under Advanced, by setting Use only Mono-compatible transforms to No.
Suppress Visual Studio's Decompilation
Newer versions of Visual Studio can decompile assemblies back into C# code. Dotfuscator can prevent Visual Studio from using this feature on your assemblies; this will also stop the official .NET disassembler. Note that this setting doesn't affect third party tools.
Visual Studio's decompilation feature can be suppressed on the Settings tab's Options screen, under Advanced, by setting Suppress Ildasm to Yes.
Enable String Encryption Obfuscation
String Encryption obfuscation encrypts string literals in your assemblies' methods, preventing attackers from finding them easily with search tools in order to extract sensitive data or to better understand which parts of the code perform certain actions.
String Encryption is disabled by default. It can be enabled on the Settings tab's Options screen, under Feature, by setting Disable String Encryption to No.
String Encryption obfuscation only applies to string literals in methods specifically configured to be included in this protection. This allows you to encrypt sensitive strings while avoiding the performance impact of having to decrypt non-sensitive strings at runtime.
The methods to protect are selected on the String Encryption tab (which has only one sub-tab, Include), under the Check below to include specific items tree view.
You can start by checking an assembly's node to protect string literals in all methods of the assembly. For a more tailored approach, you can expand the tree nodes and select individual namespaces, types, and methods to include in String Encryption.
Note: Strings declared as constant (
const) fields are inlined when used, so enabling String Encryption for methods that refer to these fields will also cause these usages to be encrypted. However, the constant fields themselves will remain unencrypted, so you should enable Removal to delete these unneeded, unencrypted values from the assembly.
Dotfuscator can remove unused code and metadata from your assemblies, minimizing the surface area for attacks.
Removal is disabled by default. It can be enabled on the Settings tab's Options screen, under Feature, by setting Disable Removal to No.
Examine the Protected Assemblies
Once you've saved your changes in the Config Editor and built the app in Visual Studio, you can decompile the newly-protected assemblies to see how the changes to the Dotfuscator config file affected the protection. For details of how to do this, see Decompiling.
As an example, consider decompiling a method in the
GettingStarted sample app before and after enhancing Dotfuscator's protection:
|Default protection (excerpt)||Enhanced protection|
As a result of the increased obfuscation, the decompilation tool now crashes! Reverse engineering the assembly is now prohibitively expensive because automated reverse engineering tools have been stopped.