Best Method to Obfuscate or Secure .Net Assemblies

Best method to obfuscate or secure .Net assemblies

This is a pretty good list of obfuscators from Visual Studio Marketplace
Obfuscators

  • ArmDot
  • Crypto Obfuscator
  • Demeanor for .NET
  • DeployLX CodeVeil
  • Dotfuscator .NET Obfuscator
  • Semantic Designs: C# Source Code Obfuscator
  • Smartassembly
  • Spices.Net
  • Xenocode Postbuild 2006
  • .NET Reactor

I have not observed any performance issues when obfuscating my code. If your just sending text basted stack traces you might have a problem translating the method names.

.NET obfuscation tools/strategy

Back with .Net 1.1 obfuscation was essential: decompiling code was easy, and you could go from assembly, to IL, to C# code and have it compiled again with very little effort.

Now with .Net 3.5 I'm not at all sure. Try decompiling a 3.5 assembly; what you get is a long long way from compiling.

Add the optimisations from 3.5 (far better than 1.1) and the way anonymous types, delegates and so on are handled by reflection (they are a nightmare to recompile). Add lambda expressions, compiler 'magic' like Linq-syntax and var, and C#2 functions like yield (which results in new classes with unreadable names). Your decompiled code ends up a long long way from compilable.

A professional team with lots of time could still reverse engineer it back again, but then the same is true of any obfuscated code. What code they got out of that would be unmaintainable and highly likely to be very buggy.

I would recommend key-signing your assemblies (meaning if hackers can recompile one they have to recompile all) but I don't think obfuscation's worth it.

How can I protect my .NET assemblies from decompilation?

One thing to keep in mind is that you want to do this in a way that makes business sense. To do that, you need to define your goals. So, exactly what are your goals?

Preventing piracy? That goal is not achievable. Even native code can be decompiled or cracked; the multitude of warez available online (even for products like Windows and Photoshop) is proof a determined hacker can always gain access.

If you can't prevent piracy, then how about merely reducing it? This, too, is misguided. It only takes one person cracking your code for it to be available to everyone. You have to be lucky every time. The pirates only have to be lucky once.

I put it to you the goal should be to maximize profits. You appear to believe that stopping piracy is necessary to this endeavor. It is not. Profit is simply revenue minus costs. Stopping piracy increases costs. It takes effort, which means adding cost somewhere in the process, and so reduces that side of the equation. Protecting your product also fails to increase your revenue. I know you look at all those pirates and see all the money you could make if only they would pay your license fees instead, but the reality is this will never happen. There is some hyperbole here, but it generally holds that pirates who are unable to crack your security will either find a similar product they can crack or do without. They will never buy it instead, and therefore they do not represent lost sales.

Additionally, securing your product actually reduces revenue. There are two reasons for this. One is the small percentage of customers who have trouble with your activation or security, and therefore decide not to buy again or ask for their money back. The other is the small percentage of people who actually try a pirated version of software to make sure it works before buying. Limiting the pirated distribution of your product (if you are somehow able to succeed at this) prevents these people from ever trying your product, and so they will never buy it. Moreover, piracy can also help your product spread to a wider audience, thus reaching more people who will be willing to pay for it.

A better strategy is to assume that your product will be pirated, and think about ways to take advantage of the situation. A couple more links on the topic:

How do i prevent my code from being stolen?

Securing a .NET Application

obfuscation vs unmanaged assembly

There are advantage and disadvantages to both models. But these will primarily depend on your specific threat model, which is where I suggest you start. Which groups of people present security threats to your product, and what are those threats?

In general, the advantage of using managed code is speed to market, but it's more susceptible to certain attacks and IP theft. The advantage of using native code is that it's less susceptible to certain attacks, but the speed to market is slower. These are very generic advantages and disadvantages that should be tuned based on your threat model.

EDIT to answer your comment. If you do have IP that you need to protect, I would (in the generic case) go for a native code executable rather than an encrypted obfuscated assembly. Native code is harder to crack open than encrypted obfuscated managed code, and the additional complications of encryption and obfuscation will add a significant amount of design and testing to your product.

EDITED again to point out that there's another option: you can use a packer like MPress. This doesn't have the performance and complexity implications of obfuscation and/or encryption, but still provides reasonable protection against IP theft by non-professional crackers. If you look at a packed .NET assembly with Reflector, you just see a single Main call.

Should I be worried about obfuscating my .NET code?

I wouldn't worry about it too much. I'd rather focus on putting out an awesome product, getting a good user base, and treating your customers right than worry about the minimal percentage of users concerned with stealing your code or looking at the source.

encrypting a .Net application and assemblies

Assembly strong naming was never designed to protect against an attacker who is in control of the machine. From the msdn entry on delay signing:

The following example turns off verification for an assembly called
myAssembly.dll.

sn –Vr myAssembly.dll

The design goal of strong names is to provide name uniqueness and to protect the user (not the publisher) against an attacker. If the user wants to disable all strong name checks, or maybe even strip out your signature and re-sign the assembly with his own key then there is technically speaking nothing to prevent him from doing so.

Simply loading your assemblies from an encrypted file is also not very useful because the decryption code itself cannot be encrypted and is therefore an easy target for reverse engineering.

As mentioned by other posters, what you are looking for is obfuscation. You probably already have such a tool: Visual Studio (at least 2005 and 2008) comes with the community edition of PreEmptive Solutions’ Dotfuscator. Microsoft also has its own "Software Licensing and Protection Services" product.

Obfuscation has some technical disadvantages however:

  • it may complicate your build process.
    You need an unobfuscated and an
    obfuscated build, because the latter
    is not debuggable.
  • I like to have an error dialog for unexpected exceptions where the user can click "copy details" and send me a mail with some technical information including the stack trace. With obfuscation however, you can forget about getting anything useful
    from Exception.StackTrace.
  • if your code makes use of reflection then
    there is a good chance that things will
    break in the obfuscated build, because internal type and member names are not preserved.


Related Topics



Leave a reply



Submit