[A]dvanced Keygenme by sd3332214 minutes read
CrackMes are a great way to improve reverse engineering skills. In these series, I’ll try to analyze and solve some medium level CrackMes. Solving similar problems are very helpful for malware analysts.
Today’s CrackMe is
[A]dvanced Keygenme by sd333221
Date of Release:
I encourage you to do it yourself before reading the solution.
Note: Variables are named by me after analysis.
PeStudio, now we know the author (
haxx0r) and fact that the executable uses
Thread Local Storage.
Let’s open in
tls-callback it calls
GetTickCount and computes value of
HIGH_pp from the result:
GetRand_CPUID_getTick it gets CPU vendor ID using
cpuid (EAX=0) , and uses
HIGH_pp to compute new value:
After that, it converts the result to
modify_str contains two parts
mix_two_list it builds a list of bytes(I renamed variable as
0xFF and modifies it using another list of
Python implementation of
modify_cpuid_time it uses the value converted from integer to string and modifies this value using
Python implementation of
modify_str is used to encrypt/decrypt computed value before using it.
At the end of
tls-callback, it uses two ways to detect debuggers, named as
chckDbgr uses “guard” pages to detect debuggers and
CreateFile() functions, both tricks are explained in
The Ultimate Anti-Reversing Reference by Peter Ferrie (must read!)
The CrackMe uses custom base64 alphabet:
/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA but if it detects a debugger it calls
ifDebugg__ function, which reverses the alphabet:
WinMain it sets the result of our old friend
GetRand_CPUID_getTick as username, that’s exactly same value what we have in encrypted form.
CheckSerial function (we are trying to write keygen, don’t patch it)
CheckSerial function it decrypts the value (Yeah, this is from
tls-callback), decrypted version of text is same as
username, both are from
GetRand_CPUID_getTick, after decryption it encodes result with
base64 but uses custom alphabet, encrypts result once again and encodes result as well, final result is saved in
SerialComp gets our input as a parameter and returns value which should be same as in
SerialComp is some kind of decoding function:
Python REVERSE implementation of
What we know:
- It gets value from
GetTickCount- same as username
- Encodes the value with
base64using custom alphabet
- Encrypts decoded value
- Encodes encrypted value
Main parts of writing keygen are implementing reverse of
SerialComp and encryption function (I’m using the built-in support of
We have everything we need to write keygen:
Any feedback appreciated.