Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#
Article

7 Ways to Protect your .NET Code from Reverse-Engineering

16 Mar 2011CPOL5 min read 55.6K   31   14
If you’re about to release your software internationally and it’s written in .NET, then you ought to consider protecting your code and IP. This article outlines 7 ways to protect your .NET code from reverse-engineering and other malicious forms of attack.

This article is a paid placement in the Solution Center for our sponsors at The Code Project. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

If you are making your software available internationally, and your software is written in .NET (which is particularly easy to decompile), then you ought to consider protecting your code. You can protect your code in various ways, including obfuscation, pruning, resource encryption, and string encoding. In this article, we will show you 7 different ways to protect your Intellectual Property against reverse-engineering, theft, and modification, by using just one tool: SmartAssembly.

Obfuscation

Obfuscation is a classic code protection technique used to make your code hard to read. Obfuscation changes the name of your classes and methods to unreadable or meaningless characters, making it more difficult for others to understand your code.

SmartAssembly offers a choice between type/method name mangling and field name mangling.

 

Obfuscating type and method names

SmartAssembly offers three levels of obfuscation for type names and method names:

ASCII characters Renames types and methods using ASCII characters. For example, the type FullScreenSplash might be obfuscated to #dc.

Note: you must choose this option if you want to be able to decode stack tracks after obfuscation.

Unicode unprintable characters Renames types and methods using Unicode unprintable characters. For example, the type FullScreenSplash might be obfuscated to U+1D11E (which is unprintable).
Unicode unprintable characters and advanced renaming algorithm Renames types and methods using Unicode unprintable characters, and renames multiple items with the same name. For example, the types FullScreenSplash and FontStyle are both obfuscated to U+017D.

The following example shows code before and after type/method name mangling:

Before obfuscation:

C#
public ClientLicence GetLicence(ItemType type);

public bool IsFileInProject(string fileName);

public void ResolveAssemblyReferences();

public void Save();

private void SetMemento(Properties memento);

public void Start(bool withDebugging);

private void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink);

After obfuscation:

It is not possible to display unprintable characters. For the purpose of this example, unprintable characters are represented by an asterisk (*).

C#
public ‑.‑ *(‑.‑);

public bool *(string);

public void *();

public void *();

private void *(‑.‑);

public void *(bool);

private void *(‑.‑,‑.‑);

To check that your code has been obfuscated properly, you can use Red Gate’s .NET Reflector (a tool for disassembling .NET executables).

Obfuscating Field Names

Again, in order to give you more control over the level of obfuscation strength, SmartAssembly offers three different schemes for renaming field names:

One-to-one renaming schemeChanges all fields in all classes so that they have different names. A field's name is unique within an assembly.

Note: you must choose this option if you want to be able to retrieve the original field names from stack traces.

Standard renamingAlters the field name so that it is unique within a class; however the same name is often used within other classes in the assembly. For example, #a: string, #b: boolean, #c: string, #d: boolean.
Advanced renamingAlters the field name, however it not unique within a class and is reused. Fields of a different type will have the same name. For example, #a: string, #a: boolean, #b: string, #b: boolean.

Control Flow Obfuscation

In additional to renaming crucial parts of your code, you can also use Control Flow Obfuscation. This technique changes the code inside your methods, converting it into a complex and tangled control structure (spaghetti code). After Control Flow Obfuscation, you can execute your application in exactly the same way as before, but it is now very difficult for anyone else to analyze your code, and almost impossible for a decompiler to recreate the original source code.

Control Flow Obfuscation prevents most programs from being able to disassemble the code. For example, attempting to disassemble control flow obfuscated code using .NET Reflector will give:

C#
private static void Main() 
{ 
// This item is obfuscated and cannot be translated. 
}

String Encoding

Managed software stores all strings in one place and in a clear structure. By following the references to these strings, it is then possible to understand the purpose of your code, even after obfuscation. These strings can reveal important information, such as passwords, SQL requests, serial numbers, or login information. String Encoding protects the strings by encoding them.

The examples below show the effect of encoding three strings within an assembly:

Before String Encoding:

C#
"Fred.gate@hotmail.com"
"p@ssw0rd1"

"licensingUrl=http://licensing.red-gate.com/licensingactivation.asmx"

After String Encoding:

"FNRFk1TTJZM016VTPQ==.bmV1dSBzcGVjaWZpZWQ9sbGVjdGlvbi4=L"

References Dynamic Proxy

If you make calls outside of your assembly, these calls will still be visible in your code after String Encoding and Control Flow Obfuscation. For example, if you make a call to a message box, it would still be possible to find that call in the disassembled application, even with String Encoding and Control Flow Obfuscation enabled. By following external calls like this, it may still be possible for other people to understand parts of your code.

Reference Dynamic Proxy is a unique protection feature offered by SmartAssembly that allows you to hide most of the calls to external methods, properties, or fields in your code, by replacing them with calls to the proxy. By using this type of protection, you can make it very difficult for someone to find calls such as a trial expiry dialog, which could unintentionally offer clues about where to break in.

Pruning

Pruning automatically scans your software and removes any code that will never be executed at runtime. This includes removing non-useful metadata, such as the names of events, properties, and method parameters that would give someone else clues about what particular types and methods are for.

Resource Compression and Encryption

This feature compresses and encrypts your managed resources. This reduces the size of the assembly and makes the code harder to understand.

Dependency Merging

Dependency Merging allows you to choose particular DLLs, then merges them into one executable, giving you performance benefits because you don't have to load lots of DLL files. After merging, the dependency is inseparable from the main assembly.

Dependency Merging is not a protection feature per se, but it is it a lot easier to obfuscate and prune your code if you have one assembly, rather than several smaller DLLs. (If you want to obfuscate several assemblies without merging them, you will need to create several SmartAssembly projects.)

Conclusion

In this article, we have shown how you can use SmartAssembly to protect your intellectual property by obfuscating your code, hiding most calls to external methods, encoding strings, removing unessential code, and compressing and encrypting resources.

To try SmartAssembly on your own software, simply download a 14-day free trial from Red Gate’s website.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Red Gate Software Ltd.
United Kingdom United Kingdom
Redgate makes ingeniously simple software used by 804,745 IT professionals and counting, and is the leading Microsoft SQL Server tools vendor. Our philosophy is to design highly usable, reliable tools which elegantly solve the problems developers and DBAs face every day, and help them adopt database DevOps. As a result, more than 100,000 companies use products in the Redgate SQL Toolbelt, including 91% of those in the Fortune 100.
This is a Organisation

1 members

Comments and Discussions

 
SuggestionMessage Closed Pin
18-Feb-12 4:38
Ivan Voyager18-Feb-12 4:38 
NewsRe: What about code protection? Pin
abdurahman ibn hattab11-Feb-13 7:53
abdurahman ibn hattab11-Feb-13 7:53 
GeneralMy vote of 4 Pin
ahmedfaruk8830-Sep-11 4:42
ahmedfaruk8830-Sep-11 4:42 
General[My vote of 1] poor article Pin
Sebastian Pederiva2-Apr-11 21:48
Sebastian Pederiva2-Apr-11 21:48 
GeneralFree and OS alternative Pin
Claudio Nicora22-Mar-11 21:45
Claudio Nicora22-Mar-11 21:45 
Can do the same things (for free) with Eazfuscator.
Same renaming, same spaghetti code obfuscation, same protection against .NET Reflector.

Visit my website for some interesting .NET free tools: http://coolsoft.altervista.org

GeneralMy vote of 2 Pin
Veener22-Mar-11 2:05
Veener22-Mar-11 2:05 
Rant[My vote of 1] Poor article... Pin
Sérgio Vicente22-Mar-11 1:21
Sérgio Vicente22-Mar-11 1:21 
GeneralMy vote of 1 Pin
Martin Hart Turner21-Mar-11 21:16
Martin Hart Turner21-Mar-11 21:16 
GeneralRe: My vote of 1 Pin
tecnova126-Apr-13 18:10
professionaltecnova126-Apr-13 18:10 
GeneralMy vote of X Pin
Bob100021-Mar-11 12:45
professionalBob100021-Mar-11 12:45 
GeneralMy vote of 1 Pin
zebishop17-Mar-11 21:32
zebishop17-Mar-11 21:32 
Rant[My vote of 1] Poor article Pin
zebishop17-Mar-11 21:31
zebishop17-Mar-11 21:31 
QuestionC++/CLI compatible? Pin
Lucas Vogel16-Mar-11 7:04
professionalLucas Vogel16-Mar-11 7:04 
AnswerRe: C++/CLI compatible? Pin
redcheek21-Mar-11 20:08
redcheek21-Mar-11 20:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.