What we have to do:
Find a valid serial
Write a keygenerator
First of all, let me explain how keygenning works... Lets suppose that you want to register an app.
How can that be accomplished?
Most apps ask you of a username and a valid serial.
( What do they take as a valid serial?
Each app has its own serial-generating algorithm, that will examine your username character-to-character and produce a serial.
The structure of the algorithm is the app coder's choice.HE decides what a valid serial will be for each username.)
Then, they take your input and based on your username, the generate the valid serial.
Then, they compare the serial you entered to the one they generated and if they are equal - BINGO - you have registered the app!!!
So, in order to fish a serial we take the app that we want to make the keygenerator for, and examine the serial-checking algorithm.
The one of the two serials is the correct one, so we try to find it in memory ;-)
Open up the crackme and click 'Check' just to see what error messages it gives us when we enter a wrong serial
When dealing with larger apps(real life,commercial apps that will probably have more lines of code than just the code for the registration process ;-)) it is very useful to write the text of the error message down so that later you can use it to find the lines of the code that compose the serial checking process.
But in our case, the crackme won't have so many lines so we can just open it in OllyDbg (File-->Open) and scroll down a bit until we find some references of the GetWindowText API or the GetDlgItemText API or the SendMessage/SendDlgItemMessage API combined with the WM_GETTEXT message
These are the most common ways to get the text from an edit box when dealing with asm-compiled apps.
In our case:
0040121B /$ 55 PUSH EBP
0040121C |. 8BEC MOV EBP,ESP
0040121E |. 81C4 00FFFFFF ADD ESP,-100
00401224 |. 56 PUSH ESI
00401225 |. 57 PUSH EDI
00401226 |. 51 PUSH ECX
00401227 |. 53 PUSH EBX ;Nothing that we should care about
00401228 |. 52 PUSH EDX ;until here
00401229 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ;ESI=Address of Username
0040122C |. 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+C] ;EDI=Address of Serial
0040122F |. 33C9 XOR ECX,ECX ;/
00401231 |. 33DB XOR EBX,EBX ;|Zero-out the values of the registers
00401233 |. 33D2 XOR EDX,EDX ;
00401235 |. B3 15 MOV BL,15
00401237 |> 8A1431 /MOV DL,BYTE PTR DS:[ECX+ESI] ;/
0040123A |. 325431 01 |XOR DL,BYTE PTR DS:[ECX+ESI+1] ;|
0040123E |. 80C2 29 |ADD DL,29 ;|
00401241 |. 36:889429 00FF>|MOV BYTE PTR SS:[ECX+EBP-100],DL ;|The Serial Generation Algorithm
00401249 |. FEC3 |INC BL ;|(don't worry I'll explain it later)
0040124B |. 41 |INC ECX ;|
0040124C |. 80FB 25 |CMP BL,25 ;|
0040124F |.^75 E6 JNZ SHORT keygenme.00401237 ;
00401251 |. 36:C68429 00FF>MOV BYTE PTR SS:[ECX+EBP-100],0 ;add a 0 at the end of the serial, making it a valid string ;-)
0040125A |. 8DB5 00FFFFFF LEA ESI,DWORD PTR SS:[EBP-100] ;ESI=Address of the place where the fake serial begins(in memory)
00401260 |. F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ;compare our serial to the one generated just before, byte2byte
;when it encounters differrent bytes, it stops the comparing
;because the REPE instruction repeats executing a line of code while the zero flag is set
00401262 |. 803F 00 CMP BYTE PTR DS:[EDI],0 ;Check if the next byte of the correct serial is a 0
;That's a smart way to check if the 2 serials are identical because if they are not,
;the REPE comparing will stop at the position of the 2 differrent bytes and as a result
;the next byte won't be the trailing 0 ;-)
00401265 |. 75 05 JNZ SHORT keygenme.0040126C ;prepare the return values to decide which messagebox will be shown
00401267 |. 33C0 XOR EAX,EAX
00401269 |. 40 INC EAX
0040126A |. EB 02 JMP SHORT keygenme.0040126E
0040126C |> 33C0 XOR EAX,EAX
0040126E |> 5A POP EDX
0040126F |. 5B POP EBX
00401270 |. 59 POP ECX
00401271 |. 5F POP EDI
00401272 |. 5E POP ESI
00401273 |. C9 LEAVE
00401274 . C2 0800 RETN 8
to find out which is the correct serial for the name you entered, hit F9 then click 'Check' again and at 00401260 right click at 'ES:[EDI]=...' below the asm code and select 'Follow in Dump'.
Then, in the window below the place where you right-clicked under the header 'ASCII' there is the correct serial(it starts at the top left and ends at the first 0).
We found a suitable serial for our Username!!!
Now on to the KeyGenning!!!
Part 3:Writting the Keygen!!!
Hmm...as you can see, the serial generation algorithm is a loop that takes every character of our username and XORes it with next(00401237 and 0040123A).
Then, it adds 0x29 to the result of the XORing and saves that byte of data.
That byte of data is a character of the correct serial...
So...the serial is an array of characters each one (let's say n in position) created by XORing your name's n-th character with the (n+1)th and then adding 0x29 to it..
To conclude this tutorial, let me present to you the KeyGenning procedure in win32asm:
To generate the serial, you will need to put the username in the username variable and then use:
invoke GenerateSerial,addr username
However, in order for this keygenerator to be successful, you need to do some checks on the username first, as the crackme does(no numbers, etc...)
There is also one other problem:there are some usernames that will cause the serial to have characters that are not represented equally in each encoding(u may be using a differrent one from the crackme).This, results in some serials being rejected although they are correct...
In the zip file I include a simple keygenerator(with no checks on the username).
Another tutorial (my second one) has been completed!!!
Hope you learned something...