Friday, October 24, 2008

Dotfuscate

Introduction
The Microsoft .NET compiler converts the C# source code into Microsoft Intermediate Language (MSIL). However, with the use of a good decompiler tool and a few mouse clicks, any person can revert this .NET compiled code to its original C# source code. Hence, we need to protect the source code, including the 'trade secrets and logic' from attackers, especially when distributing the libraries/executables to third parties. A viable solution is the use of an Obfuscation Tool such as the .NET Dotfuscator (or simply, Dotfuscator).

The definition of 'obfuscate' is 'to confuse' or 'to make obscure or unclear', and that's exactly what an obfuscator tool will do. The Obfuscator will apply behavior preserving transformations on the code so that the functionality is preserved but the readability or understandability of the code is drastically reduced. The aim is to confuse observers while giving a consistent behavior to the Runtime Environment.

Main strategies of an obsfuscator
Compaction
The entire application is analysed and unused members are identified and removed from the obfuscated assembly. This is called the Compaction process. The unused members include unused classes, methods, instance variables and design time metadata, just to name a few. For example, a common library may offer a lot of functionalities but only a few are used in the application. So, these unused methods can be safely removed. Compacted programs also tend to load faster and run using less memory.

Overload Induction
The obfuscator renames all program identifiers to small, meaningless names. The Overload Induction mechanism works by identifying colliding set of methods across inheritance hierarchies and renaming such sets according to some enumeration (e.g. the alphabet). This method determines all opportunities for name reuse and hence, you may find more than 30% of ALL methods renamed to a single letter 'a'. Another advantage is the final program size of the obfuscated code is reduced by approximately 10% as there is heavy reuse of identify names.

String Encryption
Another interesting feature is the implementation of the runtime decrypted string encryption. An encryption algorithm is applied to all string literals and constants so as to make reverse-engineering even harder. This is very useful to hide hardcoded SQL strings, usernames and passwords that may be found in the code. Also, a decryption algorithm is inserted in the obfuscated code and later called at runtime to get back the original string literals.

Control Flow obfuscation
Control Flow obfuscation is yet another strong form of code protection. Here the flow of the program is changed so that the link between the original code and the obfuscated code breaks. It also ensures that no bug is introduced. For example, a for loop statement may be transformed into a while loop, a switch statement may be converted to a nested if statement and go to statements and labels may be introduced, just to name a few. This in turn transform the neat logic and flows in the original source code into a 'spaghetti-like' code to confuse the readers and any reverse engineering tool.

Assembly Linking
Multiple input assemblies are also combined into one or more output assemblies.



PreEmptive Solutions Dotfuscator flavors
There are currently two different version of the Dotfuscator: Professional Edition and Community Edition. The Community Edition is an entry level obfuscator and is included in Visual Studio 2005 Pro. The Professional Edition provides superior protection to foil decompilation, size reduction to conserve memory and improve load times, incremental obfuscation to release patches, watermarking to track pirates and so on and so forth.

Simple Dotfuscator Demonstration
1. Create your project in VS2005. Here, I shall use a simple application that print numbers 1 to 100.
using System;
using System.Collections.Generic;
using System.Text;
 
namespace DotfuscateDemo
{
    class Program
    {
        private double unUsedDouble;
 
        /// <summary>
        /// Gets or sets the un used double.
        /// </summary>
        /// <value>The un used double.</value>
        public double UnUsedDouble
        {
            get { return unUsedDouble; }
            set { unUsedDouble = value; }
        }
 
        /// <summary>
        /// Main method
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            Print1ToN(100);
            Console.ReadLine();
        }
 
        /// <summary>
        /// Print1s to N.
        /// </summary>
        /// <param name="nValue">The n value.</param>
        private static void Print1ToN(int nValue)
        {
            for (int i = 1; i <= nValue; i++)
            {
                Console.WriteLine(i);
            }
        }
    }
}


2. Build your project to get the assemblies that needs to be dotfuscated.

3. In Visual Studio 2005, open the Dotfuscator Community Edition found under Tools menu.


4. On the 'Select Project Type' screen, select the 'Create New Project' option.


5. Now we are ready to dotfuscate the project asssembly.

Select the Input tab on the Dotfuscator main window.

Select the option 'Browse and add assemblies to list' (this is an open folder icon) and add the project assembly.


6. There are other features available in the different tabs on the window and many of them may also be disable if you using the Community Edition. To keep this example simple, I will go directly to the dotfuscation process.

7. Now its time to save the project using Save Project under File menu. The solution is saved as an xml file.

8. The final step is to kick off the obfuscation process. This is done by selecting the Build Project option (play icon).

9. Once the build is completed, a Build Statistics is shown giving summary details of the obfuscated code changes.


10. You can now find the dotfuscated assemblies in a folder named Dotfuscated at the location where you saved the project xml file.

Before obfuscation...
After obfuscation...
Worth noting facts about Dotfuscator
A command line interface is available and thus, makes it suitable for integration into scripting environments or automated build processes.

ASP.NET code behind assemblies can be obfuscated using the Dotfuscator.

Dotfuscator will solely work on the compiled .NET assemblies and the original source code is never affected.

Dotfuscator is not a profiler (a very common misconception!!!).

Dotfuscator supports the Microsoft .NET Compact Framework.

And finally ...
Last but not least, it is important to know that obfuscation (or even encryption) is not 100% protected and secure. The only aim is to make the reverse engineering process extremely time consuming and painful so that it's not worth the effort and hence, stopping any potential attacker.

References
Microsoft .NET Support Team Blog
Preemptive Solutions
The Dotfuscator Solution

No comments: