This is the first tutorial I am posting. I will be using OllyDbg. I am not sure if I should use screen shots. I am not that good with OllyDbg, and don't know if I will get more confused trying to explain how to get around in OllyDbg. I was thinking about finding the algo and just showing how to write a keygen. It would be more benificial if I can find a way to explain how I found it with Olly. So hang in there:
crackme#1.exe by microplant
The first thing to we want to do is find out more about the crackme. Run the program and we get this:
We need to keep our eyes out for anything that can be useful. Looks like it is asking for a username and serial. There
is a register button. Lets put the username as: cracked , serial: 47806 . In a tutorial I read, can't remember author,
he stated that 47806 in decimal is BABE in hex. He said he could find a BABE in code any day. Now lets hit the register
button. We get:
We always need to pay attention to the message we get when our serial fails. We can use it to find a starting point when
searching for the algorithm in one of our tools. Now that we have some info about the crackme, open it up in OllyDbg.
There are several windows that can be opened in Olly. I will only be using three for this tutorial. 1) CPU Window (View
-> CPU or Alt+C). 2) Executable Modules (View -> Executable Modules or Alt+E). 3) Command line (Plugins ->
Command line or Alt+F1). The newer versions of OllyDbg come with the command line plugin installed. If you don't have it, you
can download it at the OllyDbg homepage. Here is a screen shot of the windows.
1) CPU Window. This is where we will be stepping through our code.
1B) Displays data as we step through code.
1C) Dumped data of our exe. You can see the badboy message we got here.
1D) Registers of CPU. The Zero flag is also useful to us.
1E) Stack and the data that is pushed to it.
2) Executable Window. Right now only interested in crackme#1.exe
3) Command line window. Type help for list of commands.
Earlier when we ran the program we saw that it has input boxes for us to fill in. When we hit the register button it
checks to see if we entered the correct data. Most of the time when a message box asks us for data it uses an API call.
This is good for us because we can set a breakpoint on these calls and be able to jump to a closer location of the algorithm.
After it gets the data from the input box it has to compare it to the correct serial. When we jump to the code that captures
our inputted data we know the comparing algo should be somewhere close. The most popular call we can break on is:
GetWindowTextA and the next is GetDlgItemTextA. Both of these are used by a program to get data inputted by the user. I
always check for GetWindowTextA first. So lets try this:
In the Executable Modules window you see the path to our crackme#1.exe. You can right click this path and choose (View Names
or hit Ctrl+N). A new window will pop up:
When this window is highlighted we can type the name of the API Call we are looking for. Start typing GetWindowTextA. As
you type the window will scroll down to the call we are looking for. We find that GetWindowTextA is used in this crackme.
So lets right click that name and choose (Toggle break point on import). Now when we hit register the debugger should stop
in the location of code that is receiving our data. Go ahead and close the View Names window. (We can rewind/restart our
program any time by pressing or Ctrl+F2. We must reset our breakpoint each time we restart!)
Now that we have a break point set we can run the program inside OllyDbg. We can do this by pressing
or F9. The crackme should now popup. It is being run inside Olly. It may popup behind Olly so keep an eye out on the task
bar. Input the username: cracked, serial: 47806 and hit register. The breakpoint shows up in black and red on the top
left of the CPU window. You can also see a call to GetWindowTextA on the bottom right in the stack area.
This is where my explanation may get a little ugly. I don't know all the details of what is going on. Now that we
should be at a close point in the code to where the program checks our username and serial. We will step through the code.
I will be using step over or F8. The plan is to hit F8 until we find something to do with our
username or serial. I pressed F8 27 times and found "cracked" inside the EDI Register. It has also been popped to the
stack.
We should be getting close now. We found the username we entered. Now we keep going and look for the serial we entered.
Before we see our serial we should hit another breakpoint. The first call to GetWindowTextA was the username. If we hit
F8 14 more times (41 in total) we hit the second breakpoint. You will know because the top left of the CPU window will have
77D6213C The black and red let us no it is a breakpoint. From this
breakpoint we hit F8 27 more times (68 in total). We can see our serial is in ??????? Now we need to pay attention and look
for anything that is going to hint towards our serial and its algorithm.
Now we need to press F8 13 more times (81 in total). We see cracked is in EAX. F8 one more time (82 in total) and 7 is in EAX. The program
just calculated how many characters are in our username. F8 one more time (83 in total) and 7 is moved(copied) from EAX to
EBX. Lets look at the line we are sitting on.
004011E6 . 83FB 05 CMP EBX,5 004011E9 . 7D 14 JGE SHORT crackme#.004011FF 004011EB . 68 34404000 PUSH crackme#.00404034 ; /Arg2 = 00404034 ASCII "registration failed - try again :)" 004011F0 . 68 57404000 PUSH crackme#.00404057 ; |Arg1 = 00404057 ASCII "crackme #1" 004011F5 . E8 17090000 CALL crackme#.00401B11 ; \crackme#.00401B11
It is going to compare 7 (the length of our username) which is inside the EBX register with 5. If the username is less than five it will give us the bad boy message "registration failed - try again :)". Our username is 7 characters so we will jump past this bad boy message.
We should still be on line:
Hit F8 30 more times (113 in total) and we see cracked is placed in EAX. Hit F8 4 more times (117 in total) and notice 63 is placed in
EAX. If you know your ASCII letters and numbers in hex, decimal, and binary it will benifit you. If not you can use a chart like this
one. Doing so you will find out that the hex for the
letter c is 63.
Hit F8 2 more times (119 in total) and 99 is placed into EAX. Using the same chart you can determine that 99 is the decimal
equivalent to c. Could our serial be the decimal representation of our username? Lets keep going. If this is where the algo is
being determined then we should be jumping back to the beginning of the algo pretty soon. It has to loop through each letter of the
username.
We hit F8 5 more times (124 in total) and we will end up on this line.
004012E3 .^EB 8A JMP SHORT crackme#.0040126F
This is a jump. Actually this is the jump that will take us back to the beginning of the algo that determines our serial.
We may not know this the first time we go through. So hit F8 1 more time (125 in total) and we will have jumped to the beginning
of the algo.
Hit F8 13 more times (138 int total) and cracked is placed in EAX. Hit F8 4 more times (142 in total) and 72 is placed in
EAX. 72 is hex for r (ascii). F8 2 more times (144 in total) and 72 is converted to the decimal 114 which is placed in EAX.
F8 3 more times (147 in total) and the decimal version of the first two letter of our username will be joined together and
placed in EDX = 99114.
F8 2 more times (149 in total) and we are on this line again.
004012E3 .^EB 8A JMP SHORT crackme#.0040126F
It will take us to the front of the algo once again. Take a look at where it is jumping? 0040126F ! Hit F8 1 more time
(150 in total). We land at the front of the algo which is here:
0040126F > A1 E4484000 MOV EAX,DWORD PTR DS:[4048E4]
Look at the first part of the code: 0040126F . See how we jumped to this location? So now lets go through the full length of
the username.
F8 13 times (163 in total) EAX = cracked
F8 4 times (167 in total) EAX = 61. 61 is hex for a.
F8 2 times (169) EAX = 97. 97 decimal for a
F8 3 times (172) EDX = 9911497
F8 3 times (175) we are back at beginning of algo.
F8 13 times (188) EAX = cracked
F8 4 times (192) EAX = 63
F8 2 times (194) EAX = 99
F8 3 times (197) EDX = 991149799 (c=99,r=114,a=97,c=99) 1st,2nd,3rd,4th charcters of username
F8 3 times (200) back at beginning of algo
0040126F > A1 E4484000 MOV EAX,DWORD PTR DS:[4048E4]
F8 13 times (213) EAX = cracked
F8 4 times (217) EAX = 6B
F8 2 times (219) EAX = 107
F8 3 times (222) EDX = 991149799107
F8 3 times (225) beginning of algo
F8 13 times (238) EAX = cracked
F8 4 times (242) EAX = 65
F8 2 times (244) EAX = 101
F8 3 times (247) EDX = 991149799101
F8 3 times (250) beginning of algo
F8 13 times (263) EAX = cracked
F8 4 times (267) EAX = 64
F8 2 times (269) EAX = 100
F8 3 times (272) EDX = 991149799107101100
F8 3 times (275) beginning of algo
We have gone through all the characters of the username. The code is going to jump out of the algo loop we were just in. We
will keep stepping through code to see if anything else happens.
F8 2 times (277) and we land on this line:
00401279 . 3B05 D4484000 CMP EAX,DWORD PTR DS:[4048D4]
This line is going to compare the length of our username = 7 to the next inc of this loop = 8. Eight is higher so the zero
flag is set. F8 1 more time (278) and we come to this line:
0040127F . 7C 64 JL SHORT crackme#.004012E5
This jump will be taken since the zero flag is set. We will go to 4012E5.
F8 1 more time (279) and we jump out of algo loop to:
004012E5 > FF35 C0404000 PUSH DWORD PTR DS:[4040C0]
If we look in the Display window under where we step through. (1B in the description of Olly windows diagram!)
You will see:
DS:[004040C0]=00890048, (ASCII "991149799107101100")
Jump from 0040127F
This shows us that the ascii characters 991149799107101100 are located at DS:[004040C0] we can verify this by typing:
d ds:[004040c0]
in the command line prompt and hitting enter.
This will be displayed in the hex dump area. (1C of the Olly pic up top).
You can use the command line to view other areas. Remember our registers in the top right? EAX, ECX, etc.
Right now EDX = 008721C0. If you want to know what that address contains you can type this into the command line and hit enter:
d edx
(d = display) The result is:
008721C0 AB AB AB AB AB AB AB AB «««««««« 008721C8 00 00 00 00 00 00 00 00 ........ 008721D0 04 00 04 00 55 07 1A 00 ..U. 008721D8 34 37 38 30 36 00 AB AB 47806.«« 008721E0 AB AB AB AB AB AB EE FE ««««««îþ 008721E8 00 00 00 00 00 00 00 00 ........ 008721F0 06 00 04 00 51 07 1D 00 ..Q. 008721F8 39 39 31 31 34 39 37 39 99114979 00872200 39 31 30 37 31 30 31 31 91071011 00872208 30 30 00 AB AB AB AB AB 00.««««« 00872210 AB AB AB FE EE FE EE FE «««þîþîþ 00872218 00 00 00 00 00 00 00 00 ........ 00872220 BC 01 06 00 EE 14 EE 00 ¼.îî. 00872228 60 FA 89 00 78 01 87 00 `ú.x. 00872230 EE FE EE FE EE FE EE FE îþîþîþîþ 00872238 EE FE EE FE EE FE EE FE îþîþîþîþ 00872240 EE FE EE FE EE FE EE FE îþîþîþîþ
Amongst the jibberish we can find the serial we entered = 47806 as well as the one our crackme has generated so far = 991149799107101100
Lets look at current line we are on:
FF35 C0404000 This is the hex equivalent of:
PUSH DWORD PTR DS:[4040C0] which is the ASM or mnemonic/opcode (I think).
PUSH puts something on the stack. It is going to push DS:[4040C0] onto the stack. We already know our generated serial is
in DS:[4040C0] because we used this command in the command line just a second ago:
d DS:[4040c0]
F8 1 time (281) and F is pushed to pushed to stack. This will be used as a count down from 15. Hit F8 2 times (283) EAX = 008721F8 ASCII "991149799107101100"
We are now on this line.
This line is going to call 0040158D. We could use F7 to step into this call and see what is going on. I will leave this for you
to explore as this tutorial is already getting long. We will still be able to see what is happening without stepping into this call
. This crackme is for beginners so lets hope a brain will keep us from having to step through each call. With more complicated algos
you can be sure you will need to F7.
In short this call will keep the first 15 digits of the generated serial. Using the F that was pushed onto the stack earlier,
as a count down to zero.
F8 1 more time (284) and EAX = 991149799107101 . Only the first 15 characters are left.
F8 7 times (291) and this is pushed to stack:
0012FFA4 00890048 ASCII "991149799107101"
F8 1 time (292) 5 is pushed to stack.
F8 2 times (294) and EAX = our 15 digit serial
Once again we could F7 into this call to dig around, we won't.
F8 1 more time (295) and EAX = 99114 . It took the first 5 characters using the 5 we pushed to the stack earlier.
This call will add an - at the end after the first five characters of the username.
F8 1 more (297) and notice this is pushed to the stack.:
0012FFA4 00890048 ASCII "99114-"
Instead of trying to keep explaining all the F8s. Just keep stepping through and pay attention to what is going on inside Olly.
Watch closely EAX and the Display window underneath where we step. The 15 digit serial is going to be split with "-" .
Pay attention and hit F8 32 times (329). Look at our registers
ECX 008721D8 ASCII "47806"
EDX 00872220 ASCII "99114-97991-07101"
004013D2 . E8 31050000 CALL crackme#.00401908
This is going to compare the first character of both serials. So hit F8 1 time (330).
JNZ SHORT crackme#.004013EA
Will take us to "registration successfull - look out for a harder target now :)" if the zFlag is not zero.
If it is zero it will take us to "registration failed - try again :)"
Look at the zFlag and we see it is set to 1. Which means the zFlag is set. Which means it is zero. So hit
F8 1 more time (331) and you will see that we went to the badBoy message. Hit F8 3 or 4 more times and we get
Keep in mind that the message may popup behind Olly. So you may have to choose it on the taskbar or use Alt+Tab.
We could use an ascii to decimal chart as our keygen. Instead lets write one. We know we have to take the username, with
more than five characters and convert the ascii characters to decimal. We only need the first 15 decimal characters and
need seperate them five at a time with -. We also know if we use "cracked" as the username we should get "99114-97991-07101"
as our serial. Feel free to use any language you wish.
Rem Project: crackme_microplant Rem Created: 12/27/2005 9:24:44 PM Rem ***** Main Source File ***** _start: cls serial$ = "" fullSerial$ = "" input "Name: ", name$ numChars = len(name$) if numChars <= 5 then print "WARNING: need more than 5 characters in name!" dim serial$(numChars) for i = 1 to numChars serial$(i) = str$(asc(mid$(name$, i))) fullSerial$ = fullSerial$ + serial$(i) next i leftSerial$ = left$(fullSerial$, 5) midSerialPrep$ = left$(fullSerial$ , 10) midSerial$ = right$(midSerialPrep$, 5) rightSerialPrep$ = left$(fullSerial$, 15) rightSerial$ = right$(rightSerialPrep$, 5) finalSerial$ = leftSerial$ + "-" + midSerial$ + "-" + rightSerial$ print "Password: ", finalSerial$ print repeat input "Press r for new serial or escape to cancel ", redo$ if redo$ = "r" then goto _start until escapekey()
I wrote this code a while ago and did not comment it. I have reformatted and don't have darkBasic installed on this computer any more. I don't want to add comments in because I can't test the compiled version. I also want to provide a openSource version of all the keygens, so here is a php version. I will comment this so you should be able to figure out what is going on in the darkBasic version also.
php version:<html> <body> <form method="POST" action="crackme1_microplant_keygen.php"> <input type="text" name="username"> <input type="submit" value="generate"> </form> </body> </html> <?php //grab variables posted from form $username = $_POST['username']; //grabs username posted from form $usernameLength = strlen($username); //gets length of username for ($i=0; $i<$usernameLength; $i++){ //loop for each character in username $uNameToDecimal .= ord($username{$i}); //replace each letter with two digit serial and concat var } $firstFiveSerial = substr($uNameToDecimal, 0, 5) . "-"; $secondFiveSerial = substr($uNameToDecimal, 5, 5) . "-"; $thirdFiveSerial = substr($uNameToDecimal, 10, 5); $serial = $firstFiveSerial . $secondFiveSerial . $thirdFiveSerial; echo $serial; ?>
So now that we have a working keygen, lets try another username. Let's try our generated serial as the username.
username: 99114-97991-07101
serial: 57574-94952-45575
running crackme#1.exe we find that this serail works also. Test out different names and see if they work? Here is another.
username: B!z@1r3
serial: 66331-22644-91145
This is what we want to see!
It's always a good idea to take a look at the readme that comes with alot of crackmes. Among other things you will find the rules for the crackme, author's name, difficulty level, etc.
//////////////////////////////////////////////// // crackme #1 - ultra-easy for real beginners // //////////////////////////////////////////////// hi and welcome to my first crackme for crackmes.de this one is dedicated to the real beginners, and can be solved in a few minutes by average crackers (even with the time to code a keygen !) i tried to make it as easy as possible to let beginners get the "high" to finaly solve a crackme and to understand how the serial is beeing generated. there is just one rule: #1 only keygens allowed ! you will see why i only accept keygens and no name/key combos :D but now - have phun microplant |