Config File Reference
Dotfuscator config files contain information about how a given application is to be protected.
The config file is an XML document conforming to dotfuscator_v2.5.dtd
(or one of its predecessors) and usually has the .xml
extension.
This page documents Dotfuscator's config file format, with detailed descriptions of each configuration option. You can use this page as guidance when editing a config file in a text editor. There are additional ways to work with config files, such as modifying a config file with the Config Editor on Windows, or generating a config file with the MSBuild targets or the command line interface.
- Version
- Property List and Properties
- Global Option Section
- Input Management
- Library Option
- Verbose, Quiet, and Investigate Options
- SuppressIldasm Global Option
- Force IL Tools from NuGet
- Debugging Options
- NoDotfuscatorAttribute Option
- MonoCompat option
- Input Assembly List
- Library Mode By Assembly
- Declarative Obfuscation By Assembly
- Check Processing By Assembly
- Transform XAML By Assembly
- User Defined Assembly Load Path
- Output Directory
- Temp Directory
- Obfuscation Attribute Feature Map
- Renaming Section
- Renaming Scheme
- Renaming Options
- Renaming Exclusion List
- Renaming Referenced Rules
- Output Mapping File
- HTML Renaming Report
- Input Mapping File
- Control Flow Obfuscation Section
- String Encryption Section
- Removal Section (a.k.a. Pruning)
- Disable Removal Option
- ConstOnly Option
- Removal Trigger List
- Conditional Includes List
- Removal Referenced Rules
- Removal Report
- Linking Section
- PreMark Section
- Signing Section
- EventList Section
- Checks Section
- Extended Attributes Section
- SmartObfuscation Section
- Target Platform Specific Configuration
- A Note about XML Config Files
- Custom Rules
Version
The .xml file version attribute must be present and must be applicable to your version of Dotfuscator. It should match the version number of the DTD to which it conforms. Point releases of Dotfuscator are designed to be able to use unmodified config files from earlier versions. For example, you should be able to run Dotfuscator 1.1 using a version 1.0 config file without having to edit the config file.
Version:
<dotfuscator version="2.2">
Property List and Properties
The optional <propertylist>
section allows for the definition and assignment of variables known as <properties>
that may be used later in the config file.
Property definitions defined in this section are referred to as config properties.
Config Properties:
<!-- define expandable properties -->
<!-- optional -->
<propertylist>
<property name="name" value="myapp"/>
<property name="outdir" value="c:\myapp\out"/>
</propertylist>
Variables, or property references, may be used in the config file without being defined in this section. For example, they may be defined on the command line or come from the environment. Properties work via string substitution, using the following algorithm to find a value associated with the property:
- Check the external property list for a value.
- If not found, check for an environment variable with the same name as the property,
- If not found, check for a config definition in the propertylist section of the config file,
- If still not found, use the empty string as the value.
External properties are passed in on the command line using the -p
option.
There are three built-in external properties:
applicationdir
, which reflects Dotfuscator's installation directory.appdatadir
, which reflects Dotfuscator's local data directory.configdir
, which reflects the directory in which the config file resides.
Properties are useful for creating config files that act as templates for multiple applications, for different versions of the same application, or for simple portability across different build environments. A property is referenced with the following syntax:
Property Syntax:
${property_name}
Property references are case sensitive, therefore ${OutDir}
references a different property than does ${outdir}
.
Property values can reference other property values.
Currently, property references may only be used as values in the dir
or name
attributes of the <file>
element, and not just anywhere in the config file.
Here is a list of sections that use the <file>
element:
- inputassembly
- mapinput
- mapoutput
- output
- tempdir
- assembly
- removalreport
- transform
- key
- loadpaths
- program
- filelist
- smartobfuscationreport
- pfx
A property reference is interpreted literally in any other place in the config file.
Here is an example of a property reference in use:
<output>
<file dir="${testdir}/output"/>
</output>
Global Option Section
The global option section is for defining configuration options that apply across the entire run. This section describes each option in detail. This section is not required.
Input Management
There are two modes for Input Management: manual
(the default) and automatic
.
This option controls how Dotfuscator determines which inputs to process.
manual
means that the Dotfuscate task, when called from MSBuild, will merge the inputs from the InputAssemblies property and the inputs listed in the config file.
This merge is performed every time Dotfuscate is called, and does not modify the config file.
automatic
means that the Dotfuscate task, when called from MSBuild, will only use the inputs specified by the InputAssemblies property.
The inputs specified in the config file will be ignored.
As part of the Dotfuscate task, the config file will be automatically updated to reflect the inputs provided to the task.
This way, if you open the config file in the Dotfuscator Config Editor, you can make changes to the config in light of the most recent inputs as determined by MSBuild.
Regardless of this setting, during a build the Properties property values given to the Dotfuscate task will be merged (during the build) with properties specified in the config file. However, the Properties will not be saved.
automatic
value is only compatible with the Dotfuscate
MSBuild task.
If you enabled automatic
, you will not be able to build via the Dotfuscator Config Editor or command line.
automatic
.
Input Management Setting:
<global>
<input_management>automatic</input_management>
</global>
Library Option
This option was deprecated in Dotfuscator 3.0. It has been replaced with a more granular library option that can be applied to individual input assemblies. When reading older config files, Dotfuscator reads this option and honors it, but the Config Editor saves the config file using the new options. See Library Mode By Assembly.
Library Option:
<global>
<!-- set library option -->
<option>library</option>
</global>
Verbose, Quiet, and Investigate Options
These options are the same as the corresponding command line options and can be enabled either in the config file or from the command line. There is no way to unset an option from the command line.
Verbose, Quiet, and Investigate Options:
<global>
<!-- run in verbose mode -->
<option>verbose</option>
<!-- run in quiet mode -->
<option>quiet</option>
<!-- investigate only and generate a map -->
<option>investigate</option>
</global>
SuppressIldasm Global Option
Setting this option tells Dotfuscator to prevent Microsoft's ILdasm utility from displaying the assembly IL. Enabling this option also prevents Visual Studio from decompiling source code with the "Navigate to Decompiled Sources" feature. This is only valid for assemblies targeting .NET 2.0 and above.
SuppressIldasm Global Option:
<global>
<option>suppressildasm</option>
</global>
Force IL Tools from NuGet
This option prioritizes the use of ILasm/ILdasm tools obtained via NuGet over those from locally installed .NET Framework on Windows for the assemblies that target .NET Framework.
The option only applies to Dotfuscator when it runs on Windows, and is ignored otherwise, because, outside Windows, the tools obtained via are always used NuGet.
In Dotfuscator, for obfuscating assemblies that target .NET Framework, locally installed ILasm and ILdasm tools from .NET Framework framework are used, unless you specify the force_nuget_tools
option. For other targets, such as .NET Core or .NET 5.0 or later, Dotfuscator obtains ILasm/ILdasm tools via NuGet on any operating system, thus for such targets this option is ignored.
<global>
<option>force_nuget_tools</option>
</global>
Debugging Options
Setting one of the options below causes Dotfuscator to produce debugging symbols along with the output assemblies.
These options correspond to the -debug
switch on the command line and the Emit Debugging Symbols option in the Config Editor.
Config File Global Option | Command Line Switch | Config Editor Description |
---|---|---|
(none) | (none) or -debug:off |
Never |
DebugAuto |
-debug:auto |
Automatically Based on Input Assemblies |
Debug (deprecated) |
-debug:on |
No JIT Optimization; Sequence Points from PDB (deprecated) |
DebugImpl (deprecated) |
-debug:impl |
No JIT Optimization; Sequence Points from MSIL (deprecated) |
DebugOpt (deprecated) |
-debug:opt |
JIT Optimization; Sequence Points from MSIL (deprecated) |
Pdb (deprecated) |
-debug:pdb |
JIT Optimization; Sequence Points from PDB (deprecated) |
Debugging symbols contain information such as source file paths, local variable names, and line numbers. They are usually stored in separate PDB files in the same directory as the assemblies. Debuggers use this information to set breakpoints and determine the values of expressions while debugging.
With one of the Debugging options enabled, Dotfuscator will read existing debugging symbols for input assemblies and produce debugging symbols updated to reflect changes made by Dotfuscator.
You can then continue to debug your application against the original source code and set breakpoints in the obfuscated code.
These settings also affect the DebuggableAttribute
attached to each assembly, which tells the .NET runtime how to allow for debugging, such as by disabling JIT (just-in-time) optimizations.
If none of these options are set, Dotfuscator will not produce any debugging symbols for the output assemblies, regardless of any symbols present for the input assemblies.
Any instances of the DebuggableAttribute
in the input assemblies will be removed in the output assemblies.
DebugAuto Option
The DebugAuto
option causes Dotfuscator to automatically create updated debug symbols for output assemblies in the same format as the symbols for the corresponding input assemblies.
<global>
<option>debugauto</option>
</global>
This setting can produce Portable PDBs as well as the PDBs in the original .NET Framework format, depending on the kind of symbols present with each input assembly.
For input assemblies with no associated debugging symbols, Dotfuscator will not produce any corresponding output symbols.
Any DebuggableAttribute
present in the input assemblies will be preserved as-is in the output assemblies.
This setting supports assemblies that do not reference the mscorlib
assembly, including .NET Core and .NET Standard assemblies.
This setting does not support assemblies targeting .NET 1.0 or 1.1.
Please use Debug
instead.
Debug, DebugImpl, DebugOpt, and Pdb Options
Each of these four options causes Dotfuscator to create debug symbols for all output assemblies in the original .NET Framework PDB format.
<!-- Create a PDB file,
set DebuggableAttribute to:
disable JIT optimization and
use sequence points from the PDB file -->
<global>
<option>debug</option>
</global>
<!-- Create a PDB file,
set DebuggableAttribute to:
disable JIT optimization and
use implicit sequence points from the assembly's IL -->
<global>
<option>debugimpl</option>
</global>
<!-- Create a PDB file,
set DebuggableAttribute to:
enable JIT optimization and
use implicit sequence points from the assembly's IL -->
<global>
<option>debugopt</option>
</global>
<!-- Create a PDB file,
don't set a DebuggableAttribute, runtime defaults to:
enabled JIT optimization and
using sequence points from the PDB file -->
<global>
<option>pdb</option>
</global>
These settings will only produce PDBs in the original .NET Framework format, even for input assemblies that use Portable PDBs.
For input assemblies with no associated debugging symbols, Dotfuscator will produce output symbols with source file and line number information based on the .NET intermediate language (IL), not any high-level source language (such as C#).
Any DebuggableAttribute
present in the input assemblies will be removed.
Depending on the setting, a new DebuggableAttribute
will be added to the assembly, with the meaning explained in the XML comments above.
These settings only support assemblies that reference the mscorlib
assembly.
If one of these options is specified and an input assembly doesn't reference mscorlib
(e.g., it is a .NET Core or .NET Standard assembly), the resulting output assembly will have no debugging symbols and all instances of DebuggableAttribute
will be removed.
The DebugImpl
, DebugOpt
, and Pdb
options are only supported for assemblies targeting .NET 2.0 or later.
If one of these options is specified and an input assembly targets an earlier version of .NET, the resulting output assembly will have no debugging symbols and all instances of DebuggableAttribute
will be removed.
NoDotfuscatorAttribute Option
Dotfuscator, by default, inserts a custom attribute into your application named DotfuscatorAttribute
.
The attribute contains information about the Dotfuscator version used to obfuscate the program, including product ID (Community vs. Professional) and version numbers.
If you prefer not to insert the DotfuscatorAttribute
, you can disable it by manually setting an option in the config file, called nodotfuscatorattribute
.
NoDotfuscatorAttribute Option:
<global>
<option>nodotfuscatorattribute</option>
</global>
MonoCompat option
Some of Dotfuscator's transforms are useful in protecting apps for .NET Framework and .NET Core, but can cause runtime issues when running on Mono (including Xamarin and MAUI apps).
To disable these transforms, set the monocompat
global option.
<global>
<option>monocompat</option>
</global>
This global option corresponds to the Config Editor setting Use only Mono-compatible transforms. If the setting is Yes, the global option will be present in the config file.
When creating a new config file in the Config Editor, this global option is not present, so the protected app will not be Mono-compatible.
When creating a new config file via the MSBuild targets, this global option is present, so the protected app will be Mono-compatible.
Input Assembly List
The input assembly list contains the file names and directories of the assemblies and/or packages you want to obfuscate. It also contains configuration options that are set at the package or assembly level.
If you have a multi-module assembly, only list the module containing the manifest.
Input Assembly List:
<input>
<asmlist>
<inputassembly>
...
<file dir="c:\temp" name="myproj.dll"/>
</inputassembly>
...
</asmlist>
</input>
Library Mode By Assembly
To specify Library Mode for an input assembly, add a library
option to its <inputassembly>
element.
<inputassembly>
<option>library</option>
...
</inputassembly>
Declarative Obfuscation By Assembly
Enabling or Disabling Declarative Obfuscation
To enable Declarative Obfuscation for an input assembly, add an honorOAs
option to its <inputassembly>
element.
<inputassembly>
<option>honoroas</option>
...
</inputassembly>
Stripping Obfuscation Attributes
To enable obfuscation attribute stripping for an input assembly, add a stripOA
option to its <inputassembly>
element.
<inputassembly>
<option>stripoa</option>
...
</inputassembly>
Check Processing By Assembly
Dotfuscator allows you to control code injection of Checks for specific input assemblies. This section describes the effects of setting these options.
When Checks are enabled, Dotfuscator honors and strips unnecessary Check attributes from the output assemblies. This default behavior can be overridden at the input assembly level by specifying one or both:
nohonorsos
prevents Dotfuscator from processing Check attributes declared in the assembly.nostripsos
prevents Dotfuscator from stripping unnecessary Check attributes from the assembly after processing them.
Check Processing by Assembly:
<inputassembly>
<!-- Do not strip Check attributes -->
<option>nostripsos</option>
<!-- Do not honor Check attributes -->
<option>nohonorsos</option>
...
</inputassembly>
Transform XAML By Assembly
This setting tells Dotfuscator that a particular input assembly may contain markup, either XAML as found in Universal Windows applications or compiled XAML resources (BAML) as found in Windows Presentation Foundation applications; and any markup should be analyzed and included for renaming. For Dotfuscation purposes, markup that is transformed will have identifiers renamed in conjunction with any code-behind references of the elements. Properties that are referenced from markup resources will have their property metadata retained but will be renamed.
To specify Transform XAML mode for an input assembly, add an <option>
element to its <inputassembly>
element.
Transform XAML Mode by Assembly:
<inputassembly>
<option>transformxaml</option>
<file dir="c:\temp" name="myproj.dll"/>
</inputassembly>
User Defined Assembly Load Path
Dotfuscator needs to load assemblies referenced by your input assemblies in order to discover information about types you are using in your input assemblies. Dotfuscator uses discovery rules similar to the rules used by Visual Studio and the CLR itself.
If a referenced assembly cannot be found using the default search rules, Dotfuscator provides a way for you to specify additional directories in which to look for referenced assemblies. Dotfuscator searches these directories in the specified order as the last step in its algorithm. However, if the prepend option (the Search First checkbox in the Settings Tab) is used, then Dotfuscator searches the load path before applying its standard search.
To add a User Defined Assembly Load Path to your XML config file:
Adding a User Defined Assembly Load Path:
<input>
<loadpaths>
<option>prepend</option>
<file dir="C:\temp" />
...
</loadpaths>
....
</input>
Output Directory
This is the directory where output assemblies are written. The application always overwrites files in this directory without prompting the user.
Output Directory:
<!-- destination directory is required -->
<output>
<file dir="c:\work"/>
</output>
Temp Directory
This section is optional and specifies Dotfuscator's working directory. If not specified, the working directory defaults to the system's temporary directory. The application uses the working directory to run ILdasm and ILasm on the input assemblies. The disassembled output is stored in this directory along with any resources embedded in the input assemblies. These files are automatically deleted after processing.
Temp Directory:
<!-- scratch directory is optional -->
<!-- If absent, defaults to system's temp dir -->
<tempdir>
<file dir="c:\temp"/>
</tempdir>
Obfuscation Attribute Feature Map
The feature map is for Declarative Obfuscation. For a complete description of Dotfuscator's support for Declarative Obfuscation, see Declarative Obfuscation via Custom Attributes. That section describes the Feature Map and lists the native feature strings that Dotfuscator understands.
In the config file, the <obfuscationattributemap>
element is where you can map strings obtained from an obfuscation attribute's Feature property to one or more feature strings that Dotfuscator understands.
Here is what such a mapping looks like in the XML config file:
Obfuscation Attribute Feature Map:
<obfuscationattributemap>
<feature name="testmode">renaming, controlflow</feature>
</obfuscationattributemap>
Renaming Section
The renaming section allows you to specify options that are specific to renaming, input and output mapping file locations, and fine-grained rules for excluding items from renaming.
The renaming section is optional. If not present, the following defaults apply:
- Default renaming (namespaces are removed).
- New names are chosen using the
lowalpha
renaming scheme. - No mapping file is read for Incremental Obfuscation.
- The mapping file is written to {CurrentWorkingDir}/Dotfuscator/Map.xml.
- No exclusions beyond those dictated by your application type.
The section on identifier renaming describes the renaming options, the mapping file, and custom exclusions in great depth. The following sections present an overview of each.
Renaming Scheme
Dotfuscator allows you to choose from several predefined algorithms for generating obfuscated identifier names:
- Low Alpha: This is the default renaming scheme used by all versions of Dotfuscator and uses lower case alphanumeric characters:
{a,b,c,...}
- Upper Alpha: This scheme uses upper case alphanumeric characters:
{A,B,C,...}
- Numeric: This scheme uses numeric characters only:
{0,1,2,...}
- Unprintable: This scheme uses unprintable, high Unicode code points.
The renaming scheme is an attribute of the <renaming>
element.
Allowable values are lowalpha
, upperalpha
, numeric
, and unprintable
.
Renaming Scheme:
<renaming scheme="unprintable">
...
</renaming>
Renaming Options
When you use the disable
option, Dotfuscator skips the renaming step altogether, regardless of what's in the rest of the renaming section.
Disable Renaming Option:
<renaming>
<!--Skip renaming, ignoring rest of section-->
<option>disable</option>
...
</renaming>
Dotfuscator allows several options that govern how namespaces
are treated by the renaming algorithm.
These are: "keepnamespace
" and "keephierarchy
" and are explained in detail in the section on identifier renaming.
Dotfuscator allows you to specify that obfuscated type names must be prefixed with a default or user-specified string.
To use this feature, specify the prefix
option.
Please see Renaming Prefixes for full details.
Turning on the Renaming Prefix Feature:
<renaming>
<!-- this turns on the renaming prefix feature -->
<option>prefix</option>
...
</renaming>
Dotfuscator also allows an enhanced level of Overload Induction that adds return type to the mix.
The option to turn this on is: enhancedOI
and is explained in detail in the section on overload induction method renaming.
Apply Enhanced Overload Induction:
<renaming> <!-- Apply Enhanced Overload Induction. -->
<option>enhancedOI</option>
...
</renaming>
Enhanced Overload Induction is, by default, not applied to classes marked as serializable.
If you wish to apply enhanced overload induction to all types, including serializable types, use the enhancedOIOnSerializables
option:
Apply Enhanced Overload Induction Serializable Option:
<renaming>
<!-- Apply enhanced Overload Induction even on serializable types. -->
<option>enhancedOIOnSerializables</option>
...
</renaming>
You can change the renaming algorithm to rename types and members in a way that's compatible with the XML Serializer.
Change Renaming Algorithm to be Compatible with XML Serializer:
<renaming>
<!-- XML Serialization compatibility. -->
<option>xmlserialization</option>
...
</renaming>
For more information, see XML Serialization and Renaming.
You can prevent managed resources from being renamed by using the keepManagedResourceNames
option. This option is explained in detail in the section on Class Renaming Options.
<renaming>
<!-- this prevents managed resources from being renamed -->
<option>keepManagedResourceNames</option>
...
</renaming>
Using the <randomizeRenaming>
option causes Dotfuscator to assign the new names in a non-linear order.
So instead of assigning Low Alpha names in the order {a, b, c, d,...}, you would get something more like {u, p, k, f,...}.
This option will work with any Renaming Scheme.
Use Random Name Assignment:
<renaming>
<!-- Use random name assignment -->
<option>randomizeRenaming</option>
...
</renaming>
Renaming Exclusion List
This section provides a dynamic way to fine tune the renaming of the input assemblies. It can contain a list of exclusion rules that are applied at runtime. If a rule selects a given class, method, field, property, or event then that item is not renamed.
- These rules are applied in addition to rules implied by global options such as the library option.
- The rules are logically
OR
-ed together, so any item that is selected by at least one rule is not renamed. - The exclusion list has support for excluding names by type, method, field, property, event, assembly, module, or namespace.
- Each type of rule is explained in detail in the section on identifier renaming.
Renaming Referenced Rules
Referenced rules allow you to import rules from an external file so they can be shared among configurations.
Dotfuscator's Built-In renaming rules use this to import rules from Dotfuscator's Common
directory, which can be found in the same directory as your dotfuscator installation.
The rule is referenced via the rulekey
attribute whose value is a GUID defined by the rule being referenced.
Reference Rule List:
<referencerulelist>
<referencerule rulekey="{0D471A86-E98F-4493-849B-85BD4CC884A1}"/>
<referencerule rulekey="{C9D9BF84-4F0D-4e9f-B3EC-3038235AE741}"/>
</referencerulelist>
Output Mapping File
This feature of Dotfuscator produces a log of all the renaming mappings used by Dotfuscator during a specific run. It also provides a statistics section.
Specifying this option instructs Dotfuscator's renamer to keep track of how things were renamed for both your immediate review and for possible use as input in a future Dotfuscator run. A file is created from this option that is then used in the incremental input file option.
Accidental loss of this file can destroy your chances of incrementally updating your application in the future. Therefore, proper backup of this file is crucial. For this reason, Dotfuscator automatically renames an existing map file with the same name before overwriting it with a new version of the map file.
If you do not want Dotfuscator to rename existing map files before overwriting, set the attribute overwrite="true"
.
The format of the mapping file is discussed in the section on identifier renaming.
Setting the Attribute to Overwrite:
<renaming>
...
<mapping>
<mapoutput overwrite="true">
<file dir="c:\work" name="testout.xml"/>
</mapoutput>
</mapping>
</renaming>
HTML Renaming Report
The output mapping file is natively formatted as an XML document suitable for parsing.
For a human readable renaming report, you can tell Dotfuscator to transform the output mapping file into an HTML formatted document.
Dotfuscator will apply a predefined XSL document to the mapping file to accomplish the transformation.
If you do not like the default HTML report, you can optionally specify your own XSL document to use for the transformation.
The output report is placed in the same directory as the XML formatted mapping file.
The filename will be the same as the XML file, but will have a .html
extension rather than a .xml
extension.
HTML Renaming Report:
<renaming>
...
<mapping>
<mapoutput overwrite="true">
<file dir="c:\work" name="testout.xml"/>
<transform>
<!-- specifying your own XSL file is optional -->
<file dir="c:\mytransforms" name="map.xsl"/>
</transform>
</mapoutput>
</mapping>
</renaming>
Input Mapping File
In Dotfuscator, the input mapping file allows you to import names that Dotfuscator created in a previous run (a process known as Incremental Obfuscation). Dotfuscator will make a best-effort attempt to rename classes, methods, and fields to the names indicated in the input mapping file.
The <mapinput>
element allows you to specify the input mapping file.
It also has an optional obfuscatereferences
attribute, which defaults to "true
" if not present.
This attribute controls how Dotfuscator handles names contained in the input mapping file that are not defined within the set of input assemblies.
When true, references to these names within the current set of input assemblies will be renamed.
Input Mapping File:
<renaming>
...
<mapping>
<mapinput obfuscatereferences="true">
<file dir="c:\work" name="testin.xml"/>
</mapinput>
</mapping>
</renaming>
Control Flow Obfuscation Section
The control flow section allows you to specify options that are specific to control flow obfuscation, including fine-grained rules for excluding items from control flow obfuscation.
The control flow section is optional. If not present, control flow obfuscation is disabled.
Control Flow Obfuscation Level
The level of control flow obfuscation may be set to one of three values: "low
", "medium
", or "high
".
These levels correspond to the aggressiveness of Dotfuscator's control flow obfuscation algorithms.
A higher level generally results in stronger obfuscation at the cost of increased code size and degraded performance.
This is because more aggressive control flow obfuscation involves adding more branch instructions to the code.
The level of control flow obfuscation applies globally to all methods being obfuscated.
Control Flow Obfuscation Options
When you use the disable
option, Dotfuscator skips control flow obfuscation altogether, regardless of what's in the rest of the control flow section.
Disable Control Flow Option:
<controlflow level="high">
<!-- Skip control flow, ignoring rest of section-->
<option>disable</option>
...
</controlflow>
Control Flow Exclusion List
This section provides a dynamic way to fine tune control flow obfuscation of the input assemblies. It can contain a list of exclusion rules that are applied at runtime. If a rule selects a given class or method, then that item is not subject to control flow obfuscation.
The rules are logically OR
-ed together, so any item selected by at least one rule is not subject to control flow obfuscation.
The exclusion list has support for excluding methods by type, method, assembly, module, or namespace.
Each type of rule is explained in detail in the section on control flow obfuscation.
String Encryption Section
The string encryption section allows you to specify options that are specific to string encryption, including fine-grained rules for specifying types and methods subject to string encryption.
The string encryption section is optional. If not present, string encryption is disabled.
String Encryption Options
When you use the disable
option, Dotfuscator skips string encryption altogether, regardless of what's in the rest of the string encryption section.
Disable String Encryption Option:
<stringencrypt>
<!--Skip string encryption, ignoring rest of section-->
<option>disable</option>
...
</stringencrypt>
String Encryption Inclusion List
This section provides a dynamic way to fine tune string encryption of the input assemblies. It contains a list of inclusion rules that are applied at runtime. If a rule selects a given class or method, then that item is subject to string encryption.
The rules are logically OR-ed together, so any item that is selected by at least one rule is subject to string encryption.
The inclusion list has support for including methods by type, method, assembly, module, or namespace.
Each type of rule is explained in detail in the section on user string encryption.
Removal Section (a.k.a. Pruning)
The <removal>
section allows you to specify options that are specific to the removal functionality and fine-grained rules for specifying types and members subject to removal.
The <removal>
section is optional.
If not present, removal is disabled and no removal occurs.
Disable Removal Option
When you use the disable
option, Dotfuscator skips the removal step altogether, regardless of what's in the rest of the removal section.
<removal>
<!--Skip removal (pruning), ignoring rest of section-->
<option>disable</option>
...
</removal>
ConstOnly Option
This option is used to enable Constant-Only Removal. In this mode, only constant declarations will be removed. Unused types, methods, and fields will be propagated to the output assembly.
Removal Option:
<removal>
<!--Use Constant-Only Removal instead of full Removal-->
<option>constonly</option>
...
</removal>
Removal Trigger List
In the context of Removal, triggers are starting points for the static dependency analysis that Dotfuscator performs in order to determine which types, methods, and fields are used by your code. In other words, these are the entry points for your application or library.
Triggers are analyzed by Dotfuscator to determine which classes, methods, and fields are required for your application or library to function. For example, all methods called by your triggers, and methods called by those methods, are deemed required by Dotfuscator. That is, if you tell Dotfuscator a specific main method is required, then all the methods that main method calls are required as well.
A trigger list is not required, but is honored, if the library option is used.
The trigger list is used in addition to triggers implied by options such as the library option.
The trigger list specifies triggers in the same way that elements are selected for exclusion and inclusion in other parts of the configuration. It contains a list of rules that are applied at runtime. If a rule selects a given method or field, then that becomes a trigger.
The rules are logically OR
-ed together, so any item that is selected by at least one rule becomes a trigger.
The trigger list has support for specifying fields, methods, properties, and events by type, method, assembly, module, or namespace.
Each type of rule is explained in detail in the section on Removal.
Conditional Includes List
A type must be conditionally included if it is not detectable by the static dependency analysis, i.e. if it is dynamically loaded; meaning, the type itself is included in the dependency analysis, but its members are still subject to removal. Please see Understanding Include Triggers and Conditional Includes for a deeper explanation of this feature.
This section provides a dynamic way to specify conditionally included types. It contains a list of inclusion rules that are applied at runtime. If a rule selects a given type, then that item is conditionally included.
The rules are logically OR
-ed together, so any item that is selected by at least one rule will be conditionally included.
The inclusion list has support for selecting types by name, assembly, module, or namespace.
Each type of rule is explained in detail in the section on Removal.
Removal Referenced Rules
Referenced rules allow you to import rules from an external file so they can be shared among configurations.
Dotfuscator's Built-In removal rules use this to import rules from the dotfuscatorReferenceRule
XML file.
The rule files can be found in the Common
directory located in the same folder as your Dotfuscator installation.
The rule is referenced via the rulekey
attribute whose value is a GUID defined by the rule being referenced.
Referenced Rules:
<referencerulelist>
<referencerule rulekey="{0D458786-E99F-4593-849B-8512493884A1}"/>
<referencerule rulekey="{C1159284-4F0D-4e9f-B3EC-303828419741}"/>
</referencerulelist>
Removal Report
The removal report provides a summary of all the elements removed by Dotfuscator during a specific run, including a statistics section. Dotfuscator writes the removal report in a parsable and easily transformed XML format. Like the renaming map file, Dotfuscator has a default transform that can generate a human readable HTML formatted version of the report.
Dotfuscator automatically renames an existing removal report with the same name before overwriting it with a new version.
If you do not want Dotfuscator to rename existing removal reports before overwriting, set the attribute overwrite="true"
.
The XML format of the removal report file is discussed in the section on Removal.
Removal Report:
<removal>
<removalreport overwrite="true">
<file dir="c:\work" name="report.xml"/>
<transform>
<!-- specifying your own XSL file is optional -->
<file dir="c:\mytransforms" name="removal.xsl"/>
</transform>
</removalreport>
</removal>
Linking Section
The linking section allows you to specify options that are specific to the assembly linking. For more information about the linker, see Assembly Linking.
The linking section is optional. If not present, assembly linking is disabled.
Disable Linking Option
When you use the disable
option, Dotfuscator skips the linking step altogether, regardless of what's in the rest of the linking section.
<linking>
<!--Skip linking, ignoring rest of section-->
<option>disable</option>
...
</linking>
Linked Assemblies
A <linkedassembly>
element specifies that one or more input assemblies should be linked into a specified output assembly.
The linking section can contain multiple <linkedassembly>
elements; therefore, you can use the linker to create multiple output assemblies.
The only limitation is that you cannot link the same input assembly into multiple output assemblies.
The <linkedassembly>
element contains sub-elements that allow you to specify options for the link step, such as the name mangling policy, the primary assembly, the list of input assemblies, and the name of the output assembly.
Options
Currently the only option you can specify is the name mangling policy, which may be one of:
- donotmangle
- manglesilently
- mangleandwarn
Primary Assembly
The <primaryinput>
element identifies the prime assembly whose manifest information is used to create the output assembly's manifest.
This assembly must also be listed in the subsequent <assemblylist>
element.
Assemblies to Link
The assemblies you want to link are listed using an <assemblylist>
element.
Each must also be listed as an input assembly.
Output Assembly
The <outputassembly>
element allows you to specify a name for the output assembly and an optional entry point method.
The assembly is written to the destination directory with the given name.
Example
The example <linkedassembly>
element specifies that input assemblies Driver.exe
and LibraryC.dll
should be linked into an assembly named out.exe
.
The entry point method is explicitly set to the Main
method in the Driver
assembly.
Linked Assembly:
<linkedassembly>
<option>donotmangle</option>
<primaryinput>
<assembly>
<file dir="${configdir}" name="Driver.exe" />
</assembly>
</primaryinput>
<assemblylist>
<assembly>
<file dir="${configdir}" name="Driver.exe" />
</assembly>
<assembly>
<file dir="${configdir}" name="LibraryC.dll" />
</assembly>
</assemblylist>
<outputassembly name="out.exe">
<entrypoint>
<type name="Driver.Form1">
<method name="Main" signature="" />
</type>
</entrypoint>
</outputassembly>
</linkedassembly>
PreMark Section
The premark section allows you to specify options that are specific to watermarking. For more information about watermarking assemblies, see Watermarking.
PreMark Options
The watermarker supports several configuration options.
The usepassphrase
option tells the watermarker to encrypt the watermark string before applying it to the selected assemblies.
The truncatestring
option tells the watermarker to truncate the watermark string if it will not fit in a given assembly.
The default action is to halt the build if the watermark string is too large.
See Watermark String Length for more details.
When you use the disable
option, Dotfuscator skips the watermarking step altogether, regardless of what's in the rest of the premark section.
PreMark Options:
<premark>
<!--Skip watermarking, ignoring rest of section-->
<option>disable</option>
<!--Encrypt the watermark string -->
<option>usepassphrase</option>
<!--Truncate the string and continue if the string is too big -->
<option>truncatestring</option>
...
</premark>
PreMark Elements
The premark section contains sub-elements that allow you to specify which input assemblies you would like to watermark, a passphrase to use if you are encrypting your watermark string, a character encoding to use, and the watermark string itself.
Assemblies to Watermark
The assemblies you want to watermark are listed using an <assemblylist>
element.
Each must also be listed as an input assembly.
<passphrase>
The <passphrase>
element specifies the passphrase to use when encrypting the watermark string.
The watermark string will be encrypted if you have set the usepassphrase
option and the passphrase itself is set.
<encoding>
- The
<encoding>
element specifies the character encoding, or character map, to use when encoding the watermark string. The<encoding>
element has aname
attribute that you can set to a supported character map. Character maps and their names are described in the Character Maps section.
<watermark>
The <watermark>
element specifies the string that you want to apply to the selected assemblies.
The string is first encoded using the character map, then optionally encrypted.
Example
This example configures PreMark to apply a watermark to MyApp.exe
.
The watermark string, MY WATERMARK
is first encoded using the 6bit-a
character map, then encrypted with the passphrase "mommy
".
PreMark Elements:
<premark>
<option>usepassphrase</option>
<option>truncatestring</option>
<assemblylist>
<assembly>
<file dir="${configdir}" name="MyApp.exe" />
</assembly>
</assemblylist>
<passphrase>mommy</passphrase>
<encoding name="6bit-a" />
<watermark>MY WATERMARK</watermark>
</premark>
Signing Section
The signing section allows you to specify if and how you want Dotfuscator to sign your strongly named output assemblies. For more information about assembly signing, see Obfuscating Strong Named Assemblies. The signing section is optional. If not present, your strongly named input assemblies will not be resigned after Dotfuscator runs.
Specifying <key> Element
You can specify the key or key pair that you want Dotfuscator to use when signing with a <key>
element.
A <key>
element can contain either a <file>
or a <container>
sub element.
A <file>
element references the file containing the key or key pair.
A <container>
element has a "name
" attribute that specifies the name of the key container.
<file> Element:
<key>
<file dir="c:\temp" name="key.snk" />
</key>
<container> Element:
<key>
<container name="foo"/>
</key>
<resign> Element
To resign an assembly that was already signed before Dotfuscation, use a <resign>
element.
If the assembly has custom attributes that specify the key to use, you do not need a <key>
element.
If you wish to ignore the attributes, set the dontuseattributes
option and provide a <key>
element.
If the assembly does not have custom attributes that specify the key, you must provide a <key>
element.
This example tells Dotfuscator to ignore any custom attributes that specify the key and instead manually specifies a key file.
<resign> Element:
<signing>
<resign>
<option>dontuseattributes</option>
<key>
<file dir="c:\temp" name="key.snk" />
</key>
</resign>
...
</signing>
<delaysign> Element
If your input assembly is delay signed and you want Dotfuscator to automatically complete the signing process, you can provide a <delaysign>
element with a <key>
sub-element.
<delaysign> Element:
<signing>
...
<delaysign>
<key>
<file dir="c:\temp" name="key.snk" />
</key>
</delaysign>
</signing>
EventList Section
The eventlist section allows you to specify pre and post build events. For more information about Dotfuscator's build events, see Build Events.
The eventlist section is optional.
<event> Element
An event is essentially a program that Dotfuscator runs at a particular point in its build sequence.
You can specify the program name, working directory, and command line arguments.
In addition, an event can support additional configuration settings using an <option>
element.
An <event>
element has a type
attribute.
Currently Dotfuscator understands two event types: prebuild
and postbuild
.
The program to run is specified using a <program>
element.
Event <program> Element
The program to run when an event occurs is specified with the <program>
element.
It contains a <file>
element specifying the program and its location, as well as an <environment>
element that specifies command line arguments and working directory.
Like files and directories, the commandline
attribute can contain property macros.
Property Macros:
<program>
<file dir="c:\temp" name="copyfiles.bat" />
<environment commandline="${myproperty}" workingdir="c:\temp" />
</program>
Pre-Build Event Options
The pre-build event supports one option that can be set using an <option>
element nested within the <event>
element for the pre build event.
Option | |
---|---|
haltonfail | If the build event program returns a non-zero error code, halt the Dotfuscator build. |
Post-Build Event Options
The post-build event supports several options that can be set using an <option>
element nested within the <event>
element for the post build event.
Option | |
---|---|
haltonfail | If the build event program returns a non-zero error code, halt the Dotfuscator build. |
runoneachmodule | Run the post build event once for each output module. |
always | Run the post build event all the time, regardless of the success or failure of the Dotfuscator build. |
buildfails | Run the post build event only when the Dotfuscator build fails. |
buildsuccessful | Run the post build event only when the Dotfuscator build is successful. |
Example
The following example shows an XML config file fragment that sets up pre- and post-build events. The pre-build event executes the program c:\temp\copyfiles.bat with no arguments. If the build is successful, then the post-build event executes the program PEVerify on each output assembly. Notice that the output assembly name is passed as a property to PEVerify.
Example XML Config File Fragment:
<eventlist>
<event type="prebuild">
<program>
<file dir="c:\temp" name="copyfiles.bat" />
<environment commandline="" workingdir="c:\temp" />
</program>
</event>
<event type="postbuild">
<option>runoneachmodule</option>
<option>haltonfail</option>
<program>
<file dir="C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin" name="PEVerify.exe" />
<environment commandline="${dotf.current.out.module}"
workingdir="${dotf.destination}" />
</program>
</event>
</eventlist>
Checks Section
The Checks section allows you to specify options that control how Dotfuscator processes Check attributes in the input assemblies. For more information about Checks, see The Checks Editor.
The Checks section is optional and is defined by the sos
element.
When you use the disable
option, Dotfuscator skips Check processing altogether, regardless of what attributes are in the input assemblies and what settings are in the rest of the config.
Disable Checks Option:
<sos>
<!-- Disable Check processing -->
<option>disable</option>
</sos>
Extended Attributes Section
Dotfuscator allows you to tag methods or assemblies with extended attributes without modifying the application source code. Extended attributes can modify existing supported custom attributes in the code, or act as new instances of supported attributes. As it processes and transforms your application, Dotfuscator treats extended attributes the same as their custom attribute counterparts.
Supported attribute arguments may be specified using a <propertylist>
element.
Any attribute listed on the Check Attributes page is a supported attribute.
Extended attributes may be set at the method level. To identify the method, its defining type, name, and signature must be specified.
Example:
<extattributes>
<extattribute name="PreEmptive.Attributes.TamperCheckAttribute">
<type name = "MyApplicaton.MainForm">
<method name="Main" signature="string[]" />
</type>
<propertylist>
<property name="Action" value="Hang" />
<property name="ActionProbability" value=".5" />
<property name="ActivationStatusSinkElement" value="field" />
<property name="ActivationStatusSinkName" value="tampered" />
</propertylist>
</extattribute>
</extattributes>
SmartObfuscation Section
Smart Obfuscation allows Dotfuscator to auto detect elements that cannot be renamed or removed based on specific rules for the application type.
Smart Obfuscation is turned on by default, and in most cases should be left on.
It can be turned off by setting the disable
option in this section in cases where the user believes that aggressive obfuscation will not hurt the application.
Smart Obfuscation includes a reporting facility and this section allows you to configure the verbosity of the report.
Allowed values for the verbosity attribute are all
, warningsonly
, and none
.
The default value is all
.
The Smart Obfuscation report can optionally be written to disk.
Dotfuscator automatically renames an existing Smart Obfuscation report with the same name before overwriting it with a new version.
If you do not want Dotfuscator to rename the existing Smart Obfuscation report before overwriting, set the attribute overwrite="true"
.
The XML format of the Smart Obfuscation report is discussed in the Smart Obfuscation section.
SmartObfuscation:
<smartobfuscation>
<!-- Skip smart obfuscation, ignoring rest of section -->
<option>disable</option>
<smartobfuscationreport verbosity="all" overwrite="true">
<!-- Specifying a destination report file is optional -->
<file dir="c:\myapp" name="smartobfuscation.xml"/>
</smartobfuscationreport>
</smartobfuscation>
Target Platform Specific Configuration
Dotfuscator supports creating and using target platform-specific configuration files, which can be helpful for MAUI projects. By enabling this feature, Dotfuscator will create a separate configuration file for each of the target platforms specified. If your MAUI app targets Android, iOS, Mac and Windows platforms, Dotfuscator will generate DotfuscatorConfig_Android.xml, DotfuscatorConfig_iOS.xml, DotfuscatorConfig_MacCatalist.xml and DotfuscatorConfig_Windows.xml
To enable platform-specific configuration file support, add the following tag to the .csproj file:
<DotfuscatorUsePlatformSpecificConfig>true</DotfuscatorUsePlatformSpecificConfig>
Note that if you remove the tag from your project file, Dotfuscator will fall back to one configuration file behavior, which is the default for Dotfuscator.
A Note about XML Config Files
Dotfuscator uses XML formatted documents for the configuration and mapping files.
When loaded, these documents are validated according to the Document Type Definitions (DTDs) specified in the doctype
.
In order to perform the validation, Dotfuscator must be able to access the relevant DTD.
Dotfuscator takes the following steps to locate DTDs:
- If the DTD URI specifies a local file, Dotfuscator searches for it in the indicated location. If it is not found, an error occurs.
- If the DTD URI specifies a web resource, Dotfuscator first searches its cache for a file with the same name as that specified in the URI.
Dotfuscator keeps its cache in your installation's
Common
directory (e.g.,C:\Program Files (x86)\PreEmptive Protection Dotfuscator Professional A.B.C\Common
). - If not found, Dotfuscator accesses the URI to obtain the DTD. If found, Dotfuscator caches the DTD so subsequent requests will not need to access the network. If the DTD is not found, or if Dotfuscator is unable to retrieve it from the network, an error occurs.
Custom Rules
Dotfuscator allows you to customize obfuscation rules for your application.
Both Inclusion Rules and Exclusion Rules provide a dynamic way to fine tune the renaming, control flow obfuscation, string encryption, and removal of the input assemblies.
These rules are applied in addition to rules implied by options such as library and they are logically OR
-ed together.
Exclusion Rules
The exclude list section provides a dynamic way to fine tune the renaming and control flow obfuscation of the input assemblies. The user specifies a list of rules that are applied at runtime. If a rule selects a given class, method, or field, then that item is not renamed or is excluded from control flow obfuscation.
These rules are applied in addition to rules implied by options such as library.
Rules are logically OR
-ed together.
Regular Expressions (REs) may be used to select namespaces, types, methods or fields.
The optional regex
attribute is used for this purpose.
The default value of regex
is false.
If regex
is true then the value of the name
attribute is interpreted as a regular expression; if it is false, the name is interpreted literally.
This is important since regular expressions assign special meaning to certain characters, such as the period.
Here are some examples of simple, regular expressions:
.* Matches anything
MyLibrar. Matches MyLibrary, MyLibrari, etc.
My[\.]Test[\.]I.* Matches My.Test.Int1,My.Test.Internal, etc.
Get.* Matches GetInt, GetValue, etc.
Get* Matches Ge,Get,Gett,Gettt, etc.
Please refer to the .NET Framework documentation for a full description of the regular expression syntax.
Excluding Namespaces
This option excludes all types and their members in a given namespace. You can use a regular expression to specify the namespace.
Regular Expression:
<namespace name="My.Excluded.Namespace"/>
Excluding Types
This option excludes a type by name or by attribute specifier. You can use a regular expression to specify the type name. Type names must be fully qualified names. Inner (nested) classes are specified by using the '/' as a delimiter between outer and inner class. For example:
Inner (Nested) Classes:
<type name="Library.Class1/NestedClass"/>
Attribute specifiers are selected or deselected with the speclist
attribute.
The speclist
attribute is a comma-separated list of legal attribute specifiers for types.
The legal values are:
Legal Values:
abstract
interface
nestedassembly
nestedfamily
nestedfamorassem
nestedprivate
nestedpublic
notpublic
public
sealed
serializable
enum
A '-' preceding an attribute specifier negates the rule (i.e. it excludes all classes that do not have the specified attribute).
A '+' may be specified but is not required.
The rules implied in this list are logically AND-
ed together (that is, the set of excluded types is the intersection of all types that match each rule.).
For instance, the following rule excludes any type that is public AND sealed.
Exclude Public and Sealed Type Rule:
<type name=".*" speclist="+public,+sealed" regex="true"/>
The <type>
element may also be used to select a type in order to specify rules for field, method, property, and event exclusion within it.
This allows members to be excluded while not excluding their owning type.
The optional excludetype
attribute is used for this purpose.
If not specified, the default value is true
, meaning that the type name will be excluded from renaming or control flow obfuscation.
Specify Rules for Field, Method, Property, and Event Exclusion:
<type name="MyCo.Test.MyOtherTest" excludetype="false">
<!-- methods and fields excluded here -->
...
</type>
If a Type rule contains no Property or Event rules, then all property and event names in that excluded type are preserved. If a Type rule contains one or more Property rules, then only those property names will be preserved and all others will be removed. If a Type rule contains one or more Event rules, then only those event names will be preserved and all others will be removed.
Remember: If a type is not excluded and the library option is not set, then Dotfuscator removes property and event names.
Applies only to Renaming:
Type rules can be applied to entire inheritance hierarchies by specifying the applytoderivedtypes
attribute.
Setting the value of this attribute to true
will apply the type rule and any Method, Field, Property, Event, Custom Attribute, or Supertype rules that it contains to the selected type and all types that derive from it.
If not specified, the default value is false
, meaning that the type rule will only be applied to the specified type.
Excluding Methods
Methods may be excluded by first selecting the type using the <type>
element, then providing a rule for selecting methods to exclude.
Methods may be excluded by name and attribute specifier, as well as by signature.
Allowed attribute specifiers are:
abstract
assembly
family
familyorassembly
final
private
public
static
virtual
If the attribute specifier is not set explicitly, then the speclist
attribute will not be used as a matching criterion.
The following example selects all public instance methods beginning with Set:
<method regex="true" name="Set.*" speclist="+public,-static"/>
Method signatures are specified using the signature
attribute.
A signature specifies both the return type and the parameter types of the method:
Return Types and Parameter Types
signature="" <!-- empty signature -->
signature="string(int,MyClass,MyClass[])"
If the signature is not set explicitly, then the method signature will not be used as a matching criterion.
The following example selects a method by signature:
Method by Signature
<method name="DoIt" signature="string(int, System.Console, System.Collection.ICollection, float[])"/>
Global methods may be specified by using a special type selector with the name "Module:mod_name
" where mod_name
is the name of the module containing the global method.
Excluding Fields
Field exclusion is valid for Renaming only.
Fields may be excluded by first selecting the type using the <type>
element, then providing a rule for selecting fields to exclude.
Fields may also be excluded by name and attribute specifier.
Allowed Attribute Specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
notserialized
If the attribute specifier is not set explicitly, then field attribute will not be used as a matching criterion.
The following example selects all static fields starting with "ENUM_
":
All Static Fields Starting with "ENUM":
<field regex="true" name="ENUM_.*" speclist="+static"/>
Field signatures are specified using the signature
attribute.
A signature specifies the type of the field:
signature="" <!-- empty signature -->
signature="int"
If the signature is not set explicitly, then the field type will not be used as a matching criterion.
Global fields may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global field.
Excluding Properties
Property exclusion is valid for Renaming only. Property rules are qualified by type rules, so they appear in the rules view as children of type nodes. A property rule will select all properties (in all types matched by the parent type rule) that match your criteria. Supported matching criteria include property name and property attributes.
Allowed Attribute Specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
If the attribute specifier is not set explicitly, then the property attribute will not be used as a matching criterion.
The following example selects all properties starting with "Sample":
<propertymember regex="true" name="Sample.*"/>
Property signatures are specified using the signature
attribute.
A signature specifies the type of the property:
signature="" <!-- empty signature -->
signature="int"
If the signature is not set explicitly, then the property type will not be used as a matching criterion.
Global properties may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global property.
Excluding Events
Event exclusion is valid for Renaming only. Event rules are qualified by type rules, so they appear in the rules view as children of type nodes. An event rule will select all events (in all types matched by the parent type rule) that match your criteria. Supported matching criteria include event name and event attributes.
Allowed attribute specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
If the attribute specifier is not set explicitly, then the event attribute will not be used as a matching criterion.
The following example selects all events starting with "On":
<eventmember regex="true" name="On.*"/>
Global events may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global event.
Excluding By Custom Attribute
Types, methods, fields, and properties may be selectively excluded by custom attribute. A custom attribute rule selects an item (type, method, field or property) based on matching against the names of custom attributes that annotate the item. One or more custom attribute rules may be nested inside any rule that selects types, methods, fields, or properties.
A type, method, field, or property rule may have multiple custom attribute rules associated with it. In this case, an item is selected if at least one of the custom attribute rules selects it.
The following example selects all types that are annotated with either MyCustomAttribute
or MyOtherCustomAttribute
:
Types Annotated with MyCustomAttribute or MyOtherCustomAttribute:
<type name=".*" excludetype="false" regex="true">
<customattribute name="MyCustomAttribute"/>
...
<customattribute name="MyOtherCustomAttribute"/>
</type>
Custom attribute rules can also be written using regular expressions to match custom attribute names.
The following example is another way to select all types annotated with either MyCustomAttribute
or MyOtherCustomAttribute
:
Types Annotated with MyCustomAttribute or MyOtherCustomAttribute:
<type name=".*" excludetype="false" regex="true">
<customattribute name="My.*CustomAttribute" regex="true"/>
</type>
The next example shows how to exclude all methods annotated with a custom attribute named MyCustomAttribute
:
Exclude Annotated Methods
<type name=".*" excludetype="false" regex="true">
<method name=".*" regex="true">
<customattribute name="MyCustomAttribute"/>
</method>
</type>
Custom attribute rules can be applied to subtypes or overriding methods and properties by specifying the allowinheritance
attribute.
When the value of this attribute is set to true
then subtypes or overriding methods and properties with the specified custom attribute will also be excluded.
Excluding By Supertype
Types may be selectively excluded by supertype. A supertype rule selects a type based on matching against the names of types that the given type inherits from. One or more supertype rules may be nested inside any rule that selects types.
A type rule may have multiple supertype rules associated with it. In this case, an item is selected if at least one of the supertype rules selects it.
The following example selects all types that inherit from MySupertype
:
All Types that Inherit from MySupertype:
<type name=".*" excludetype="false" regex="true">
<supertype name="MySupertype"/>
</type>
Supertype rules can also be written using regular expressions to match supertype names.
The following example shows how to select all types that inherit from either MySupertype
or MyOtherSupertype
:
All Types that Inherit from MySupertype or MyOtherSupertype:
<type name=".*" excludetype="false" regex="true">
<supertype name="My.*Supertype" regex="true"/>
</type>
Excluding Assemblies
Assemblies may be excluded by name. When an assembly is excluded, all types and members within any of the assembly's modules are excluded. It makes sense to exclude an assembly when you have a scenario such as the following:
- Assembly A should be obfuscated.
- Assembly B should not be obfuscated.
- Assembly B depends on assembly A.
In other words, A provides services to B and no one else. You want the references to A embedded inside B to be obfuscated, so you include B in the same run as A, but you exclude B from renaming or control flow obfuscation.
Excluding Assemblies:
<assembly>
<file dir="c:\src\app1\" name="ExcludedLib.dll"/>
</assembly>
Excluding Modules
Modules may be excluded by name. Use the assembly attribute to qualify the module to a particular assembly. When specified, the assembly name should be the logical assembly name rather than its physical file name. When a module is excluded, all its defined types and members are excluded.
Obviously, if a given module is shared among multiple assemblies, then the module will be excluded from all the assemblies.
Module Excluded from all Assemblies:
<module name="MyLibResource.dll" assemblyname="MyLib"/>
Inclusion Rules
The include list section provides a dynamic way to fine-tune the string encryption and removal of the input assemblies. The user specifies a list of rules that are applied at runtime. If a rule selects a given class, method, field, property, or event then that item is included for string encryption or removal.
These rules are applied in addition to rules implied by options such as library.
Rules are logically OR
-ed together.
Regular Expressions (REs) may be used to select namespaces, types, methods, fields, properties, or events.
The optional regex
attribute is used for this purpose.
The default value of regex
is false.
If regex
is true then the value of the name
attribute is interpreted as a regular expression; if it is false, the name is interpreted literally.
This is important since regular expressions assign special meaning to certain characters, such as the period.
Here are some examples of simple regular expressions:
Regular Expressions:
.* Matches anything
MyLibrar. Matches MyLibrary, MyLibrari, etc.
My[\.]Test[\.]I.* Matches My.Test.Int1,My.Test.Internal, etc.
Get.* Matches GetInt, GetValue, etc.
Get* Matches Ge,Get,Gett,Gettt, etc.
Including Namespaces
This option includes all types and their methods in a given namespace. You can use a regular expression to specify the namespace.
Regular Expression:
<namespace name="My.Included.Namespace"/>
Including Types
This option includes a type by name or by attribute specifier. You can use a regular expression to specify the type name.
Type names should be fully qualified names.
Inner (nested) classes are specified by using the '/' as a delimiter between outer and inner class. For example:
Inner (Nested) Classes
<type name="Library.Class1/NestedClass"/>
Attribute specifiers are selected or deselected with the speclist
attribute.
The speclist
attribute is a comma-separated list of legal attribute specifiers for types.
The legal values are:
Attribute Specifiers:
abstract
interface
nestedassembly
nestedfamily
nestedfamorassem
nestedprivate
nestedpublic
notpublic
public
sealed
serializable
enum
A '-' preceding an attribute specifier negates the rule (i.e. it includes all classes that do not have the specified attribute).
A '+' may be specified but is not required.
The rules implied in this list are logically AND
-ed together (that is, the set of included types is the intersection of all types that match each rule.).
For instance, the following rule includes all methods within any type that is public AND sealed.
Include Method with Public and Sealed Types:
<type name=".*" speclist="+public,+sealed" regex="true"/>
The <type>
element may also be used to select a type in order to specify rules for individual method inclusion within it.
This allows string encryption in some methods of a type, while not in others.
Note the <type>
element's excludetype
attribute is not used in the context of string encryption inclusions.
Allow String Encryption in Some Methods of Type:
<type name="MyCo.Test.MyOtherTest">
<!-- individual methods included here -->
...
</type>
If a <type>
element contains no nested <method>
elements, then all methods are selected for inclusion.
This is in contrast to an exclusion rule.
Applies only to Removal:
Type rules can be applied to entire inheritance hierarchies by specifying the applytoderivedtypes
attribute.
Setting the value of this attribute to true
will apply the type rule and any Method, Field, Property, Event, Custom Attribute, or Supertype rules that it contains to the selected type and all types that derive from it.
If not specified, the default value is false
, meaning that the type rule will only be applied to the specified type.
Including Methods
Methods may be included by first selecting the type using the <type>
element, then providing a rule for selecting methods to include.
Methods may be included by name and attribute specifier (as explained in the type section above), as well as by signature.
Allowed attribute specifiers are:
abstract
assembly
family
familyorassembly
final
private
public
static
virtual
If the attribute specifier is not set explicitly, then the speclist
attribute is not used as a matching criterion.
The following example selects all public instance methods beginning with Set
:
All Public Instance Methods Beginning with Set:
<method regex="Qtrue" name="Set.*" speclist="+public,-static"/>
Method signatures are specified using the signature
attribute.
A signature specifies both the return type and the parameter types of the method:
Return Type and Parameter Types of the Method:
signature="" <!-- empty parameter list -->
signature="string(int,MyClass,MyClass[])"
If the signature is not set explicitly, then the method signature is not used as a matching criterion.
The following example selects a method by signature:
Select Method by Signature:
<method name="DoIt" signature="string(int, System.Console, System.Collection.ICollection, float[])"/>
Global methods may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global method.
Including Fields
Field inclusion is only valid for removal triggers and removal conditional includes.
Fields may be selected by first selecting the type using the <type>
element, then providing a rule for selecting fields.
Fields may be selected by name and attribute specifier (as explained in the type section above).
Allowed attribute specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
notserialized
If the attribute specifier is not set explicitly, then field attribute will not be used at all as a matching criterion.
The following example selects all static fields starting with "ENUM_
":
Static Fields Starting with "ENUM_":
<field regex="true" name="ENUM_.*" speclist="+static"/>
Global fields may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global field.
Including Properties
Property inclusion is valid for Removal only. Property rules are qualified by type rules, so they appear in the rules view as children of type nodes. A property rule will select all properties (in all types matched by the parent type rule) that match your criteria. Supported matching criteria include property name and property attributes.
Allowed attribute specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
If the attribute specifier is not set explicitly, then the property attribute will not be used as a matching criterion.
The following example selects all properties starting with "Sample
":
Properties Starting with "Sample":
<property regex="true" name="Sample.*"/>
Property signatures are specified using the signature
attribute.
A signature specifies the type of the property:
Signature Specifies the Type of Property:
signature="" <!-- empty signature -->
signature="int"
If the signature is not set explicitly, then the property type will not be used as a matching criterion.
Global properties may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global property.
Including Events
Event inclusion is valid for Removal only. Event rules are qualified by type rules, so they appear in the rules view as children of type nodes. An event rule will select all events (in all types matched by the parent type rule) that match your criteria. Supported matching criteria include event name and event attributes.
Allowed attribute specifiers are:
public
private
static
assembly
family
familyandassembly
familyorassembly
If the attribute specifier is not set explicitly, then the event attribute will not be used as a matching criterion.
The following example selects all events starting with "On
":
Events Starting with "On":
<event regex="true" name="On.*"/>
Global events may be specified by using a special type selector with the name Module:mod_name
where mod_name
is the name of the module containing the global event.
Including By Custom Attribute
Types and methods may be selectively included by custom attribute. A custom attribute rule selects an item (type or method) based on matching against the names of custom attributes that annotate the item. One or more custom attribute rules may be nested inside any rule that selects types or methods.
A type or method rule may have multiple custom attribute rules associated with it. In this case, an item is selected if at least one of the custom attribute rules selects it.
The following example selects all types that are annotated with either MyCustomAttribute
or MyOtherCustomAttribute
:
Types Annotated with MyCustomAttribute or MyOtherCustomAttribute:
<type name=".*" excludetype="false" regex="true">
<customattribute name="MyCustomAttribute"/>
...
<customattribute name="MyOtherCustomAttribute"/>
</type>
Custom attribute rules can also be written using regular expressions to match custom attribute names.
The following example is another way to select all types annotated with either MyCustomAttribute
or MyOtherCustomAttribute
:
Selecting Types Annotated with MyCustomAttribute or MyOtherCustomAttribute:
<type name=".*" excludetype="false" regex="true">
<customattribute name="My.*CustomAttribute" regex="true"/>
</type>
The next example shows how to include all methods annotated with a custom attribute named MyCustomAttribute
:
Including Methods Annotated with MyCustomAttribute:
<type name=".*" excludetype="false" regex="true">
<method name=".*" regex="true">
<customattribute name="MyCustomAttribute"/>
</method>
</type>
Custom attribute rules can be applied to subtypes or overriding methods and properties by specifying the allowinheritance
attribute.
When the value of this attribute is set to true
then subtypes or overriding methods and properties with the specified custom attribute will also be excluded.
Including By Supertype
Types may be selectively included by supertype. A supertype rule selects a type based on matching against the names of types that the given type inherits from. One or more supertype rules may be nested inside any rule that selects types.
A type rule may have multiple supertype rules associated with it. In this case, an item is selected if at least one of the supertype rules selects it.
The following example selects all types that inherit from MySupertype
:
Selecting Types that Inherit from MySuperType:
<type name=".*" excludetype="false" regex="true">
<supertype name="MySupertype"/>
</type>
Supertype rules can also be written using regular expressions to match supertype names.
The following example shows how to select all types that inherit from either MySupertype
or MyOtherSupertype
:
Select Types that Inherit from MySupertype or MyOtherSupertype:
<type name=".*" excludetype="false" regex="true">
<supertype name="My.*Supertype" regex="true"/>
</type>
Including Assemblies
Assemblies may be included by name. When an assembly is included, all types and methods within any of the assembly's modules are included.
Including Assemblies:
<assembly>
<file dir="c:\src\app1\" name="IncludedLib.dll"/>
</assembly>
Including Modules
Modules may be included by name. Use the assembly attribute to qualify the module to a particular assembly. When specified, the assembly name should be the logical assembly name rather than its physical file name. When a module is included, all its defined types and members are included.
Obviously, if a given module is shared among multiple assemblies, then the module will be included for all the assemblies.
Including Modules:
<module name="MyLibResource.dll" assemblyname="MyLib"/>