views:

1089

answers:

7

This is a problem we all have to consider at some point.

After many years and many approaches I tend to agree in general with the staterment: "For any protected software used by more than a few hundred people, you can find a cracked version. So far, every protection scheme can be tampered with." http://stackoverflow.com/questions/343017/does-your-employer-enforce-the-use-of-anti-piracy-software

Further, every time I post about this subject, some one will remind me; "First of all, no matter what kind of protection you'll employ,a truly dedicated cracker will, eventually, get through all of the protective barriers." http://stackoverflow.com/questions/71146/whats-the-best-value-for-money-c-code-protection-for-a-single-developer

So not withstanding these two broadly true disclaimers, lets talk about "protection"!

I still feel that for smaller apps that are unlikely to warrent the time and attention of a skilled cracker, protection IS a worthwhile exercise.

It seems obvious that no matter what you do, if the cracker can switch the outcome of an IF statement (jmp) by patching the application, then all the passwords and dongles in the world anre not going to help.

So My approach has been to obfuscate the code with virtualization using products like: http://www.oreans.com/codevirtualizer.php I have been very happy with this product. To my knowledge it has neve been defeated. I can even compress the executable with PEcompact Does anyone else have experience with it?

Had nothing but problems with EXEcryptor http://www.strongbit.com/news.asp Even the site is a headache to use. The compiled apps would crash when doing any WMI calls.

This approach allows you to surround smaller sections of code with the obfuscation and thus protect the security checking etc.

I Use the online authorization approach, as the application needs data from the server regularly so it makes no sense for the user to use it off line for extended periods. By definition, the app is worthless at that point, even if it is cracked.

So a simple encrypted handshake is plenty good. I just check it occasionally within the obfuscation protection. If the user installs the app on a different machine, a New ID is uploaded upon launch and the server disables the old ID and returns a new authorization.

I also use a hash of the compiled app and check it at launch to see if a single bit has changed, then open the app as a file (with a read LOCK) from within the app to prevent anyone changing it once launched.

Since all static strings are clearly visible in the .exe file, I try to be generic with error messages and so forth. You will not find the string "Authorization failed" anywhere.

To protect against memory dumps, I use a simple text obfuscation technique (like XOR every character) This makes plain text data in memory harder to distinguish from variables and so forth.

Then of course there is AES for any data that is really sensitive. I like counter mode for text as this results in no repeating sequences revealing underlying data like a sequence of white spaces.

But with all these techniques, if the Key or Initialization vector can be dumped from memory, or the IF statement bypassed, everything is wasted.

I tend to use a switch statement rather than a conditional statement. Then I create a second function that is basically a dead end instead of the function that actually performs the desired task.

Another idea is to code pointers with a variable added. The variable is the result of the authorization (usually zero). This will inevitable lead to a GPF at some point. I only use this as a last resort after a few lower level authorizations have failed otherwise real users may encounter it. Then the reputation of your software is lowered.

What techniques do you use?

(this is NOT a thread debating the merits of implementing something. It is designed for those that have decided to do SOMETHING)

+6  A: 

I personally use the code techniques discussed here. These tricks have the benefit of inconveniencing pirates without making life more difficult for your legitimate end-users

But the more interesting question isn't "what", but "why". Before a software vendor embarks on this type of exercise, it's really important to build a threat model. For example, the threats for a low-priced B2C game are entirely different to those for a high-value B2B app.

Patrick Mackenzie has a good essay where he discusses some of the threats, including an analysis of 4 types of potential customer. I recommend doing this threat analysis for your own app before making choices about protecting your business model.

RoadWarrior
+8  A: 

I disagree xsl.

We protect our code, not because we want to protect our revenue - we accept that those who would use if without a license probably would never pay for it anyway.

Instead, we do it to protect the investment our customers have made in our software. We believe that the use of our software makes them more competative in their market place and that if other companies have access to it without paying they have an unfair advantage - ie, they become as competative without having the overhead of the licensing cost.

We are very careful to ensure that the protection - which is home grown - is as unobtrusive as possible to the valid users, and to this end we would never consider 'buying in' an off the shelf solution that may impact this.

Martin
This is just a rationalization. If you are really so concerned about the competitive disadvantage the high cost of your software puts on your customers, you could more easily fix the problem by lowering the cost.
T.E.D.
I disagree ted. Our software is very niche, the company would not be able to sustain itself if we charged less. With less than a hundreds seats, and near saturation lowering costs would remove the product from the market completey.
Martin
+10  A: 

You don't need a few hundred users to get your software cracked. I got annoyed at having my shareware cracked so many times, so as an experiment I created a program called Magic Textbox (which was just a form with a textbox on it) and released it to shareware sites (it had its own PAD file and everything). A day later a cracked version of Magic Textbox was available.

This experience made me pretty much give up trying to protect my software with anything more than rudimentary copy protection.

MusiGenesis
I bet there is a torrent of the original Magic Textbox somewhere :)
Jens Roland
If not, it wouldn't be too hard to rewrite it, maybe in .NET this time. :)
MusiGenesis
+1  A: 

I have used .NET Reactor in the past with good results - http://www.eziriz.com/

What I liked about this product is that it did not require you to obfuscate the code in order to have pretty good protection.

Sam Schutte
.NET Reactor is frequently unpacked by crackers
Simucal
Their is no support from this company, all the support emails are unanswered.
Priyank Bolia
+5  A: 

I've implemented hardware keying (dongles) before myself, so I'm not totally unfamiliar with the issues. In fact, I've given it a great deal of thought. I don't agree with anyone violating copyright law, as your crackers are doing. Anyone who doesn't want to legally aquire a copy of your software should do without. I don't ever violate software copyright myself. That being said...

I really, really dislike the word "protect" used here. The only thing you are trying to protect is your control. You are not protecting the software. The software is just fine either way, as are your users.

The reason that keeping people from copying and sharing your software is such an unholy PITA is that preventing such activites is unnatural. The whole concept of a computer revolves around copying data, and it is simple human nature to want to share useful things. You can fight these facts if you really insist, but it will be a lifelong fight. God isn't making humans any differently, and I'm not buying a computer that can't copy things. Perhaps it would be better to find some way to work with computers and people, rather than fighting against them all the time?

I, along with the majority of professional software developers, am employed full time by a company that needs software developed so that it can do its business, not so it can have a "software product" with artificial scarcity to "sell" to users. If I write something generally useful (that isn't considered a "competive advantage" here), we can release it as Free Software. No "protection" is needed.

T.E.D.
+3  A: 

xsl, that is a very narrow point of view with MANY built in assumtions.

It seems obvious to me that any app that relies on delivering something from a server under your control should be able to do a fairly good job of figuring our who has a valid account!

I am also of the belief that regular updates (meaning a newly compiled app with code in different locations) will make cracked vesrions obsolete quickly. If your app communicates with a server, launching a secondary process to replace the main executable every week is a piece of cake.

So yes, nothing is uncrackable, but with some clever intrinsic design, it becomes a moot point. The only factor that is significant is how much time are the crackers willing to spend on it, and how much effort are your potential customers willing to exert in trying to find the product of their efforts on a weekly or even daily basis!

I suspect that if your app provides a usefull valuable function then they will be willing to pay a fair price for it. If not, Competitive products will enter the market and your problme just solved itself.

Mike Trader
+1  A: 

From some of the links:

The concept I tried to explain is what I call the “crack spread”. It doesn’t matter that a crack (or keygen, or pirated serial, or whatever) exists for your application. What matters is how many people have access to the crack.

Where/when to check the serial number: I check once on startup. A lot of people say “Check in all sorts of places”, to make it harder for someone to crack by stripping out the check. If you want to be particularly nasty to the cracker, check in all sorts of places using inlined code (i.e. DON’T externalize it all into SerialNumberVerifier.class) and if at all possible make it multi-threaded and hard to recognize when it fails, too. But this just makes it harder to make the crack, not impossible, and remember your goal is generally not to defeat the cracker. Defeating the cracker does not make you an appreciable amount of money. You just need to defeat the casual user in most instances, and the casual user does not have access to a debugger nor know how to use one.

If you’re going to phone home, you should be phoning home with their user information and accepting the serial number as the output of your server’s script, not phoning home with the serial number and accepting a boolean, etc, as the output. i.e. you should be doing key injection, not key verification. Key verification has to ultimately happen within the application, which is why public key crypto is the best way to do it. The reason is that the Internet connection is also in the hands of the adversary :) You’re a hosts file change away from a break-once, break-everywhere exploit if your software is just expecting to read a boolean off the Internet.

Do not make an “interesting” or “challenging” protection. Many crackers crack for the intellectual challenge alone. Make your protection hard to crack but as boring as possible.

There are some cracks which search for byte patterns in search for the place to patch. They usually aren’t defeated by a recompile, but if your .EXE is packed (by ASProtect, Armadillo, etc) these kind of cracks must first unpack the .EXE.. and if you use a good packer such as ASProtect, the cracker will be able to unpack the EXE manually using an assembly level debugger such as SoftICE, but won’t be able to create a tool which unpacks the .EXE automatically (to apply the byte patches afterwards).

Mike Trader
The meer fact that you are referring to your users as "the adversary" should point out just how far off the path you have strayed here. :-(
T.E.D.
Users that have stolen the software, are by definition the adversary...
Mike Trader