Keygenning diablo2oo2's crackme 5
Overview
The following tutorial will document how to unpack and program a keygenerator for diablo2oo2’s fifth crackme.
Experience in x86 assembly is assumed.
The crackme can be found here.
Unpacking the crackme.
Load the crackme into x32dbg. Then, navigate to the “Memory Map” tab:
The executable has 2 PE sections, each with the name “d2k2”. Place a one-shot on-execution breakpoint on the upper “d2k2” section, with the RWC permissions.
Run the crackme until it breaks on the breakpoint set.
Then, click on the “Scylla” icon.
Click on the IAT Autosearch, then click “Get Imports.
Click “Dump” to save a unpacked copy of the executable. Then, click “Fix Dump” to rebuild the executable into a working one. This will be the one to use when debugging. Unload this executable from x32dbg.
Reverse engineering the crackme.
Load up the freshly depacked executable in x32dbg again. The debugger should load the executable at the following code at the executable’s real entrypoint, since the packer’s loader is now removed.
Run the crackme in x32dbg.
From here, it is needed to place any possible breakpoints on places which the user enters any data, say for instance username and serial key.
Stepping through our entered serial number and username, it becomes immediately apparent that the length of the serial key is checked and tested against the length entered. In this case our entered serial, which is 5 characters in length does not match the limit, which is 0x20 characters. In this case the check will fail and jump over a vast length of code to drop at the following….
Which is precisely where we don’t want to be. We want to pass the check, so our serial key must be exactly 0x20 (in hex) characters in length
So we rerun the check in the debugger, only this time trying a serial key which is precisely 32 characters (0x20 in hex) in length. Doing so gets us to the following:
This check checks the username for the length of characters. It must be greater than 4 characters in length and less than 32 characters (20 in hex).
From here if the name passes those checks it moves to the first portion of the serial algorithm. For the sake of brevity the following screen illustrates how this portion of the serial check works:
Once that routine is complete, the check moves to a much longer and more complex loop….
Once again, the above picture is used for brevity. One very worthy point of note is the special call which is called multiple times in the main serial loop:
This call is full of binary math, constants and very lengthy and outputs a 128bit length bytestream. One thing of note is that the constants are based off the MD5 hash algorithm, same with some of the logic seems derived from it, however there has been many modifications such as “round” constants being tweaked.
Once the subcall has been run, it exits back to the main logic of the serial routine.
The rest of the hashing loop is documented here.
Once the loop is complete, the next phase is undertaken.
The formatting of the hash output is then done and concatenated into one large 32 character string.
The final string is then checked one final time, one character at a time using some byte level arithmetic and division. This is where the actual serial check takes place. If all the per-character checks pass, then the crackme is complete.
Writing the keygen.
Writing the keygen involved some debugging to check that the operations are perfect, byte per byte. The 128bit hash function was not reversed, however it was code spliced from the original crackme using fearless’ CopyToAsm plugin for x64dbg.