In continuation of my previous analysis of
“Reverse engineering test crackme from Kaspersky Lab” . Found on the Internet
one more option crackme from Kaspersky Lab. The author applied brute force to solve it. This rough "cracker" method does not suit us here. We are interested in the analysis of the license key verification algorithm. You can, of course, make a huge sample of the right keys and try to find a pattern, but it seems to me that it is better to revise a little. So, let's begin. The crackme has the same beginning as in the previous article: the key must contain 19 characters, every 5th character must be "-" and all characters must be numbers. We turn to the interesting. We use 1234-5678-9012-3456 as a trial key.
In the selected section of the code contains the algorithm for checking key blocks. We analyze it in detail.
000000014000106E | movsx eax,byte ptr ds:[r9] 0000000140001072 | add al,byte ptr ds:[r9+1] 0000000140001076 | add al,byte ptr ds:[r9+2] 000000014000107A | movsx ecx,byte ptr ds:[r9+3] 000000014000107F | add eax,ecx 0000000140001081 | add eax,ecx 0000000140001083 | add eax,ecx
This part of the code performs the operation of summing hexadecimal codes of the block symbols in this order - the first three characters of the key block (or rather their hexadecimal codes) are added and the code of the last block symbol is added to this sum three times (for example, if our first key block is 1234, then this amount will look like 31h + 32h + 33h + 34h + 34h + 34h = 132h) and then this number is entered into the battery (RAX). Next comes the key line of code:
')
0000000140001091 | lea ecx,dword ptr ds:[rcx+rax-150]
This line records in ECX the result of the following operation: RCX stores the code of the last character of the block and adds the value stored in RAX to this code, and as we remember, the result of the operation from the previous step is stored there. After that, 150h is deducted from this amount. In our example, it will look like this: 34h + 132h-150h = 16h. Next, this value is pushed onto the stack with the following line:
0000000140001098 | mov dword ptr ds:[rbx-4],ecx
And the program conducts such an operation with each key block, simultaneously summing up the results entered into the data stack in the r10 register. After all the results are pushed onto the stack and their sum is placed on register r10, the program will divide the contents of register r10 by 4 (shr r10d, 2) and check for equality each entered value on the stack with the result obtained from the division. If the values are equal, then the check is performed further, if not, the program will say that the key is incorrect. According to the results of this analysis, we have the following - the
results of calculations, according to the algorithm at 140001091, should be equal for each block . If we try the key 1234-1234-1234-1234, then the check will pass this step and the last stage of the check will begin:
This section of code controls that the location of the characters in each subsequent key block does not coincide with the location of the symbols in the previous block. Generate the key, according to the findings. Let's try 9870-5781-1872-7503
Fine!