Cracking a Game

From SkullSecurity
Jump to navigation Jump to search
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.

Common Protections

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.

Questions

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.