Wednesday, May 25, 2005 1:57 PM codingsanity

YAWGA.N

or ... Yet Another Whiny Gripe about .NET

In honour of the
Return of the Sith (which I'm going to see tomorrow), imagine the Imperial March playing in the background throughout this diatribe.

Right, so what whiny pansy-assed opinion am I going to attack this time?

Why does .NET make it so easy to decompile my code?
Actually this is a pretty good question, in that it appears to have a simple answer ("because MS wanted it that way"), and in fact the reason is more complex. It turns out that this is an emergent feature of a confluence of factors, the most important of which is Verification. So what is verification? It's the process that the JIT compiler performs to ensure that your code isn't going to break out and guzzle your beer, or worse.

There's basically two broad results of a verification procedure:
  • Verifiably type-safe - This has been proven to be type safe.
  • Scummy - This code could be doing unspeakable things with your new HDD.
 
Well, so what does this have to do with decompilation? You see, JIT has to be fast, and it has to be accurate. If it's operating off complicated inputs, then it will be neither fast nor accurate. When you add into this mix all the little performance optimisations that the JIT will try to do for you, we quickly see that a complex input would result in either unacceptably long JIT times, or unacceptably bad JIT results.
 
I'm pretty sure that MS didn't go out and say "let's write a system that can be easily reverse-engineered", it just happens to be a logical result of making a verifiable type-safe JIT-ted system.
 
So what can I do about it?
Get out of delivering products to consumers. Frankly, that's the only way you'll reliably keep your IP secure. The problem is that when you give something to your customers, they can by definition reverse engineer it. If they couldn't reverse engineer it they wouldn't be able to make it work. This is why things like DRM are bad technology. They work off the assumption that the consumer cannot illicitly decrypt the data, but they have to provide the means of decryption to the consumer in order to allow the user to view the movie, hear the song and so forth. So, this means that by reverse engineering the decryption mechanism one can circumvent the DRM protection.
 
Now, .NET does make this reverse engineering process easy, especially when using tools like Lutz Roeder's Reflector coupled with such nifty add-ins as Denis Bauer's File Disassembler. So what can one do about this? You could use an obfuscator like Dotfuscator or XenoCode. These tools will garble your internal names, mess around your logic while retaining it's workings, and encrypt strings to make it harder for hackers to find that piece of your code that shows the "Trial Period Expired" message. Just as a bonus obfuscators will generally cut down your code size by, for example, renaming your "CustomerDetails" class to "a".
 
What this is basically doing is removing some of your documentation. If you think about it, you'll see that there's quite a bit of documentation associated with your code. The class and member names are documentation. The comments are documentation. The unit tests, help files, error messages, stack traces, debug messages, trace messages, instrumentation, debug symbols, and data files are all documentation.
 
Now, when you ship a compiled (non-obfuscated) product you're removing the comments, the actual "official" documentation, the debug messages, and the debug symbols. A hacker could easily recreate everything except the comments and the documentation itself. So then the question becomes: "how important are the comments and documentation to understanding my code?"
 
In my opinion, they're critically important. It's hard enough understanding someone else's code even with these aids. Think about how long it takes a new developer on your team to come fully up to speed with your project, now double that time for not having mentoring, double it again for not having documentation, and double it again for not having comments. If nothing else this should inspire you to go write documentation and comments for your project. Throw in an obfuscator and you could probably double this time again, bringing your obfuscated, undocumented, uncommented C# as easy to read as well commented, well documented C++ code (Sorry, couldn't resist).
So, my advice is: stop worrying about people copying you, slap a "do not reverse engineer" clause into your EULA and work on more productive things like, I don't know, improving your product. Oh, and make sure you document and comment, it'll give you a competitive advantage against people who steal your code...
Filed under:

Comments

No Comments