Cruehead CrackMe v3.0 - Tutorial

Cruehead CrackMe v3.0 - Local Download (3k).

Welcome to what would seem to be the final Cruehead CrackMe. This CrackMe presents a different challenge to the previous versions in that our task is to create a working keyfile for the program. The first thing you should find out is that the name of our missing file is crackme3.key, use a file monitoring tool or just disassemble if you want to verify this.

So lets create an empty crackme3.key file. Now we need to use Softice to intercept the reading of the key file, you can use ReadFile however I strongly recommend CreateFileA which is used unsurprisingly for creating and opening files (check the disassembly also). So lets >bpx CreateFileA and launch the CrackMe. You should break on this code:

:00401032 CMP EAX,-01 <-- If EAX is returned -1 then the file doesn't exist.
:00401035 JNZ 00401043 <-- Jump_crackme3.key_exists.
:00401043 MOV [004020F5],EAX
:00401048 MOV EAX,00000012 <-- Number of bytes to read from file.
:0040104D MOV EBX,00402008
:00401052 PUSH 00 <-- Now the program is pushing all the parameters for ReadFile.
:00401054 PUSH 004021A0
:00401059 PUSH EAX
:0040105A PUSH EBX
:0040105B PUSH DWORD PTR [004020F5]
:00401061 CALL KERNEL32!ReadFile <-- API call to read file.
:00401066 CMP DWORD PTR [004021A0],12 <-- Compare for 12h (18 decimal).
:0040106D JNZ 00401037 <-- Jump_crackme3.key_was_wrong_length.

Now lets modify our key file so that it is 18 bytes in length, it will now pass the 2 validity checks above. After the length check you should proceed to trace CALL 00401311:

:00401315 MOV ESI,[ESP+04] <-- ESI holds crackme3.key contents.
:00401319 MOV BL,41 <-- BX-low moved to 41h.
:0040131B MOV AL,[ESI] <-- AX-low moved to byte from crackme3.key.
:0040131D XOR AL,BL <-- XOR.
:0040131F MOV [ESI], AL <-- Save XOR result.
:00401321 INC ESI <-- Increment ESI to next byte.
:00401322 INC BL <-- Increment BL from 41h to 42h for next byte.
:00401324 ADD DWORD PTR [004020F9], EAX <-- checksum.
:0040132A CMP AL,00 <-- Finished decrypting.
:0040132C JZ 00401335 <-- Jump_finished_decrypt.
:0040132E INC CL <-- Increment CX-low.
:00401330 CMP BL,4F <-- Is BX-low 4F. (i.e. 4F-41 = 14).
:00401333 JNZ 0040131B <-- Loop_again_if_not.
:00401335 MOV [00402149],ECX

After this simple decryption you'll return from the function at this code:

:00401079 XOR DWORD PTR [004020F9],12345678 <-- Sum of decrypted bytes XORed with 12345678.
:0040108B CALL 0040133C <-- Last 4 bytes of keyfile.
:00401093 CMP EAX, [004020F9] <-- Compare.
:00401099 SETE AL <-- Set AX-low to 1 if the compare was good.
:0040109C PUSH EAX
:0040109D TEST AL,AL <-- Test AX=low for 0.
:0040109F JZ 00401037 <-- No_jump_and_we've_cracked_it.

Now that we have examined the code lets start to construct our valid keyfile, in this case for the name CrackZ. We know that the first 14 bytes determine the name and that it works on a simple character by character XOR starting with 41h. So for CrackZ our keyfile must look like the following:

CrackZ = 43 72 65 63 6B 5A
XOR with: 41 42 43 44 45 46
Result: 02 30 22 27 2E 1C <-- Use Softice if you want to quickly work out this result.

Example

72h XOR 42h = 30h

0111 0010 = 72h (114 decimal)
0100 0010 = 42h (66 decimal)
-----------
0011 0000 = 30h (48 decimal)

We now need to terminate our name by ensuring that the next character produces an XOR result of zero, so our next value must be 47 i.e. XOR 47,47=0, the remaining 7 bytes can be left blank as they will not be checked (If you want to do this easily I recommend using Hiew in HEX mode). The last 4 digits however must be the sum of the decrypted values XOR-ed with 12345678.

So the sum of our decrypt = 23E (Tip: Obtain this value from DS:004020F9 from the Softice register window).

Now we need to XOR this result 23E with 12345678.

12345678
xxxxx23E
----------
12345446

So the last 4 bytes of the keyfile for me are 46 54 34 12.

CrackMe 3.0 Registered Picture

cruekey3.zip


© 1998 CrackZ. 10th June 1998.