Cracking a Game
|Assembly Language Tutorial|
| Please choose a tutorial page:
This section will go over several techniques used by crackers to register games/software. I don't mention cd-cracks, because I don't know how to do those; rather, I mention attacks that are generally based on a key or registration code.
The most common protection, and the one discussed here, is when a program requires a registration key to unlock. Usually, the key is based either on a random registration code provided by the program, or based on the username you enter.
I'll list some definitions here. Note that these definitions are mine, and won't necessarily correspond to definitions others use. These are simply to make it easier to understand this and proceeding sections:
- A registration code is a code generated by a program, that the registration key is derived from or checked against.
- A registration username or just username is a username that a user enters. The registration key is based on that username.
- A registration key is the key used to unlock a program. It may be based on a registration code, on a registration username, or based on nothing at all.
Finding the Spot
The very first example goes over Starcraft's CDKey verification algorithm, but I provided the algorithm. Starcraft's is the simplest kind of verification, the key verifies itself without a username or code. The question is, how do you find the algorithm?
Well, the unfortunate answer is, it varies, and it generally isn't easy.
The first step is obviously to disassemble the program. After that, as a cracker, you have to try and find a weak point in the program. Here are several techniques:
- Search for the text prompting for the key
- Search for the registration code in memory, and find out where it's accessed
- Enter a code, have it fail, then search memory for that failed code
- Search for anything unique about the registration (colors, text, dialogs, etc).
- Search for the registry key that stores the key
- Search for a file that stores registration information
- Search for the error message when a bad key is given
The last technique is the most useful one, I've found. However, trying them all, and trying anything else that seems to suit the game works best. In the example in the next section, I found that searching for the text informing the user that the software is unregistered worked well for the game, as you'll see later. I may do a second example where I searched for the file that stored the key, and where it was created.
To find Starcraft's CDKey verifier, I started with the network traffic, at the Winsock function (send() and recv()). From there, I backtracked to find where the packet is sent that validates the Starcraft key with Battle.net. It was a lot of work, but at the time I was learning about Starcraft's network activity so it was mostly a side-effect of what I was already doing. If I continue writing these tutorials, I might eventually get into that much detail, but I have no plans to yet.
Cracking the Game
Once the right spot is found, cracking a game is often very easy. Typically, a program will have the following code:
if(keyIsValid) unlock() else displayError()
The assembly for that would look like:
85 xx test keyIsValid, keyIsValid 74 06 jz error e8 xx xx xx xx call unlock eb 06 jmp done error: e8 xx xx xx xx call displayError done:
As discussed in the section on machine code, the bytes to the left may be the machine code bytes (I did them quickly from a reference sheet, so they may or may not be exactly correct. This program can be modified by changing a couple bytes, which can either force the code to jump always or jump never.
To force the code to jump (which, in this case, will make the key always valid), the jz is replaced with a jmp (by changing 74 to eb):
85 xx test keyIsValid, keyIsValid eb 06 jmp error e8 xx xx xx xx call unlock eb 06 jmp done error: e8 xx xx xx xx call displayError done:
To prevent the code from jumping (which, in this case, will make the key always valid), the jz is replaced with a pair of nop instructions:
85 xx test keyIsValid, keyIsValid 90 nop 90 nop e8 xx xx xx xx call unlock eb 06 jmp done error: e8 xx xx xx xx call displayError done:
Make the appropriate change, run the game, and type in any code. The expected result should occur!
The next example will show this on an actual game (on a game that I won't name here, for obvious reasons).
Writing a Keygen
Even better than cracking a game is writing a keygen for it. The user enters their username or registration code, and the keygen outputs a valid key.
Generally, this requires that the algorithm be fully reverse engineered and understood. Then a copy of it is made in C (or whatever language) which produces the same results. Note that the first three examples in this tutorial do just that: turning the assembly code back into C. So anybody who actually followed them should be in a good position to write a keygen, which will come in a later tutorial.
Feel free to edit this section and post questions, I'll do my best to answer them. But you may need to contact me to let me know that a question exists.