Getting Started
Understanding Protection
Understanding Obfuscation
Understanding Checks
Understanding Instrumentation
Using the GUI
References
P/Invoke methods (i.e. native platform methods) are automatically not renamed if Dotfuscator detects that the name is used to find the corresponding native function. P/Invoke methods that are mapped to native functions by an alias or by ordinal can be renamed.
Dotfuscator can process assemblies containing managed and unmanaged (native) code, such as those created by the Managed C++ compiler. Dotfuscator performs renaming and metadata removal on mixed code modules; however, string encryption, control flow obfuscation, and removal are automatically disabled. These features are still enabled on other "pure managed" input modules included in the run.
Managed resources may be embedded inside a module (internal) or may be in files external to the module. Often, part of the name of the managed resource is a type name (see the .NET Framework documentation for more information about the “hub and spoke model” for lookup of managed resources.).
When the type name is renamed, Dotfuscator attempts to locate and rename the corresponding managed resource. If the resource is internal to the assembly, this is automatic. If the resource is embedded inside an external file, then the file must be in the same directory as the referencing module. If the resource is embedded inside another assembly, then that assembly must be one of the input assemblies.
Localized applications can be seamlessly obfuscated along with their satellite resource DLLs. Dotfuscator automatically discovers these DLLs using the same rules that the runtime uses and automatically adds them as inputs to the obfuscation process. You do not need to explicitly specify them as inputs.
Your localized resources contained in the satellite DLLs will be renamed in sync with your culture neutral resources in the main assembly.
A .NET assembly may be made up of multiple modules (i.e. files on disk). Usually an assembly is made up of one module, and this is the scenario that most tools, such as Visual Studio, support. Occasionally it is desirable to create assemblies made up of more than one module. Dotfuscator supports this scenario. Note that obfuscating a multi-module assembly is not the same as obfuscating multiple input assemblies.
To obfuscate a multi-module assembly, only the prime module needs to be listed as an input assembly. The non-prime modules are searched for in the same directory as the prime module.
In the prime module’s assembly manifest, Dotfuscator automatically updates the hash values of the other modules.
Dotfuscator can transparently obfuscate managed assemblies written explicitly for specific CPU architectures, including 64-bit architectures.
Dotfuscator itself is a managed application and can run on 32-bit and 64-bit versions of Windows.
Reflection and dynamic class loading are extremely powerful tools in the .NET architecture. However, this level of runtime program customization prevents Dotfuscator from infallibly determining whether it is safe to rename all types loaded into a given program.
Consider the following (C#) code fragment:
C# Code Fragment:
public object GetNewType() {
Type type = Type.GetType( GetUserInputString(), true );
object newInstance = Activator.CreateInstance( type );
return newInstance;
}
This code loads a type by name and dynamically instantiates it. In addition, the name is coming from a string input by the user!
There is no way for Dotfuscator to predict which type names the user will enter. The solution is to configure Dotfuscator to exclude the names of all potentially loadable types. Note that method and field renaming can still be performed. This is where manual user configuration plays an important role.
Often the situation is less serious. Consider a slight variation:
C# Code Fragment Variation:
public MyInterface GetNewType() {
Type type = Type.GetType( GetUserInputString(), true );
object newInstance = Activator.CreateInstance( type );
return newInstance as MyInterface;
}
Now it is immediately obvious that only a subset of types need to be excluded: those implementing MyInterface
.
The .NET Framework provides two custom attributes designed to make it easy to automatically obfuscate assemblies without having to set up configuration files. This section outlines how you can use these attributes with Dotfuscator. It is assumed that you are familiar with custom attributes and how to apply them in your development language.
If you are using an earlier version of the .NET Framework that does not have these custom attributes, Dotfuscator ships with a DLL containing compatible attributes.
The ObfuscateAssemblyAttribute
is used at the assembly level to tell Dotfuscator how to obfuscate the assembly as a whole.
This attribute's properties specify whether the assembly is in library mode and whether obfuscation attribute stripping is enabled for the assembly.
Full configuration details for the ObfuscateAssemblyAttribute
can be found here.
The ObfuscationAttribute
is used on types and their members and has a Feature property that specifies what action Dotfuscator should perform on the annotated code element.
Dotfuscator supports configuring the following features via ObfuscationAttributes
:
Multiple features may be configured independently by annotating a single code element with multiple ObfuscationAttribute
s, each with a different feature property value.
Dotfuscator ignores attributes with feature strings that it does not understand.
Full configuration details for the ObfuscationAttribute
can be found here.
Dotfuscator allows you to switch Declarative Obfuscation on or off for any or all input assemblies. If not enabled, Dotfuscator completely ignores obfuscation-related custom attributes.
Configure the Honor Obfuscation Attributes setting in the Dotfuscator GUI.
Dotfuscator can remove the obfuscation attributes when processing is complete, so output assemblies will not contain clues about how they were obfuscated.
Configure the Strip Obfuscation Attributes setting in the Dotfuscator GUI or configure attribute stripping via the StripAfterObfuscation property of the obfuscation-related custom attributes.
Dotfuscator allows you to map values contained in the Feature property of an ObfuscationAttribute
to feature strings that Dotfuscator understands.
For example, you can annotate your application with ObfuscationAttributes
that reference a feature called "testmode"
.
Dotfuscator, by default, does not understand this feature string; therefore, it ignores the attributes.
Later, if you want Dotfuscator to use these attributes to configure Renaming and Control Flow obfuscation, then map the feature string "testmode"
to Dotfuscator's built-in "renaming"
and "controlflow"
strings.
Configure the Feature Map Strings on the Settings Tab of the Dotfuscator GUI.
The .NET Framework has the concept of friend assemblies, where an assembly may declare that its internal type definitions are visible to specified other assemblies.
This is done using the System.Runtime.CompilerServices.InternalsVisibleToAttribute
.
Dotfuscator detects the use of this attribute and modifies its renaming and removal rules as described below.
Assume A and B are two assemblies where assembly B references A, and A is marked with InternalsVisibleTo ( B )
.
There are a few cases of interest:
Dotfuscator uses ildasm and ilasm to process the input assemblies. Ildasm is the MSIL disassembler that ships with the .NET Framework SDK. Ilasm is the MSIL assembler that ships with the .NET Framework Redistributable.
On systems with .NET 1.1 or below, Dotfuscator attempts to match each input assembly with the toolset that ships with the version of the .NET Framework that it was compiled with. If Dotfuscator cannot find the version appropriate toolset for an input assembly, it uses a later version if present. It never uses an older version.
On systems with .NET 2.0 and above, Dotfuscator will use the latest tools even for .NET 1.x assemblies. When building, Dotfuscator passes the appropriate command line arguments to ilasm to ensure that the output assemblies target their correct framework versions.
By default, Dotfuscator searches for these external tools using the following algorithm:
Property | Value | |
---|---|---|
ILASM_v1.0.3705 | C:\tools\ilasm.exe | .NET v1.0.3705 assemblies will use this version of ilasm. |
ILDASM_v2.0.50215 | C:\tools\ildasm.exe | .NET v2.0.50215 assemblies will use this version of ildasm. |
ILDASM_v1.1 | C:\tools\ildasm.exe | .NET v1.1.xxxx assemblies will use this version of ilasm. |
Note: These properties are case sensitive.
If Dotfuscator cannot find one or both of these programs, it issues an error.
Dotfuscator uses the strong naming tool (sn.exe
) to automatically resign your strong named assemblies.
This tool also ships with the .NET Framework SDK and Dotfuscator searches for it in the same directory as ildasm.
Dotfuscator Version 4.33.0.6680. Copyright © 2017 PreEmptive Solutions, LLC