The sad (but inevitable) state of .NET Obfuscation

Since the release of the .NET framework there has been a quiet arms-race between those who want to protect their intellectual property, and those who want avail themselves of the intellectual property of others. And from where I’m standing, the reverse-engineers are winning, convincingly. 


The CLR is a virtual machine, and for JIT compilation, linking and introspection to work a considerable amount of type information must remain in an assembly when it is compiled.  Because of the extra meta-data (compared to a native C/C++/Delphi etc DLL) if you’re shipping an un-obfuscated assembly to your customers you may as well be giving them the source code. Sure they’ll miss out on the “why” in your comments, but other than that they get pretty much everything.  Tools like reflector just make it that easy to reverse-engineer un-obfuscated .NET code. This leads most people who are developing commercial products built on the .NET framework that are shipped to end-users to investigate obfuscation as a means of pr otecting their IP. Often this is also done to prevent easy circumvention of any licensing checks and restrictions that developers may have put into their .NET products.

Obfuscation can use a number of techniques, such as stripping meta-data, encrypting string resources, scrambling control-of-flow, adding rogue IL instructions that don’t break the program during execution but crash ildasm or reflector, aggressive method overloading (effectively another way to throw out information by removing method names), “packing” the application to hide the IL, and safeguards to prevent debuggers “attaching” as well as probably dozens more that I’m not aware of. And the reverse engineering crowd seem to have counter-measures for every one of these techniques.

Sometimes this takes the form of de-obfuscation tools specifically developed to un-do the work of a particular obfuscator ({smartassasin} for {smartassembly}, “the Xenocode solution” for Xenocode, DotFuckScator for dotfuscator etc). Usually this is a “partial” thing – after all the obfuscation process usually removes information which can’t be recovered, but the de-obfuscator will usually un-encrypt encrypted strings, allow the assembly to be viewed in reflector and un-scramble the control-of-flow obfuscation. No, I haven’t tried all these tools and some of them are now a little out of date, but I’m fairly sure similar ones exist for the newer obfuscation products, and it really doesn’t matter because the general-purpose de-obfuscation tools are even scarier.

And if the thought of obfuscator-product-specific tools isn’t worrying enough, or you were thinking about rolling up your sleeves and writing your own obfuscator have a look at this - a general-purpose re-assembler with de-obfuscation tools built in, demonstrated by Daniel Pistelli, author of the “NativeBlocks” application (currently unreleased, but you can be sure serious reverse-engineers have tools like this or more powerful). By running a few fairly short scripts through his tool he is able to remove a lot of the control-of-flow obfuscation in reflector (before Lutz Roeder gave it in to the care of red-gate/sold it). This is in addition to publicly available tools like Rebel.NET (a re-assembler for .NET, also by Daniel) and simple assembly explorer (a class browser and re-assembler, one of the few reverse-engineering tools I found that came with source…I guess if you know what you’re doing with RCE you don’t need source).

I guess it’s not that surprising that reversing of .NET applications is easy for those who know how. Even native applications that don’t have as many restrictions as .NET applications, and CAN quite happily redact all of their internal structure as they feel like during the compilation process are frequently reverse-engineered using tools like Ollydbg, IDA and Hex-Rays. Ultimately if it runs on a computer outside your control it can be broken. The ethics of all this reverse-engineering seems fairly dubious to me. Aside from the area of malware reverse-engineering I can’t think of many legitimate uses for this stuff, but that doesn’t stop me from being impressed by their ingenuity. 

And before you ask, yes - knowing most of this already I wrote my own obfuscation scheme, only later to be gutted when another “generic” tool that I haven’t linked to here was easily able to circumvent it.


David Connors
The key sentence in your article is "Ultimately if it runs on a computer outside your control it can be broken." It is not specific to .NET but encompass a lot of time and money wasted on things Office DRM, HDCP, WMA DRM, and the numerous runtimes out there that ‘secure’ binaries from inspection at runtime.

The key tenet of trusted systems is that a given trusted system has a reference monitor that you can trust to arbitrate all of the security decisions that need to be made. The problem with all of the systems I’ve outlined above (and any sort of code-level obfuscation for that matter) is that all bets are off in terms of trusted systems/computing when someone has unmonitored and unfettered access to the entire system (the securable entity + reference monitor + hardware).

In my view, this is part of the attractiveness of ensuring that your software is delivered as a service. You don’t have the same issue. Your licensees are reduced to userland privileges and you can enforce whatever you want.

Once you get your head around that you just look at any sort of obfuscation or DRM and point and laugh. It is a pointless exercise. The only difference between modifying an x86 binary and a de/recompiled MSIL executable to circumvent licensing is that you need a marginally smarter person to do the former.

When considering software targeting business and the enterprise, another point to consider is whether or not anyone who was going to be bothered cracking your scheme (or downloading a pirate copy) was ever going to pay you in the first place. I highlight the pain that Microsoft subjects us all to in terms of different media, MSDN vs SPLA vs Volume licensing schemes, keys bound to media, activation, etc. This is all unwarranted “assumed guilt” punishment meted out to your otherwise honest customers who are happy to pay for your product. It does nothing to deter hackers because those things do not exist in their version.


7/06/2010 3:45:42 PM