The Removal Editor
The Removal editor displays three configuration tabs:
- The Include Triggers tab, which is used to tell Dotfuscator about the entry points for your application, so it can determine which code can be safely removed.
- The Conditional Includes tab, which is used to tell Dotfuscator about types that should not be wholly removed, because of special cases such as reflection.
- The Removal Options tab, which is used to configure the removal report.
Understanding Include Triggers and Conditional Includes
Dotfuscator can statically analyze an application to determine which elements are not actually used and remove those elements from the output binaries, reducing application size.
The static analysis works by traversing your code, starting at a set of methods called “triggers," or entry points.
In general, any method that you expect external applications to call must be defined as a trigger.
For example, in a simple standalone application, the Main
method would be defined as a trigger.
An assembly can have more than one trigger defined for it.
As Dotfuscator traverses each trigger method’s code, it notes which fields, methods, and types are being used. It then analyses all the called methods in a similar manner. The process continues until all called methods have been analyzed. Upon completion, Dotfuscator is able to determine a minimum set of types and their members necessary for the application to run. Only these types are included in the output assembly.
If Dotfuscator is unable to tell that certain methods are being called (due to reflection / XAML / etc.), then it may try to remove things that are required at runtime. To avoid this, you configure Include Triggers to tell Dotfuscator which class members (method, property, field, event) should be treated as "entry points" for the static analysis. Dotfuscator will preserve those members and all descendants of those members in the call graph.
Sometimes, though, this isn't the most optimal behavior. Consider an application that loads a set of types via reflection, casts them to an interface, and then invokes methods on that interface - a plugin model, essentially. Dotfuscator's static analysis won't identify the types that could potentially be loaded, but it does know which methods on that interface are going to be called.
In such a case, you should configure the types as Conditional Includes. Dotfuscator will include them and figure out that they implement the interface. If it determines that some of the methods in the interface are unused, it will remove those methods from the interface, and from all the implementations in the conditionally included types. Methods that weren't removed will then be further analyzed for removal, as usual.
The Include Triggers Tab
The Include Triggers tab allows you to graphically specify all the methods that are to be used as application entry points ("triggers") for the removal process.
You may include specific methods as entry points by browsing the tree view of your application and checking the items you want to include. In addition, you may visually create your own custom rules for selecting multiple methods for inclusion.
To help you fine-tune your inclusion rules, you can preview their effects at any time. The application tree view shades all items selected for inclusion. You can preview the cumulative effects of all rules, or preview a specific rule that you select.
See the section on the Rules Editor for detailed information about working with Inclusion and Exclusion Rules.
The Conditional Includes Tab
The Conditional Includes tab allows you to graphically specify all the types that should be conditionally included in the removal process. Please see Understanding Include Triggers and Conditional Includes for a deeper explanation of this feature.
You may conditionally include specific types by browsing the tree view of your application and checking the items you want to include. In addition, you may visually create your own custom rules for selecting multiple types for inclusion.
To help you fine-tune your inclusion rules, you can preview their effects at any time. The application tree view shades all items selected for inclusion. You can preview the cumulative effects of all rules, or preview a specific rule that you select.
See the section on the Rules Editor for detailed information about working with Inclusion and Exclusion Rules.
The Built-In Rules Tab
Dotfuscator’s Built-In Rules removal tab displays include trigger rules and conditional inclusion rules. These standard rules apply to specific application types or technologies. Each rule has a description that displays on the form when the rule is selected. You can apply a built-in rule by checking its checkbox.
The exact definitions of each of these rules can be found in your installation location's Common
subdirectory.
A typical example is C:\Program Files (x86)\PreEmptive Protection Dotfuscator Professional A.B.C\Common
.
The rule definitions are found in the XML file with a name beginning with dotfuscatorReferenceRule
.
The Options Tab
The Removal Options tab is used to select the kind of removal you want to occur.
Selecting Remove only literals (const definitions) will perform removal only on constant declarations. Selecting Remove unused metadata and code follows the usual algorithm for determining unused methods and fields and removing them, as well as removing constant definitions.
Constant-Only Removal
You may encounter situations where you may not wish to configure Removal on an assembly, but still wish to achieve some of the attack surface and assembly size reduction goals of removal. In these cases, constant-only removal is an ideal compromise. During constant-only removal, Dotfuscator will only remove constant declarations (const fields) from the input assemblies. Unused types, methods, and fields will not be discovered, and will be propagated to the output assembly.
Constant-only removal is safe to do in many situations where full removal is not desired. During compilation, .NET compilers will replace references to const fields in code with the actual values of those fields. The constant declarations remain in the assembly only to support being referenced by external assemblies or being accessed via reflection. If you do not need to support these scenarios, it is generally safe to enable constant-only removal.
Removal Report
Dotfuscator generates a removal report in XML format that lists all input assemblies and how each was pruned. Each assembly listing has a listing of types and their members (methods, fields, properties, etc.) along with an attribute indicating whether the item was removed or not. The report also describes how managed resources attached to each assembly were pruned. At the end, the report provides a statistics section regarding the overall effectiveness of Removal.
The removal report is most useful when converted to HTML, using the default transform (or one of your own). The default transform produces a browsable, cross referenced report that indicates removed items in red.
The elements of the removal report are similar to those in the map file. A few things are noteworthy:
- The report includes removal status of: types, methods, fields, properties, and managed resources.
- If a type was removed, then obviously all its members (methods, fields and properties) were removed.
- In type names, nested class names are separated from the parent using the "/" character.
- Constructors are named
.ctor
, while static constructors (a.k.a. static initializers, class constructors, etc) are named.cctor
.