Defending Shareware Against Cracks

by Adam Smith




en·crypt (n-krpt)
v. tr. en·crypt·ed, en·crypt·ing, en·crypts.

1. To put into code or cipher.
2. Computer Science. To scramble access codes to (computerized information) so as to prevent unauthorized access.

This document will focus on a very small fraction of encryption. That is, we will only discuss how to protect shareware applications from being pirated using the encrypted keys. While there are many other encryption source code sites, and such on the Internet (see the Links section at the end of this document), we will focus on how to create a system that will confuse any cracker and help prevent him/her from cracking your encryption. There are a few points that I need to make about this article outlining assumptions. This article assumes:

- You are a shareware developer seeking a way to protect your shareware program from being pirated
- You are at or near the advanced level

A note about the last assumption: when I say "advanced," I do not only mean in programming. In fact, even if you only know a few functions and the basic syntax, you can create an above-average encryption scheme using two often under-appreciated virtues: mathematical talent and creativity. I consider them to be of either equal or greater importance than knowing simple functions. Anybody can throw together an encryption algorithm using a couple of neat functions without any real mathematical thought. However, this document is not a tutorial for developing a completely new encryption algorithm. Chances are that you will end up using an already made scheme. So why must one involve mathematical thought in order to develop a *secure* encryption plan? While working to implement a packaged set of code into your application, it would be to your advantage to understand how it works and make any modifications that would either make it faster, more secure, or less faulty. Any modifications you make (provided that they do not impair functionality) will make the cracker's job harder. If you go to a common site and grab their encryption code to use, the cracker may have already seen and/or used this code so they know how it works and therefore can crack it with ease.

Now would be a good time to stop and enlighten those of you wondering what a cracker is. For our purposes, cracker is any entity that is trying to bypass your shareware protection. I have written half-a-dozen applications that have been cracked. That means that the protection was circumvented. Usually, after any given program is cracked, source code that will allow anyone to bypass your protection will be released. This program (which can be an executable, text file, or just about anything else) is called a crack. So crack along with a few suffixes can produce different nouns or verbs.

When I first started considering options for this document, I was overwhelmed. I could write a whole book on shareware protection alone! I have been forced to specialize even more than just shareware protection. As always, I choose to be as unique as possible. All across the Internet, you can find source code for various encryption techniques. Here we will focus away from the actual algorithms and more toward methods of implementation and fooling crackers.

Be Creative!


I would estimate (please remember, this is only an estimate) that 95% of all shareware programs use a kind of string for the key. Whether it is a number, hex value, serial number, or a plethora of pseudo-random characters, crackers are used to these sort of things. I would also assume that about 4.9% of shareware programs use a file as the key. These are also often called certificates. Basically, instead of having a string, a file is used as the key. This method has been found less likely to be cracked because most crackers only evolve their skills to meet the average requirements (cracking a program protected by a string). The remaining 0.1% comprises of other methods. If you only count current releases, none of my shareware programs are cracked. This is not because they are not popular enough; in fact, previous versions have been cracked. As far as current releases go, however, both are in the 0.1%. The more creative you are in your techniques, the more the crackers will be confused and go on to crack the next guy's program.

Now let's take a look at those two programs and their general structure. We won't even touch on their function, but instead look at the encryption schemes.


The scheme here is VERY unique. Not only does it require the appropriate programming skills; it also uses ASP on the server-side for a client-server session. A Microsoft Access Database is kept on the server with a list of all of the registered users. After the user receives confirmation of their registration, they input their name and email address into a form, then click a button. Upon clicking the button, the user starts the client-server session, requesting an URL like Then the ASP file (which can be written in VBScript of JavaScript) checks the database to see if the user is registered. If the user is registered, it will encrypt their key and send it back to the client. If the user is not registered, it will deny the request. Also, as a preventive measure, every time someone requests a look up (regardless of whether or not they are found to be registered), the database records the time, source IP, name, email, and HD serial number of the client.

The encryption algorithm used here is very complex and hard to break. This is necessary because the keys are stored in the registry and can be retrieved by any would-be cracker who can find their hidden location. In fact, the algorithm is so complex, it takes the program about seven seconds to decrypt and verify it on a Pentium 233MMX. The algorithm is a derivative of Skipjack, the secret key encryption algorithm used by the US government in the Clipper chip and Fortezza PC card. It was implemented in tamper-resistant hardware and its structure had been classified since its introduction in 1993. On June 24th, 1998, SkipJack was unclassified, and described in the web site of the NIST.

This particular application was not Internet-related. If it was, for example a FTP client, I could have made the application verify registration every time it started. While encryption would still be necessary, the fact that you would not have to store the keys in the registry would be a big plus. Also with this you could keep track of how often the program is started. You could also use something like this to make a 30-day trial a REAL 30-day trial. With most time-limited trials, the user can set his/her computer clock back to regain functionality after the program has expired. However, if the program refers to the server, time should be accurate.

Lines of code: 500+*

-Real-time verification
-Can monitor usage (and with considerable accuracy determine if the user is using the product on multiple computers; see HD Serial Number under the Precautions section)
-User does not have to keep track of key

-User must be connected to the Internet in order to query the server for their key
-If the server is down, users cannot retrieve registration codes

* Not counting server-side code

Time Manager

This one is fun! Not only that, but it was a real challenge to implement. Here is what the user sees. After someone registers, they receive an email with a HTML file attached. In the HTML file is their name, their password, and their key. The user then encounters a form that looks like the following:

Time Magager's Registration Key Entry Form

As you can see, this is not the typical registration key entry form. It is very unique. The typical cracker after seeing this will say to themself "Ok, time to move on to our next victim."

In this particular program, I am using the Secure Hash Algorithm (SHA-1) along with some simple conversion functions. The result is two strings (name and password) and an image sequence. To enter his or her registration, a user type in their name and password, then click the Start button. After clicking the Start button, the user has eighty seconds to click all of the images from their key in the correct sequence. It can be fun or annoying, depending on the mood of the user. However it is easier-to-use than one would think. After the key is entered, the user never sees anything about registration again.

The major problem with this system is that some user's email clients do not support attachments. Either that or the user did not know how to open HTML attachments. This is the case in about 10%-20% of registered users. For them, I simply upload the HTML file to my web server and they can browse to it just like any other page. This contingency has never failed me, but there are a few security precautions that should be taken to keep other people from accessing this key. The HTML file can be put in a password protected directory if your host supports it; also you can give it an unusual name to the HTML file, and turn off directory listings. Another precaution is to ask the user to tell you once they have accessed and printed their key, then you can remove it from the server.

Lines of code: 400+

-Can be fun

-User's email client must support HTML attachments

Tips & Tricks


Below are legions of various tips and tricks that will help you make your program more secure. I have learned these through much experience in trying to stop crackers in their tracks. Take them to heart.

Serial Numbers

Throughout shareware history, developers have been looking for ways to enforce their policies. For example, I have seen keys that only work on a hard drive with a certain serial number. This is effective. Perhaps too effective, because if a user re-formats their hard drive, they must obtain another key. This is an inconvenience for the user *and* the developer. After paying for your product, any customer will expect for the program to work without any nags. Imagine their surprise when their key is rejected after a re-installation.

This system is often implemented in a challenge-response scheme. When a user wants to register, they open up a registration screen that contains instructions and a certain string. This string is usually either the hard drive serial number itself or a derivative. Then when you are building the key, you input this string and the final product is specific to computers with that input string that is based on that unique hard drive serial number.

There are distinct advantages and disadvantages to limiting a key to a certain hard drive serial number. On one side it will effectively restrict the user from using the program on any computer other than that on which they gave you their challenge from. However, if the user re-formats their hard drive or gets a new computer, the challenge will change, and because of that the original key will not work. At this point the user is obliged to obtain a new key if they wish to continue to use the program that they have already paid for.

This is one of the distinct advantages of the key system that references an Internet server like StuffV. If the user formats and reinstalls, they simply type in their name/email and get their key. The key *can* be hard drive serial number specific to keep users from simply copying the key from one computer to the next via the registry. However, if the user wants to re-install StuffV, they must go through the form. After they submit the form, the hard drive serial number of that machine is recorded on the server. Therefore I can keep track of how many different serial numbers any StuffV user has registered with.

Check for empty fields

It happens to all of us at some point: we release a product with a major bug. It happens to the big guys too (*cough* Microsoft *cough*)! I have seen people write elaborate and complex encryption codes, but fall victim to an extremely simple error. In fact, it happened to the person who got me started in programming. Josh Straub forgot to add a routine to check the length of the name field in an early version of his QuakeNameEditor, so any user could leave the name empty, type in "0" for the key, and become instantly registered!

Check, check, and recheck

When a user inputs their key into your program, don't simply write a boolean variable to the registry, but instead copy the key to the registry. Then, on every execution, check the key from the registry to confirm it. It might even be advisable to check the key at random times in your program, and/or when a function for registered users is called.

A note on variables

When a cracker starts at a program, the typical method is to scan through and monitor all of the variables to try to determine the one that holds the keys and results in a decryption routine. Therefore, if you have a boolean variable named IsRegistered, the cracker will know that all that needs to be done is to write a modification for your program to always switch the IsRegistered variable on at every execution. Therefore, if you must use a boolean variable, give it a misleading name. However, it would be to your advantage if you could hide it even further. For example, in Time Manager, there are a host of variables that hold numbers that work with the time. When the function to validate the key from the registry is called, I could tell it to write a random value between 30 and 60 to an integer variable if the key is valid, but a value between 0 and 29 if the key is invalid. Then, when I wanted to determine if the program is registered, inside a bunch of other complex functions I could stick in stuff like:

if(tsec < 30) {

If tsec < 30 Then
Call HideAdvanced
End if

This is really going to make the cracker's job harder. The only "weak" line in this code is the name of the function: HideAdvanced. It would be better to name it something stealthier. In the case of Time Manager, something like ResetTime might be more appropriate.

(VB Specific) P-Code: The Best

To be honest, I really do not know exactly why it is, but I do know that P-Code is harder to disassemble than Native Code. While it is really neat to be able to optimize your program for things like size, speed, and Pentium Pro processors, this makes the cracker's job easier. Also to take into consideration is that native code can also cause other problems such as the compiler executing the program incorrectly.

Discombobulate now!

Your job as a shareware developer is to confuse the cracker in your key system. Again, be creative (yes, that's an order)! Make sure to integrate some of your routines into your main data functions, so it is impossible to figure out. You can add in a simple layer to the encryption scheme that could share a function with the main data functions. For example, in Time Manager, when the user enters their values for the time to start at, the program will take the seconds field and if it is greater than 59, convert it to a new hour/minute/second value. So if the seconds is 150, Time Manager will convert this to two minutes and 30 seconds. This could be used as a primitive mod function. Now imagine the cracker trying to figure that out!

Layer, layer, crack slayer

When the Russians were making their first Atomic bombs, they found that a good way to induce pressure on the Uranium-235 was to stack it in layers with some conventional explosives. For every layer they added the bomb's power was increased exponentially. In the same way, a highly secure program will use multiple layers of encryption. Even if one is a simple Xor routine and another is an easy Caesar algorithm, as long as there is a strong element somewhere, all of the little things will pay off. Here is a sample flow chart of three encryption techniques that we will lovingly call A, B, and C. The terms Name and Key are simply generic; you can use anything here!

Name >> EncryptA >> EncryptB >> EncryptC >> Key

Key >> DecryptC >> DecryptB >> DecryptA >> Name

It's that simple!

Armed Combat


Are you ready to take active measures against crackers? This is for the people who really want to target the crackers in their programs. This isn't easy, and should only be attempted by the best of the best. If you are one of these few, suit up and prepare to brandish your programming sword!

Let me open with an example for an introduction. At one time, I noticed that a certain site was serving a crack to one of my programs. That was the only site that I could find that had it. The site was first brought to my attention when I was looking at the sites that people were coming from on my website statistics. A fair amount of traffic was coming from this page advertising the crack. I decided to set up an ASP script that would separate the traffic coming from this site and the traffic coming from everywhere else. The traffic coming from that site downloaded a version of the program that would do various things to the machine it was ran on, such as deleting all of the DLL files it could. All other traffic was directed to the real thing. A total of 12 copies of the malicious version were downloaded. I never heard a word about it from anyone. After a while, though, the crack was taken down. Victory.

Looking back now, I see how effective it was. I also can see more clearly how risky it was. I probably could have been legally prosecuted for it. While it serves as a good example of what Armed Combat really is, we will not discuss or promote wreaking havoc on a machine here.

This section will be presented in two sub-sections. In the first we will discuss how to identify when the program is being attacked by a cracker, then we will discuss what to do about it.

A big warning that EVERYONE should read: Don't cross the line. Nothing you do should interfere with the end user's experience. If your protection is so elaborate that you're warding off the legitimate users, it doesn't matter how good your program or how secure your protection is, you've lost. If a newbie does something wrong or weird and they see a message box saying "GO AWAY YOU CRACKER!" that's not good for business. You want to make a direct distinction of what the end user sees and what the cracker sees. The legitimate user should see a terse and modest key entry form while the underlying code is very complex. Then, the cracker will have to look at the code, trying to figure out what it is doing.

Detection: the first step to protection

Here is where we will test your creativity. I will only give you one possible method of detection here. You can then either use it or make up your own.

Declare a boolean variable IsRegistered. Set it to false, *never* set it to true. Do checks when you're bringing up the main form. If the variable is ever true, then your program has been tampered with.


"Tell me where you at, I will be there in ten seconds flat. You know I got your back, I'll be there just in time to counteract.

- Busta Rhymes, "Fire it up"

Now that we have identified that the program has been tampered with, we can take action. Here we have a few interesting options:

a) Wreak havoc (this will not be discussed)
b) Ignore it
c) Fake the cracker out

There are more than these; you only need to be (again) creative. If we ignore the variable, we will only have succeeded in wasting some of their time. On the other side, we can also fake them out. How? After detecting that the program has been tampered with, change the program to act as if it were registered. However, encrypt the current date (anything here will do, including Xor) and write it to the registry or hide it in some other corner of their computer. Every time the program starts, search for this date. If the date can be found, you have a record of when the tampering was first detected. If the current date is three or more days after when the first tampering was detected, give the cracker a nice message box saying something to the effect of it didn't work, then either close out the program or let it continue unregistered.

Why the three day period? By the time that point is reached, the user will have probably already distributed the crack to his friends. Eventually it will probably reach the general public. After three days, it will stop working, however. Then, the cracker will be labeled as a lamer in the cracker community.

Sounds pretty easy, huh? Yeah, maybe so. Nevertheless, you must be extremely stealthy about it. If you just put it out there in plain code, maybe the newest of crackers will fall victim to the trap, but the adept will catch on. Be creative and set it's roots deep into the main functions of your program. This is why at the beginning of this section I warned that only the best should try this one.

Cracks happen

Eventually, at some point one of your programs will be cracked. That is provided that they are popular enough and that there are enough of them. What do you do then? Fire up your tools and prepare for battle.


Before you can start to fight against a crack, you have to know that it exists. I am not going to turn this section in to a document outlining how to find a crack for any program. However, some good sites to look at are and you can run searches with keywords like "crack download YOUR-PROGRAM-NAME-HERE."

It is also a good idea to make friends with some crackers. A lot of them will give you advice on what to do and what not to do. They can also help keep a look out for cracks. Actually, tell all of your friends to keep a look out for cracks.

Taking Action

After a crack is released, you must then try to defeat it. It is generally best to redesign your encryption scheme, as this is the only long-term (hopefully) fix! Unfortunately, it involves re-sending keys to all of your users; either that or simply issuing new keys upon request (this is generally the best option). To design a fully reliable encryption scheme can take hours, even days. However, sooner or later will be necessary.

After you have completed your changes, you must decide whether or not you want to release a new version. If you do decide to do that, you can't hurt the cracker's reputation as described below. In fact, I wouldn't recommend releasing a new version unless you have a multitude of new features in it. My reasoning is that these features should persuade users to leave the old cracked version and to upgrade to the new version, which they will have to pay for. If you do not release a new version but replace all of the old cracked versions, then the problem should be remedied.

Replacing Files

This topic is often overlooked. When you have a new fix, you want to replace your old program with the new one as soon as possible. The sooner you do it, the fewer people that will have the crack, and the more registrations you will have. Consequently, it is extremely important to maintain good control over your distribution points. One of the best schemes to have here is as follows:

Primary: On the same server as your website, you should have direct control.

Secondary: To be used if primary is too slow; these guys should have MEGA bandwidth. You should have a contact here that has direct control.

3rd-ary: This can be your friend's cable modem that is on 24/7, which you can send ICQ updates to.

In the case that a crack is released, you need to be able to replace the old version very quickly. This is the only thing I have against big servers such as Simtel.Net. It may take days for them to update their files. The same is true for ZDNet Downloads, who insists on having their own copy of your software on their servers. One can be caught having to wait for days or even weeks to get a program updated. Yet I still have my software on their site, for the publicity. Remember that it doesn't matter how good your program or encryption is if you go so far as to hinder the real users.

Now, moving on, if you like you can possibly hurt the cracker's reputation. In every crack there is almost always an address at which the user of the crack can download the main program. Now, let us assume that a working crack has been widely distributed and many users are downloading your program only to be cracked. After discovering this, here is what you do:

a) Fix the program so that the crack no longer works (described above)
b) Adjust the file's dates and times in which they were created
c) Zip 'em up (or whatever you do for your distribution)
d) Set the zip date and time to the same as the original
e) Upload

I'll leave the changing of the file information up to you. Now if the cracker claims that you changed the program so that the crack no longer works, he will be put down. As far as the end users see, the program is the exact same as it was before. But the crack doesn't work!


In conclusion, I would like to drive home two main points:

a) Remember, there is no such thing as a program that cannot be cracked!
b) Also remember that if you overdo yourself, you will lose potential customers. Do not cross the line!

That's it! I hope that you learned something from this document.
Copyright © 2000 Sense of Security Incorporated All Rights Reserved.