6
votes

As discussed in similar questions here and here I want to protect my code from reverse engineering.

My situation is as Simucal describes in his (excellent) answer here:

Basically, what it comes down to is the only chance you have of being targeted for source theft is if you have some very specific, hard to engineer, algorithm related to your domain that gives you a leg up on your competition. This is just about the only time it would be cost-effective to attempt to reverse engineer a small portion of your application.

I have exactly this situation. A hard to engineer algorithm which is elegant and valuable for our specific domain.

After spending months fine tuning and developing this the end result is very compact (approx. 100 lines of code) and elegant. I want to protect this specific part of the code from reverse engineering or at least make it reasonable difficult.

The scenario is a rich-client application written in C# and I have to deploy this part of the code - I cannot execute it from a webservice.

I think extracting the code and rewriting it in a unmanaged native binary is not an option due to performance reasons (and cross boundary issues).

Initially I wanted to do simple obfuscation but given the small size of the code I don't think this will offer much protection.

Ideally I would like to protect my whole application but there are two main issues that seem to make ordinary obfuscaters and 3rd party packers difficult to use:

  1. The application offers a plugin interface and therefore some assemblies (and interfaces/classes) should not be obfuscated and packed

  2. We still want to be able to get to a real stack trace when receiving error reports - potentially this could be done my mapping obfuscation to the real code.

Setting these issues aside (although I would appreciate any input on this as well), what is a good way to protect a tiny part of my code from reverse engineering? I am not concerned about anyone altering or hacking the code but want to make it difficult to understand and reverse engineer it.

8
How is this different from the many questions that have been asked before? stackoverflow.com/questions/506282/… and stackoverflow.com/questions/106794/…George Stocker
I am asking how to protect a relatively small part of my code which is embedded in a complex application (with a plugin architecture). While this question is similar to the other questions (and I have referred to them), I ask for a very specific scenario. (small part of code)Patrick Klug
Indeed not a dupe, but I really wonder why do people have these delusions that they have some incredibly valuable little algorithm. Even if the algorithm is awesome, it doesn't make a program, besides algorithms should be free for all, and you should keep your customers through quality and service.Robert Gould
I agree. Even if someone could see the algorithm they would need to get other things right (such as the UI to make use of it). I did not say that this is the only thing valuable nor that it is of value (or even interest) for someone outside our domain.Patrick Klug
SO's resident expert reverse engineer, Cody Brocious (user 4977), seems to be out. I would still try packing, it is an important defensive measure which is much more effective than obfuscation. Ensure your plugins still work with it. Similarly, you could do as Steven says and do some runtime..mmcdole

8 Answers

3
votes

You should obfuscate the complete code since it gets harder to reach that small valuable part. The smaller the code gets, the easier it becomes to understand it. Most obfuscators should not mess with public interfaces since there are many obfuscated libraries out there.

However I think you should rather convince users that there are no special tricks there instead of trying to hide it. To quote Kaiser Soze, "the greatest trick The Devil has ever pulled is to convince the world that he doesn't exist".

And of course you can always file a patent for your invention and protect yourself legally.

3
votes

Aside from obfuscation it is almost worthless, even Microsoft (ScottGu etc) basically say that people with the right amount of intent and ability will reverse engineer an application and in .NET a basic defense is licensing and IP instead of trying to guard your code through obscurity or some other means of preventing reverse engineering.

That is part of the reasoning of why they released the BCL source instead of keeping it private.

3
votes

It cannot be done. If your code can be run, then it can be read and reverse-engineered. All you can do is make it a little harder and, believe me, it will only be a little harder. You may not like the fact but most crackers are far better at cracking than anyone else is at making things hard to crack. The amount of effort to protect your code is usually not worth it, especially if it disadvantages your paying customers. Witness the stunning non-successes of DRM.

My advice is to not worry about it. If your algorithm is truly novel, seek a patent (although that got a little harder with the Bilski decision unless you tie it to a specific hardware implementation). Relying on trade secrets is also useless unless you only distribute your software to those that sign contracts that ensure they will not allow unfettered access. And then, you have to have a way to police this. The minute you put the binaries up on the internet or distributed them without a contract, I believe you'll be deemed to have lost trade secret status.

Relying on licensing is also fraught with danger - you may think that you can insert clauses in your license that prohibit reverse-engineering but many jurisdictions around the world specifically disallow those provisions. And the Russian mobsters who whoever are responsible for most of the cracking are unlikely to honor said provisions anyway.

Why don't you just concentrate on making your product the best it can be? The goal is to stay ahead of the crowd rather than lock them out altogether. Being the first to deliver and always having the best product in a competitive group will ensure your prosperity far more than wasting a lot of effort on useless protection (IMNSHO).

This is just my opinion. I may be wrong. I've been wrong before, you only need ask my wife :-)

2
votes

one option is to use the license key and/or hardware fingerprint to decrypt the sensitive code at runtime and emit it as IL; this will make it invisible to static reverse-engineering tools (e.g. Reflector)

also detect the presence of a debugger and refuse to run in debug mode, except possibly in very limited circumstances (i.e. on your machine)

note that this will make debugging very difficult for you, and nearly impossible for others (if this is an end-user app that's not a problem, but if it is a library or framework for other developers to build upon, that's a problem)

note also that making a copy of physical memory to disk and using offline tools on the memory-dump will reveal your decrypted algorithm, so it is fairly easy to defeat - but far more trouble than most people will bother with

the whole thing is a trade-off between difficulty for you vs deterrence for the few bad apples vs potential loss due to theft/plagarism

good luck, and let us know what you decide!

2
votes

If your code is that sensitive, put it where nobody can get to it.

E.G. provide a client or web page for people to access some service that exposes your functionality.

That service can sit behind an external firewall and communicate with a backend server behind an internal firewall, where your sensitive code runs.

For extra measure, obfuscate that code.

This would require compromising several layers of security before getting to your code.

1
votes

You can obfuscate it at the C# or CIL level but what is really going to make it impossible is that the IL compiler is designed to create the most efficient machine code that it can to actually execute.

So, to reverse engineer your algorithm, get the machine code and run standard disassembly tools on it. Trace the data through the system by following it forward from the standard input API calls to the standard output API calls.

Face it, if someone wants it, they can have it.

You can make it hard to casually figure it out. For example, I wanted to see what was in some database managed by a Java application. It turned out that the Java decompile was really messy, full of odd functions and classes and namespaces all with the same names, intentionally trying to hide what was really going on.

I could have fixed up the decompiler I was using so that it renamed everything as A_namespace instead of just A and then the function flow would have popped right out to the Eclipse call tracing graphs.

Instead I just threw up my hands and got on with real work rather than rewriting decompilers.

So, you can hide it from casually interested folks, sure.

0
votes

Most obfuscators allow you to specify which methods/classes you want to keep from being obfuscated. SmartAssembly for instance let you mark methods or classses with attributes, while others let you select the methods in a UI to exclude from the process. You ought to be able to have pretty fine grained control of the process, and so you can have your cake and eat it.

You will however run into problems if you are using reflection.

-2
votes

I've heard good comments about the Spices.Net Obfuscator. It should be able to greatly increase the time necessary to get at the algorithm.