Smaller applications download faster, install faster, load faster and run faster. Dotfuscator's Removal feature (sometimes called "pruning") statically analyzes your code to find the unused types, methods, and fields, and removes them. Dotfuscator also removes debug information and non-essential metadata from a MSIL file as it processes it, making the application smaller and reducing the data available to an attacker.
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.
Note: that turning on library mode for an assembly causes Dotfuscator to treat all visible types and members as entry points, automatically.
As Dotfuscator traverses each trigger method’s code, it notes which fields, methods, and types are being used. It then analyzes 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.
Dotfuscator generates a removal report in XML format that lists all input assemblies and how each was pruned. Each assembly 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 problems that can occur with Removal are very similar to those that may occur with Renaming. 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.
There are two types of inclusions possible, and both can be controlled by specific inclusions and by custom rules.
Consider an application in which method
A() calls method
- Include Triggers: If you select a method as an Include Trigger, Dotfuscator will make sure to keep that method, as well as any descendants of that method in the call graph Dotfuscator sees (again skipping things like reflection).
If an Include Trigger is set on method
A(), then both
B()will be kept.
- Conditional Includes: Any method set as a Conditional Include is kept, but its call tree is not traversed for additional methods to keep.
If a Conditional Include is set on method
A()will be kept, but
B()will be removed (as long as it is also not called by any other methods that Dotfuscator knows about).
There are two options for Removal Kind:
- Remove unused metadata and code: This is used when you want Dotfuscator to actively search out and remove unused types and methods.
- Remove only literals (const definitions): This is used to strengthen the power of String Encryption, so that unencrypted string consts get removed. If String Encryption is enabled, Removal should be turned on with this option selected.
Watermarking helps track unauthorized copies of your software back to the source by embedding data such as copyright information or unique identification numbers into a .NET application without impacting its runtime behavior. Dotfuscator’s watermarking algorithm does not increase the size of your application, nor does it introduce extra metadata that could break your application.