0040138E CALL <JMP.&KERNEL32.lstrlenA> ; lstrlenA
00401393 PUSH EBX
00401394 XOR EBX,EBX
00401396 MOV ECX,EAX
00401398 MOV ESI,DWORD PTR [EBP+8]
0040139B PUSH ECX
0040139C XOR EAX,EAX
0040139E LODS BYTE PTR [ESI]
0040139F SUB EAX,30
004013A2 DEC ECX
004013A3 JE SHORT Key4.004013AA
004013A5 IMUL EAX,EAX,0A
004013A8 LOOPD SHORT Key4.004013A5
004013AA ADD EBX,EAX
004013AC POP ECX
004013AD LOOPD SHORT Key4.0040139B
004013AF MOV EAX,EBX
004013B1 POP EBX
004013B2 LEAVE
004013B3 RET 4
Listing 11.2 (continued)
From looking at the code, it is evident that there are two code areas that
appear to contain the key-generation algorithm. The first is the
Key4.0040130Bsection in Listing 11.1, and the second is the entire function
from Listing 11.2. The part from Listing 11.1 generates the value in ESI, and
the function from Listing 11.2 returns a value into EAX. The two values are
compared and must be equal for the program to report success (this is the
comparison that we patched earlier).
Let’s start by determining the input data required by the snippet at
Key4.0040130B. This code starts out with ECXcontaining the length of the
first input string (the one from the top text box), with the address to that string
(40303F), and with the unknown, hard-coded address 40351F. The first
thing to notice is that the sequence doesn’t actually go over each character in
the string. Instead, it takes the first four characters and treats them as a single
double-word. In order to move this code into your own keygen, you have to
figure out what is stored in 40351F. First of all, you can see that the address is
always added to EAXbefore it is referenced. In the initial iteration EAXequals
1, so the actual address that is accessed is 403520. In the following iterations
EAXis set to 4, so you’re now looking at 403524. From dumping 403520 in
OllyDbg, you can see that this address contains the following data:
00403520 25 40 24 65 72 77 72 23 %@$erwr#
Breaking Protections 367