Applications built for .NET are highly susceptible to reverse engineering. They compile into Microsoft Intermediate Language (MSIL), an expressive, high-level instruction set that preserves significant metadata, including method names, variable names, and structural information. As a result, reverse-engineering tools can often reconstruct the code into a format resembling the source code.
The accessibility of .NET code through tools such as disassemblers and decompilers creates several business and security risks:
- Intellectual property exposure: Competitors can analyze your application to uncover proprietary algorithms and business logic.
- Security vulnerabilities: Malicious actors can inspect the code to identify security weaknesses or locate hardcoded sensitive information.
- Software piracy: Unauthorized parties can attempt to bypass licensing mechanisms or remove copy protection.
The following examples demonstrate how easily an unprotected .NET application can be reverse-engineered. They use the Dotfuscator GettingStarted sample, but you can also follow the procedures using your own application.
Disassembling a .NET Application
Disassemblers translate compiled binaries into human-readable assembly code. The .NET Framework SDK includes the IL Disassembler (ILdasm), which translates .NET assemblies into MSIL.
Disassemble the GettingStarted Sample with ILdasm
To examine the unprotected version of the GettingStarted sample:
- Open the Developer Command Prompt for Visual Studio from the Windows Start menu.
Run the following command:
ildasm- In ILdasm, select File > Open.
Browse to the output directory of the GettingStarted sample built in the Debug configuration. For example:
C:\dotfuscator-pro-samples\GettingStarted\bin\Debug- Select
GettingStarted.exe, and then click Open. - To compare the unprotected application with a version protected by Dotfuscator, open another instance of ILdasm.
Browse to the output directory of the sample built in the Release configuration. For example:
C:\dotfuscator-pro-samples\GettingStarted\bin\Release- Select
GettingStarted.exe, and then click Open.
Compare the Disassembled Assemblies
The unprotected assembly contains method names that reveal the application’s behavior. For example, the following method name indicates that it is called when the Converse button is selected:
ConverseButton_Click: void (object, class [mscorlib]System.EventArgs)In the protected version, renamed methods no longer clearly communicate their purpose, making it more difficult to identify which method handles the same action.
The SaySomething method is also absent from the protected assembly because Dotfuscator determined that the method was unused and removed it.
To compare the contents of equivalent methods:
- In the unprotected assembly, double-click
SayHello:string(). - In the protected assembly, double-click
a:string().
Although these methods perform the same operation, the protected version is more difficult to understand because Dotfuscator has transformed its contents.
For example, the unprotected version contains the following readable string:
IL_0000: ldstr "Hello, my name is "In the protected version, the string is encrypted and appears as a byte array:
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 )Renaming methods, removing unused code, and encrypting strings make the disassembled application considerably more difficult to analyze, especially in larger and more complex applications.
Decompiling a .NET Application
Reverse engineering is not limited to users who understand MSIL assembly language. Decompilers can reconstruct a .NET assembly into a high-level language such as C#, Visual Basic .NET, or Managed C++.
Because many .NET decompilers are readily available, an unprotected application’s source structure and logic can be easy to inspect.
Decompile the GettingStarted Sample with ILSpy
ILSpy is a free .NET decompiler.
To examine the unprotected version of GettingStarted.exe:
- Download ILSpy.
- Extract the downloaded ZIP archive, and then run
ILSpy.exe. - In ILSpy, select File > Open.
- Browse to the following directory:
C:\dotfuscator-pro-samples\GettingStarted\bin\Debug - Select
GettingStarted.exe, and then click Open. - Use the assembly tree to explore the application.
The decompiled application closely resembles its source code. Private members, local variable names, and the application’s control flow remain recognizable.
You can open the protected version from the Release directory using the same procedure. ILSpy might display errors when attempting to decompile the protected GettingStarted.exe sample.
Note: Results can vary depending on the ILSpy version. Even if ILSpy successfully decompiles the protected sample, the renamed identifiers, transformed control flow, and encrypted strings make the resulting code significantly more difficult to understand and reverse engineer.
Examine the Protected Application with Reflector
Reflector is a commercial .NET decompiler. After Dotfuscator protects an application, Reflector becomes less effective at reconstructing its code.
For example, when Reflector examines the obfuscated GettingStarted.exe file and attempts to display a protected method such as a(), it can return the following message:
This item appears to be obfuscated and can not be translated.These examples illustrate how Dotfuscator transformations make .NET assemblies more resistant to analysis by common disassemblers and decompilers.