After you protect your app for the first time, you can adjust the Dotfuscator configuration to make the protected output harder to reverse engineer and harder to misuse at runtime.
By default, Dotfuscator protects your app with Renaming obfuscation in Library Mode and Control Flow obfuscation. These default settings provide strong starting protection with minimal setup. However, you can improve protection by configuring additional options, including runtime Checks, stronger Renaming settings, stronger Control Flow settings, String Encryption, and Removal.
Before You Start
Before you enhance protection, make sure you have:
- A working Dotfuscator configuration file, such as
DotfuscatorConfig.xml. - A successful protected build.
- A way to test the protected app.
- Access to the Config Editor on Windows, or access to edit the config file manually.
Open the Dotfuscator Config File
You can customize protection by editing your Dotfuscator config file. By default, this file is named DotfuscatorConfig.xml and is located in your project directory.
You can edit the config file in one of these ways:
- On Windows, use the Dotfuscator Pro Config Editor.
- On any platform, edit the XML file in a text editor.
To open the config file in the Config Editor:
- Open Dotfuscator Pro Config Editor from the Windows Start Menu.
- Select File > Open.
- Open your
DotfuscatorConfig.xmlfile.
The Config Editor includes several tabs for configuring protection. The Input tab shows the assemblies Dotfuscator protects.
Check Automatic Input Management
Before you change protection settings, confirm how your input assemblies are managed.
If you use the recommended MSBuild targets approach, Dotfuscator uses Automatic Input Management. In this workflow, the MSBuild integration automatically manages the input assemblies during the build.
If you use an alternative approach, you must specify input assemblies manually on the Input tab.
Enhance Protection Safely
Use this workflow each time you change protection settings:
- Open
DotfuscatorConfig.xml. - Change one protection setting.
- Save the config file.
- Build the app using your normal build process.
- Run the protected app.
- Confirm that the app behaves as expected.
- Continue with the next protection setting.
If the protected app does not behave as expected, review the setting you changed and test again. If needed, see Runtime Issues.
Add Runtime Checks
Dotfuscator can add runtime Checks to help your app respond to unauthorized use while it runs. Checks can detect specific runtime conditions and respond with a configured action or by calling custom app code.
For example, a Debugging Check can help detect when someone attaches a debugger to your production app.
To add a Check:
- Open the config file in the Config Editor.
- Select the Checks tab.
- Click the Add button for the type of Check you want to configure.
- Configure the Check properties.
- Choose the locations where the Check should run.
- Save the config file.
- Build and test the protected app.
Add a Debugging Check for a .NET Framework App
Use a Debugging Check to define how the app responds when a debugger is attached.
To configure a basic Debugging Check:
- Open the Checks tab.
- Click Add Debugging Check.
- In Check Properties, set Action to Exit.
- In Locations, choose the startup method for the app, such as Main.
- Save the config file.
- Build the project.
- Test the protected app.
To test the Debugging Check:
- Use Start Debugging in Visual Studio to test the unauthorized-use case. The app should exit after launch.
- Use Start Without Debugging to test the normal case. The app should run normally.
The current article uses this same testing approach for a first Debugging Check.
Add a Tamper Check for Xamarin Android
Use a Tamper Check to define how the app responds if Dotfuscator detects tampering.
To configure a basic Tamper Check:
- Open the Checks tab.
- Click Add Tamper Check.
- Set Action to the response you want, such as exiting the app.
- Choose a method from your Xamarin Android app as the Check location.
- Save the config file.
For Xamarin Android apps, also set the DotfuscatorAndroidSigningCertFingerprint property in the project file. Use the SHA-1 fingerprint of the certificate used to sign the application.
Improve Renaming Obfuscation
Dotfuscator enables Renaming obfuscation by default. You can improve Renaming protection by allowing more code elements to be renamed and by allowing multiple elements to share the same renamed value.
Disable Library Mode
Library Mode preserves the public contract of protected assemblies so that external code can continue to reference them. If an assembly is not referenced by external code, you can disable Library Mode for that assembly. This allows Dotfuscator to rename more items and increases protection.
To disable Library Mode:
- Open the Input tab.
- Expand the assembly node.
- Clear Library.
- Save the config file.
- Build and test the protected app.
Enable Enhanced Overload Induction
Enhanced Overload Induction increases the effectiveness of Renaming obfuscation by allowing more code elements to share the same new name.
To enable Enhanced Overload Induction:
- Open the Rename tab.
- Select the Options sub-tab.
- Enable Enhanced Overload Induction.
- Save the config file.
- Build and test the protected app.
Improve Control Flow Obfuscation
Dotfuscator enables Control Flow obfuscation by default. You can make this protection stronger by disabling Mono compatibility and suppressing Visual Studio decompilation.
Disable Mono Compatibility
If your app does not need to run on Mono, disable Mono compatibility. This allows Dotfuscator to apply stronger Control Flow obfuscation.
To disable Mono compatibility:
- Open the Settings tab.
- Open the Options screen.
- Under Advanced, set Use only Mono-compatible transforms to No.
- Save the config file.
- Build and test the protected app.
Suppress Visual Studio Decompilation
Visual Studio 15.6 and later can decompile assemblies into C# code. Dotfuscator can prevent Visual Studio and the official .NET disassembler from using this feature on your assemblies. This setting does not affect third-party tools.
To suppress Visual Studio decompilation:
- Open the Settings tab.
- Open the Options screen.
- Under Advanced, set Suppress Ildasm to Yes.
- Save the config file.
- Build and test the protected app.
Enable String Encryption
String Encryption encrypts string literals in your assemblies’ methods. This helps prevent attackers from easily finding sensitive strings with search tools or using strings to understand what specific code paths do.
String Encryption is disabled by default. It only applies to string literals in methods that you explicitly include in this protection. This lets you protect sensitive strings while avoiding the runtime cost of decrypting non-sensitive strings.
To enable String Encryption:
- Open the Settings tab.
- Open the Options screen.
- Under Feature, set Disable String Encryption to No.
- Open the String Encryption tab.
- In the Include sub-tab, select the methods that contain strings you want to protect.
- Save the config file.
- Build and test the protected app.
For a broader first pass, select the assembly node to protect string literals in all methods of the assembly. For a more targeted approach, expand the tree and select specific namespaces, types, or methods.
Enable Removal
Removal removes unused code and metadata from your assemblies. This can reduce the app’s attack surface.
Removal is disabled by default.
To enable Removal:
- Open the Settings tab.
- Open the Options screen.
- Under Feature, set Disable Removal to No.
- Save the config file.
- Build and test the protected app.
Remove the DotfuscatorAttribute
Dotfuscator adds DotfuscatorAttribute to protected assemblies by default. This attribute can help you verify that Dotfuscator protected the assembly, and some third-party build tools may use it when processing protected assemblies. However, it can also show third-party decompilers that Dotfuscator was used.
To prevent Dotfuscator from adding this attribute, add the nodotfuscatorattribute option to the global options in the config file.
Example:
<?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>Compare the Protected Assemblies
After you save your changes and rebuild the app, compare the protected assemblies to the previous output.
You can use a decompilation tool to see how the updated Dotfuscator settings affect the protected output. For example, compare the GettingStarted sample before and after you enhance protection. The current article includes an example where stronger obfuscation causes the decompilation tool to crash.
Examine the Protected Assemblies
Once you save your changes in the Config Editor and build the app in Visual Studio, decompile the newly-protected assemblies to see how the changes to the Dotfuscator config file affect the protection. For details of how to do this, see Decompiling.
For 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 stopped.
Before You Release the Protected App
Before you release your protected app or library:
- Build the app in the intended release configuration.
- Run the protected app and verify the expected behavior.
- Test any configured Checks.
- Archive the generated report files.
- Store report files securely.
- Review the Release Checklist.