Sunday, July 09 2006 @ 04:28 PM CEST Contributed by: LucyE Views: 11397
Level : newbie
Cracking and finding the name to serial algorithm in Chainie1 Crackme
This is my first crackme tutorial: I wrote it to try and help other real newbies like me to better understand the simple basics of cracking. Although this is supposed to be a very simple crackme I found it quite hard to understand what was really going on and very nearly fell into a little trap of thinking I had found the name to serial algorithm too soon.
Well where do we begin? First I check the Chainie.exe with PeID. We see that this crackme is not packed and was created with Borland Delphi 6.0 7.0 so hopefully we wont have any nasty surprises like anti-debug or other tricks.
Ok lets have a look at our target; double click Chainie.exe and a dialog box asking for a name and a serial will appear.
Enter name LucyE and enter serial 47806 and press Check.
Bam a message box appears saying, Your name is too short
Press OK and close Chainie.exe. Then right click on Chainie.exe and open with Olly.
In Olly right click and select Search for all referenced text strings. You will see this:
Text strings referenced in Chainie: CODE
Address Disassembly Text string
0045012F ASCII "Unit1"
004501F5 PUSH Chainie.0045027C ASCII "Correct"
004501FA PUSH Chainie.00450284 ASCII "Good job you did it!!!"
00450213 PUSH Chainie.0045029C ASCII "WRONG!!!"
00450218 PUSH Chainie.004502A8 ASCII "Incorrect Serial try again...." (2)
0045022F PUSH 10 (Initial CPU selection)
00450231 PUSH Chainie.004502C8 ASCII "Oops...
00450236 PUSH Chainie.004502D0 ASCII "Your name is too short" (1)
I didnt want to guess how long may name should be so I decided to double click on (1) and see if I could fix this problem first and then come back and double click on (2) to see what I could see and learn from that.
After double clicking we land here at place marked (1)
0045022F > 6A 10 PUSH 10 ί---------------------------- ; Entry point to MessageBox function
(1) 00450236 68 D0024500 PUSH Chainie.004502D0 ; ASCII "Your name is too short" 0045023B . A1 D43B4500 MOV EAX, DWORD PTR DS:[453BD4]
00450240 . E8 EF58FEFF CALL Chainie.00435B34
00450245 . 50 PUSH EAX ; |hOwner = NULL
00450246 . E8 5562FBFF CALL ; MessageBoxA
0045024B > 33C0 XOR EAX, EAX
To find out where the check that called this function right click on the entry point at 0045022F and select Go to JLE from 0045017C and we land here:
00450179 83F8 05 CMP EAX, 5 ; is name length less than 6 letters?
0045017C 0F8E AD000000 JLE Chainie.0045022F If yes then Jump to Bad Name
There are probably many ways to fix this name check like NOP the JLE, but I like the idea of entering a name so I will patch this by changing the 5 to 1. This means that your name must have more than 2 letters to be valid. We do this by clicking on the location 00450179 pressing the Space bar, change the 5 to 1, then choose assemble followed by cancel. The code will now look like this:
00450179 83F8 01 CMP EAX, 1
0045017C 0F8E AD000000 JLE Chainie.0045022F
Now the name length check has been patched our next job is to find the correct serial for our name.
Looking at the code snippet below we see that at 004501F1 there is a check which if we fail we go to the Good job you did it!!! message. This tells me that there is a check for a valid serial in the Call on the line above that returns with a non-zero value if our serial is valid. Therefore, put a breakpoint (press F2) on the Call at 004501EC and Press F9 to run the crackme. Enter LucyE for the name and 47806 as the serial then Check to find out if the serial we entered is legitimate.
004501EC . E8 2B40FBFF CALL Chainie.0040421C ί----------we break here
Hey look at the memory dump (stack) what do you see?
0012F604 00E924E8 ASCII "48706" ; the serial we entered
0012F608 0012F968 Pointer to next SEH record
0012F60C 0045026E SE handler
0012F618 00428FD0 Chainie.00428FD0
0012F620 00E924FC ASCII "3443972" ; maybe a valid serial
0012F624 00E924E8 ASCII "48706" ; the serial we entered
0012F628 00E924D4 ASCII "LucyE"
0012F62C 00E924C0 ASCII "LucyE" ; the name we entered
0012F630 00E924AC ASCII "LucyE"
Lets be brave and remove our breakpoint then hit F9 to run Chainie.exe.
After clicking OK at the Incorrect serial try again message enter this number (3443972) as the serial and press check. BINGO! We cracked it!
Our next job is to find out how this programme calculates the serial for our name.
Press Alt-E to view the Executable Modules then right click on Chanie.exe and select view names. Scroll down the list a bit and double click on the LoadStringA API then press F2 to set a breakpoint on the line highlighted in Olly at 00450152. Run Chainie.exe and press check; we break in Olly at 00450152.
00450152 . 55 PUSH EBP ί----------------------- We Break Here
You might think that this is the end of the name to serial algorithm but its not! So we will now continue from where we stopped above by pressing F7 to trace into the Call at 004501E3 until we reach here:
00407B04 /$ 08C9 OR CL, CL if result is not zero
00407B06 | 75 17 JNZ SHORT Chainie.00407B1F then Jump
00407B08 | 09C0 OR EAX, EAX if result is not signed
00407B0A | 79 0E JNS SHORT Chainie.00407B1A then Jump
.If both above checks fail algorithm is completed in this section .
00407B0C | F7D8 NEG EAX makes value in EAX positive
00407B0E | E8 07000000 CALL Chainie.00407B1A
00407B13 | B0 2D MOV AL, 2D
00407B15 | 41 INC ECX
00407B16 | 4E DEC ESI
00407B17 | 8806 MOV BYTE PTR DS: [ESI], AL ; adds value in AL to our serial
00407B19 | C3 RETN
.. Second part of algorithm
00407B1A |$ B9 0A000000 MOV ECX,0A ; Put the divisor x0A (10) in ECX
00407B1F |> 52 PUSH EDX
00407B20 | 56 PUSH ESI
00407B21 |> 31D2 /XOR EDX,EDX ; Zero EDX
00407B23 | F7F1 |DIV ECX ; Divide EAX by 0A Result in EAX remainder in EDX
00407B25 | 4E |DEC ESI ; Make room for next number of correct Serial
00407B26 | 80C2 30 |ADD DL, 30 ; Add 30 to low byte in EDX
00407B29 | 80FA 3A |CMP DL, 3A ; if DL is less than 3A
00407B2C | 72 03 |JB SHORT Chainie.00407B31 ; then Jump
00407B2E | 80C2 07 |ADD DL, 7
00407B31 |> 8816 |MOV BYTE PTR DS:[ESI],DL ; the correct serial is built here
00407B33 | 09C0 |OR EAX, EAX
00407B35 |^ 75 EA JNZ SHORT Chainie.00407B21 ; Get next number until EAX is zero
00407B37 | 59 POP ECX ; Chainie.00407B60
00407B38 | 5A POP EDX ; Chainie.00407B60
00407B39 | 29F1 SUB ECX, ESI ; the length of the correct serial
00407B3B | 29CA SUB EDX, ECX ; if EDX is bigger than ECX
00407B3D | 76 10 JBE SHORT Chainie.00407B4F ; then Jump
00407B3F | 01D1 ADD ECX, EDX
00407B41 | B0 30 MOV AL, 30
00407B43 | 29D6 SUB ESI, EDX ; Length of serial
00407B45 | EB 03 JMP SHORT Chainie.00407B4A
00407B47 |> 880432 /MOV BYTE PTR DS:[EDX+ESI],AL
00407B4A > 4A DEC EDX
00407B4B |^ 75 FA JNZ SHORT Chainie.00407B47 ; loop until EDX is zero
00407B4D | 8806 MOV BYTE PTR DS:[ESI],AL ; add AL i.e. 30 to our serial
00407B4F > C3 RETN
STOP pressing F7 when you reach RETN at 0407BF4 and note that ESI=3443972
Do you remember the number calculated from our name in the first part of the algorithm and do you recall where it was stored? Yes EAX = 348D04. Well to calculate the real valid serial this number is divided step by step by 0A at location 00407B23 until EAX is zero.
At each step the remainder of this integer division, if it is less than 0A (i.e. a single digit), is stored in ESI.
If the remainder is greater than 0A then 07 is added to DL before it is stored as a single digit in ESI.
If you recollect the serial for LucyE, was 344392. So in my case the first remainder was 2, the second 9, the third 3 and so on.
Press F8 seven times and look at the stack, at the bottom right of your screen you will see what we saw earlier, the name we entered, the serial we entered and the correct serial computed from our name. Also note that EDX = 3443972
So what have we learned?
1. How to check if a target is packed
2. How to patch a name length check
4 How to fish for a valid serial
5. How to find and understand the code that converts our name into a valid serial
6. Go slowly and keep our eye on what is happening with the registers and what is showing in the memory dump.
Although all the information to make a keygen is revealed I am not advanced enough to be able to make one but hope that someone will take the time and trouble to make a tutorial on how this can be done.
Well I have finished and it has taken me nearly 2 days to crack Chainie1 and write this little tutorial which I hope you like and will find helpful.