Enhance Protection
Once you have set up Dotfuscator Professional per the Protect Your App instructions, your app will be protected with:
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
You can customize Dotfuscator's protection by modifying your project's Dotfuscator config file (by default, DotfuscatorConfig.xml
in your project's directory).
There are two ways to modify the config file:
On Windows, you can use the Config Editor to view and modify your configuration alongside your code's structure in a graphical interface.
On all platforms, you can modify the project file as an XML document in a text editor.
This page will mainly focus on using the Config Editor to enhance your config file's protection. We will include links to the corresponding settings in the Config File Reference, so you can also apply these changes using a text editor.
About the Config Editor
To get started with the Config Editor, launch it from the Dotfuscator Pro Config Editor shortcut in the Windows Start Menu.
Load your config file (e.g., DotfuscatorConfig.xml
) using the File -> Open... command.
The Config Editor is organized into various tabs. The initial Input tab indicates the input assemblies that will be protected. This tab will differ depending on which approach you took in the Protect Your App instructions.
If you used the recommended approach, the input assemblies are handled automatically by the MSBuild targets through a feature called Automatic Input Management.
If you used an alternative approach, the input assemblies must be specified manually using the Input tab. (When editing the config file in a text editor, you configure input assemblies in the
inputassembly
section).
In either case, you can change assembly-specific settings by expanding an input assembly's node on this tab.
input_management
setting.)
When modifying protection settings, it's important to test the protected app, because certain configurations of Dotfuscator's protection can change how your app behaves at runtime. Once you've saved your changes to the config file (e.g., with the File -> Save command in the Config Editor), you need to build your app with the new settings, using your normal build process (Visual Studio, MSBuild, etc.).
After building, run your app. If it behaves as expected, you can return to the Config Editor and continue adjusting the protection. Otherwise, see Runtime Issues.
Add Checks
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 Config Editor's Checks 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.
Below are platform specific examples of applying a Debugging Check on a .NET Framework app, and a Tamper Check on a Xamarin Android app.
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 Checks 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.
If you are using key rotation and your application requires Android Pie (or later), use the last alias in the rotation, otherwise, you need to provide the first alias in the rotation.
Refer to the Xamarin section on the Protect Your App page for an example of where to set the property in your project file.
DotfuscatorAndroidSigningCertFingerprint
if you have multiple signing certificates used for different configurations of your application (e.g. different signing certificates for Debug
and Release
builds).
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.)
When editing the config file in a text editor, Checks are configured in the extattributes
section.
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.
When editing the config file in a text editor, library mode is controlled by the library
input assembly option.
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.
When editing the config file in a text editor, Enhanced Overload Induction is controlled by the enhancedOI
renaming option.
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.
When editing the config file in a text editor, Mono compatibility is controlled by the monocompat
global option.
Suppress Visual Studio's Decompilation
Newer versions of Visual Studio (15.6+) 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.
When editing the config file in a text editor, this suppression is controlled by the suppressildasm
global option.
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.
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.
When editing the config file in a text editor, String Encryption is controlled in the stringencrypt
section.
Enable Removal
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.
When editing the config file in a text editor, Removal is controlled in the removal
section.
Remove the DotfuscatorAttribute
When Dotfuscator protects an assembly, it adds the DotfuscatorAttribute
to the assembly by default.
You can check for this attribute on your assemblies to verify that Dotfuscator has protected them, and third-party build tools may also use the attribute to control how they process the protected assemblies.
However, this attribute may also inform third-party decompilers that Dotfuscator was used to protect your assemblies.
You can prevent Dotfuscator from inserting the DotfuscatorAttribute
into your assemblies by adding nodotfuscatorattribute
to the list of global options in your configuration file, as shown below.
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE dotfuscator SYSTEM "http://www.preemptive.com/dotfuscator/dtd/dotfuscator_v2.5.dtd">
<dotfuscator version="2.3">
<global>
<!-- ...other global options... -->
<option>nodotfuscatorattribute</option>
</global>
<!-- ...other tags... -->
</dotfuscator>
For more information about the DotfuscatorAttribute
and the nodotfuscatorattribute
global option, please refer to the Configuration File Reference.
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.
Before Releasing the Protected App
Before releasing your protected app or library, please review the Release Checklist. It gathers in one place all of the topics that should be considered as part of releasing your protected software.