KeygenMe - 0x0

KeyGen-me#1.exe by devilz


This is a beginner level keygenme that we will analyze to grasp an introduction into keygenning. We will find the correct serial for our name and we will also code a keygen to generate a serial for any other names.

Tools & Requirements

We'll first breakpoint on GetDlgItemTextA. Our first two breakpoints at 4010EE and 40111F are simply checks to make sure that the input fields aren't blank. Starting at 40113F the target again grabs the input of the name entered, but this time stores it into esi. Our first look at the serial keygen algorithm is here:

00401158 | mov esi,keygen-me#1.403380              | esi:"sh!ft", 403380:"sh!ft"
0040115D | mov bl,byte ptr ds:[ecx+esi]            | char byte = esi[ecx]
00401160 | add eax,ebx                             | 
00401162 | inc ecx                                 | ; move to next character
00401163 | cmp bl,0                                | ; end of string comparison
00401166 | jne keygen-me#1.40115D                  |

It's a very simple algorithm in which it cycles through each of the characters in the name, adds it to eax (starts at 0), increments ecx (index), and then checks to see if the character is equal to 0 (null byte termination) indicating the end of the string.

Once we're at the end of the string, the target then moves to the next part of our algorithm:

00401168 | mov edx,28                              | 28:'('
0040116D | mul edx                                 |
0040116F | add eax,19                              |
00401172 | push eax                                | ; correct serial
00401173 | push keygen-me#1.403364                 | ; format 403364:"%d"
00401178 | push keygen-me#1.40339A                 | ; buffer
0040117D | call <JMP.&wsprintfA>                   | 

Luckily this algorithm is very short as well. We essentially take the calculated value stored in eax and multiply it by 0x28 and then add it to 0x19. We then take that calculated value stored in eax and copy it into a buffer located at 40339A using wsprintfA.


00401182 | add esp,C                               |
00401185 | mov edx,keygen-me#1.40339A              | edx:"18825", 40339A:"18825"
0040118A | push edx                                | edx:"18825"
0040118B | push C                                  |
0040118D | push keygen-me#1.40338D                 |
00401192 | push C8                                 |
00401197 | push dword ptr ss:[ebp+8]               |
0040119A | call <JMP.&GetDlgItemTextA>             |

At this point you can see that edx is holding our correct serial of 18825. This part of the disassembly isn't too important, really it's just saving the correct serial to the stack and getting the serial we entered into the program earlier. Lets continue:


0040119F | mov esi,keygen-me#1.40338D              | esi:"sh!ft"
004011A4 | pop edx                                 | edx:"18825"
004011A5 | mov eax,dword ptr ds:[esi]              | esi:"sh!ft"
004011A7 | mov ebx,dword ptr ds:[edx]              | edx:"18825"
004011A9 | cmp eax,ebx                             |
004011AB | jne keygen-me#1.4011C2                  |

This portion is perhaps the most interesting to us as this is the deciding conditional jump that will take us to the goodboy or badboy message. It looks a bit convoluted, probably because it was custom written in x86 by the author. However, all it's doing is taking the values of our entered serial and correct serials and placing them into eax, and ebx respectively. It then compares those to values to see if we have entered the correct serial.

Coding the Keygen

Now that we have analyzed the target, we have sufficient knowledge of how to program a keygen for it. Recall this section:

00401158 | mov esi,keygen-me#1.403380              | esi:"sh!ft", 403380:"sh!ft"
0040115D | mov bl,byte ptr ds:[ecx+esi]            | char byte = esi[ecx]
00401160 | add eax,ebx                             | 
00401162 | inc ecx                                 | ; move to next character
00401163 | cmp bl,0                                | ; end of string comparison
00401166 | jne keygen-me#1.40115D                  |
00401168 | mov edx,28                              | ; edx = 0x28
0040116D | mul edx                                 | ; eax *= edx
0040116F | add eax,19                              | ; eax += 0x19
00401172 | push eax                                | ; correct serial

We know that we'll have to create a loop in which we keep adding each character of the string to itself. Luckily since a single character is also represented as an integer, we can perform simple math on this without needing to convert types in C.

#include <stdio.h>
#include <string.h>
int main() {
  char* name = "sh!ft";
  unsigned int serial = 0;
  for (int i = 0; i < strlen(name); i++) {
    serial += name[i];
  }
  return 0;
}

Simple enough right? All that's happening here is that we take the index of our name as if it were an integer and add it to the initial integer of 0 until we reach the end of the string. Now we just need a simple calculation for multiplying the result of the loop by 0x28 and adding that by 0x19.

  for...
  }
  serial = (serial * 0x28) + 0x19;
  printf("Serial: %d\n", serial);
  return 0;
}

Just like that we've made a keygen for any name you wish!