Keygenning: Part I

Souhail Hammou
August 30, 2013 by
Souhail Hammou

Introduction :

A key generator or a Keygen is a computer program that will generate a valid « Product Serial or Key » in order to completely register a software.

What should you learn next?

What should you learn next?

From SOC Analyst to Secure Coder to Security Manager — our team of experts has 12 free training plans to help you hit your goals. Get your free copy now.

The key generation process may require a name or e-mail to generate the serial, in other cases where no name or e-mail is required the validity of the serial may be checked by relying on hardware or using an algorithm that will play with the serial parts in order to determine if the provided key is correct or not.

Different from patching and serial phishing, keygenning is defined as one of the hardest cracking techniques based on the fact that when coding, a working keygen you need to fully understand how the serial checking algorithm is working. This algorithm may relay on cryptography for instance MD5 hashing.

So after understanding how the serial checking algorithm works, the reverser must code a computer program in thier favorite programming language that will generate a valid key, serial or license for the targeted software.

If the software requires a name or e-mail and they are involved in the generation algorithm inside the targeted software, the reverser has many ways to code a keygen : one of the simplest is to program a keygen that will relay on the SAME instructions used by the software to generate the serial. I think that this is what we call a « Ripped Keygen » . In my point of view, I don't think that this is a good practice of keygenning because in many cases it's similar to a copy/paste.

The best thing that can be done is coding an « Unripped Keygen », that will do the same but using a different set of instructions which will make you learn far better than ripping the keygeneration routine itself.

I - KeygenMe :

A keygenMe is a computer program completely made by reververs for other reversers, the only accepted solution for the KeygenMe is coding a valid keygen that will generate a valid serial or key according to what the keygenMe needs.

To make it « fun » and interesting I managed to code a KeygenMe in my favorite programming langage X86 assembly / MASM syntax with a serial checking algorithm that you will see in details, later in this article. The KeygenMe and Keygen download links are in the references below.

So I'll pretend that I have Zero-knowledge about this KeygenMe and start from the examination until completely coding a Keygen. Let's get started.

Examining the KeygenMe :

First of all, before starting to debug the KeygenMe you have to see what it demands from you: is it a serial ? A license file ? … etc

Let's open it and see what it needs :

As you can clearly see, the KeygenMe needs our email address and a serial number. After entering a random WRONG serial the KeygenMe prints "Invalid Serial".

With Zero-knowledge you can't actually guess if, the serial is generated based on the e-mail or not, only debugging this KeygenMe will get you the answer. So let's open it inside Immunity and see what it has for us.

I will start by checking what happens exactly after providing our e-mail to the KeygenMe:

[caption id="" align="aligncenter" width="620"]Click to Enlarge Click to Enlarge[/caption]

As you see, I tried to write short comments in front of important instructions. So what the KeygenMe does with our e-mail, is checking for its validity by seeing if it has the "@" sign in it and if there are at least 4 characters before the @ sign.

Keep in mind that we're not sure that the mail is used or not .Simply because it's still stored at memory address 00403150.

As the serial checking routine is a little bigger to be shown in one image, I will explain it to you part by part.

Let's see what the KeygenMe dœs directly after providing an input string, as you saw this input « 111122223333444455556666 » won't get us anywhere. Let's discover why :

[caption id="" align="aligncenter" width="619"]Click to Enlarge Click to Enlarge[/caption]

You can clearly see that the KeygenMe will check the input length, check if the string « ITS– » is present then locate 3 more dashes (–). As a result the serial general format should be given by the user this way : ITS-XXXX-XXXX-XXXX-XXXX, where ITS– is a harcoded string and X's are unknown for us in the mean time.

Now let's start analyzing the next part :

[caption id="" align="aligncenter" width="621"]Click to Enlarge Click to Enlarge[/caption]

This set of instructions will simply skip the first DWORD which is "ITS-" and place each of the fourth different parts of the serial in an seperated memory location. For example the first part of the serial which will come after the hardcoded string, will be placed in a DWORD that is located in memory address 004051A8.

We can suppose now that the serial checking algorithm will deal with each part of the serial alone, but we cannot judge yet because the algorithm may also link between those different parts.

Anyway, let's see what the next instructions are dealing with:

[caption id="" align="aligncenter" width="621"]Click to Enlarge Click to Enlarge[/caption]

In this phase, we started to deal with the serial checking algorithm. The serial that we have to provide must have 5 parts. Each part is recognized by a dash "-". I said that the first part is hardcoded so in the algorithm the KeygenMe will directly start dealing with the second part. Let's suppose that we provided this serial to the KeygenMe : ITS-1111-2222-3333-4444

If we had provided this serial, all the previous checks would have gone right. But this check wouldn't have gone right because simply the 2nd part of the serial which is "1111" is WRONG.

Let's try to see what's wrong and how can we fix that.

As you can clearly see the KeygenMe works on moving the DWORD in the first part into EAX register, our input is "1111" so the EAX register should hold "31313131" which is the translation of "1111" from ASCII into a Hexadecimal format. Now twill substract « 30303030 » from EAX resulting in « 01010101 ».

This value will replace the existing value in 004051A8. Now, the KeygenMe will try to do a simple addition between those bytes : 01 + 01 + 01 + 01 = 04 which is not 10h, that's why we will jump into the "invalid serial" message.

For the mean time you just need to note what you discovered here in a Notepad or somewhere you can remember it and move on to the third part of the checking routine.

[caption id="" align="aligncenter" width="618"]Click to Enlarge Click to Enlarge[/caption]

The 3rd part checking is quite different from the second one, it will simply compare the first character of our input to the letter "O", then adds the next two bytes to the 4Fh (which is O in hex) and substracts the last byte from the addition result, the final result should be held in BL and equals 8Fh.

Note: You can conclude that in this part it's preferable to use Capital letters starting in hexadecimal from 41h to 5Ah in the serial (using numbers is not a bad idea either).

For now, let's move on to the fourth part checking :

[caption id="" align="aligncenter" width="618"]Click to Enlarge Click to Enlarge[/caption]

The 4th part checking set of instructions are similar to the second part, the only difference that you can see is that 2 is substracted from the last byte of the 4th part of the serial. Then the resulted value is added to the previous total. The final result should be 10h.

E.I : If the user managed to pass all the previous checks with correct input or by patching jumps which is RESTRICTED in a KeygenMe. Here's what will happen with the input "3333" :

33333333 - 30303030 = 03 03 03 03. Then : 03 + 03 + 03 = 09, and the substraction : 03 - 02 = 01. And the addition finally : 09 + 01 = 0Ah which is different from 10h, the jump will be then taken to the invalid serial message routine.

Let's see what the last check has for us:

[caption id="" align="aligncenter" width="619"]Click to Enlarge Click to Enlarge[/caption]

So, the same thing as the second part of the serial is happening here, the only difference is that the resulted value should be 12h instead of 10h. Then we have the conditional jump that will take us to the unwanted message when the resulted value differs from 12h.

Now as we discovered together how the KeygenMe works on checking the validity of our serial, part by part and that the e-mail has no relation at all with the serial checking algorithim let's go and code a keygen for it.

II - Writing a Valid Keygen:

So now, we need to program a Keygen that will generate an infinite number of Random serials.So you will have to write it in your favorite programming language.

So to practice you are freely welcome to write the Keygen in any language you want and why not e-mail me your keygen to check it.

Random Value Generation :

One of the problems that you may face is how to code a keygen that will make you able to generate random characters for the serial.

Well, there are several ways to achieve this and I'm about to introduce you some techniques :

- GetLocalTime : This API will work on getting the current date and time, the interesting thing here is taking advantage of seconds or milliseconds (which occupy the sixth and the seventh words in the SYSTEMTIME structure) in order to generate a value especially if you're working on a multiple serial generation.

-GetTickCount : This is also a Win32 API that will retreive the milliseconds that were elapsed since the system was started (MSDN), GetTickCount will return a 32bits value to eax register. We can take advantage of this returned value especially AL or AH if we're interested in one byte. In addition, setting conditions in the code is obligatory to get the value in a specific range (Printable Characters).

-Other Methods : There are many ways to generate random values, some of them are related to cryptography. Windows is providing CryptGenRandom function for this purpose.

Random Value Generation & Looping:

Let's get back to the point where I said you must provide certain conditions when generating a random value, there are two cases here when using GetTickCount API :

The first one is obligatory, you'll need to set a loop where the return value in AL or AH (if you're interested in generating 1 byte) must be printable and/or in a specific ASCII characters range.

The second one is decided by the serial checking algorithm that will show you if there are additional conditions for example the Software will not accept a serial where two identical consecutive characters are provided.

This is the main reason why the serial generation process may take some seconds, because the keygen will keep looping until the right value is found relaying on conditions provided.

We can consider this as a drawback. However, we can turn this into a positive point in our keygen with a message that is telling the user to wait for a couple seconds until the valid serial is generated.

Serial Generation :

In the KeygenMe that we analyzed you noticed that each part of the serial (4 characters in each part) is checked alone, and also it depends on simple math operations like addition and substraction. So to generate a valid part of the serial we will need to set 3 random characters and solve a simple equation to determine the missing characters to get a valid serial.

Now, you may realize that additional loops must take place which will check if the result of the equation is also a printable ASCII character or not.

The Keygen:

Here is the Keygen source code written in x86 ASM / MASM32 syntax (some code is additional in the serial checking algorithm like trying to avoid two consecutive identical characters):

The serial generation steps are well commented step by step :


Running the keygen :

Assemble then link the keygen's source code and run it . You will be able to generate multiple valid serial numbers for the KeygenMe by pressing Return key.

[caption id="" align="aligncenter" width="621"]Click to Enlarge Click to Enlarge[/caption]

III - Conclusion :

In this article you were able to see how to analyze a Serial Checking Algorithm and code a valid key generator that will help you generate different serial numbers. No hashing or cryptography was present in this KeygenMe and the algorithm was quite simple. In the next part I will try to introduce a more harder KeygenMe with a complete tutorial on how to code a valid Keygen for it.


KeygenMe & Keygen download : http://www.mediafire.com/download/4em6cf3wwu3deu5/IS-KeyGenning_Part1.zip

Keygen Source Code : https://gist.github.com/SouhailHammou/0746b573136ba3ca0e67




FREE role-guided training plans

FREE role-guided training plans

Get 12 cybersecurity training plans — one for each of the most common roles requested by employers.


Souhail Hammou
Souhail Hammou

Souhail Hammou is a Moroccan reverse engineering enthusiast who likes to spend most of his time exploring Windows Internals and playing in CTF contests.