Programs written for .NET are easy to reverse engineer. .NET applications compile to a high-level, expressive assembly language called MSIL (Microsoft Intermediate Language, also known as CIL) that contains method and variable names and can be easily decompiled back into source form. Attackers can use freely available reverse engineering tools to easily see the source of any .NET application, exposing software licensing code, copy protection mechanisms, and proprietary business logic - whether it's legal to do so or not.
These reverse engineering tools include disassemblers and decompilers. Disassemblers expose the MSIL of an assembly. Decompilers transform the MSIL in an assembly back into a source language, like C#.
To see for yourself how easy it is to reverse engineer .NET applications, follow along with the examples of using each type of tool on the GettingStarted sample (or on your own application).
Disassemblers are tools that translate compiled binaries into human-readable assembly code. The .NET Framework SDK ships with a disassembler, ildasm, that translates .NET assemblies into MSIL assembly language.
ildasmin the Developer Command Prompt for VS20xx shortcut in your Start Menu (or Visual Studio Command Prompt (20xx) for older versions of Visual Studio).
Note: If Visual Studio is not installed, you can still use ildasm by installing the .NET Framework SDK and finding ildasm.exe in the installation directory.
Click File | Open and browse to the output of the GettingStarted sample in the
To compare the currently shown, un-obfuscated HelloWorld application to a version that was protected with Dotfuscator, start another copy of ildasm.
This time browse to the output of the sample built in the
Notice that the un-obfuscated disassembly contains names of methods that are fairly understandable.
For example, it is safe to assume that the
ConverseButton_Click: void (object, class [mscorlib]System.EventArgs) method is called when the Converse button is clicked.
Now look at the obfuscated version. Which method is called when the converse button is clicked? It is hard to tell.
Also notice the missing
Dotfuscator removed it because the method wasn't being used anywhere in the code.
Double-click the methods
SayHello:string() from the original assembly and
a:string() from the obfuscated assembly.
These two methods are the same; however, when examining the disassembled IL code further, notice that the strings have been encrypted in the obfuscated version to make the code difficult to read.
For example, locate the following line in the un-obfuscated version:
IL_0000: ldstr "Hello, my name is "
Now view the obfuscated version, and try to find the above string. If you’re having trouble finding it, it’s because it’s encrypted and looks like the following:
IL_0000: ldstr bytearray (09 42 26 44 29 46 2B 48 26 4A 67 4C 6D 4E 22 50 28 52 73 54 3B 56 36 58 34 5A 3E 5C 7D 5E 36 60 12 62 43 64 )
You can imagine how confusing this can be for attackers who are trying to reverse-engineer the code, especially with more complex applications.
Reverse engineering isn't just limited to a small circle of technical folks who know MSIL Assembly Language. You can take it a step further and actually recreate the source code from an application by using a decompiler. These utilities can decompile a .NET assembly directly back to a high level language like C#, VB .NET, or Managed C++. There are many decompilers available to easily see the source of any .NET application.
ILSpy is a free decompiler.
To view a decompiled version of
GettingStarted.exe with ILSpy:
Extract the ZIP archive and run
In the ILSpy interface, open the File menu and select Open....
Using the code tree, explore the contents of the assemblies. Note the resemblance to the original source code: private member and local variable names are preserved, and the control flow is essentially the same.
After Dotfuscator is used on
GettingStarted.exe, ILSpy can still be used to view the protected version of
GettingStarted.exe the same way.
However, you will notice ILSpy errors decompiling our
GettingStarted.exe sample application after it has been protected with Dotfuscator.
Note: Even if ILSpy did not error decompiling the sample application, you can see that the code from the protected version of the application is still difficult to understand and reverse engineer. The code is much harder to follow due to the renaming, control flow, and string encryption applied to the application.
Reflector is a commercial .NET decompiler.
After protection from Dotfuscator, Reflector becomes much less effective for reverse engineering.
Running Reflector against the obfuscated
GettingStarted.exe file and trying to examine a method such as
a() displays the following:
This item appears to be obfuscated and can not be translated.