This is a really easy crackme for Windows which I solved in no more than 5 minutes. I have chosen this one to make a simple tutorial for those who are starting with Reverse Engineering so here we go.

You can see the original crackme page here.

The rules from the author are:

1. NO PATCHING
2. Find Serial
3. Write Keygen
4. 😉 Enjoy

Let's execute the program and type some name/serial to see what's going on:

cme2-1

Okay, we can see the 'Bad Boy' message so let's open the exe file with IDA and look for that string. Once found we can get all its references by pressing Ctrl+X and see where in the code it is being used.

CME2-2As you can see in the flow chart, there is a loop making some calculations and after that, the bad/good boy decission is taken. We could patch the jump so that we always get the Good Boy but the first rule was 'no patching' so we have to find out how the program works to write a keygen. So let's focus in the inputs of the loop and the loop itself. As you can see below there are some calls to GetDlgItemTextA function which will get the strings from the DialogBox with the name / serial we have entered.

mov     esi, ds:GetDlgItemTextA
push    [ebp+hMem]      ; lpString
push    3E8h            ; nIDDlgItem
push    [ebp+hDlg]      ; hDlg
call    esi ; GetDlgItemTextA		<- Get the Name into hMem
push    [ebp+nMaxCount] ; nMaxCount
push    [ebp+arg_C]     ; lpString
push    edi             ; nIDDlgItem
push    [ebp+hDlg]      ; hDlg
call    esi ; GetDlgItemTextA		<- Get the serial into arg_C

Once the program has loaded our strings it's going to make some calculations inside a loop:

; arg_4 holds the 0x1908 value
; ebx contains the length of our name
loc_4010CC:
mov     ecx, [ebp+hMem]
mov     edx, [ebp+arg_4]
add     edx, ebx			; edx+= name_length
movsx   ecx, byte ptr [eax+ecx]		; ecx = name[i]
imul    ecx, edx			; ecx = ecx * edx;
inc     eax				; i++;
mov     [ebp+arg_4], ecx
cmp     eax, ebx			; i == name_length?
jl      short loc_4010CC		; no -> loop

When this simple algorithm's finished it's got its output at arg_4 variable. Let's see the next piece of code to see what our program does with it:

push    [ebp+arg_C]     ; char *
call    _atoi
pop     ecx				; eax = atoi(input_serial)
mov     ecx, [ebp+arg_4]		; get our computed value
push    0               ; uType
xor     ecx, 0A9F9FAh			; value ^= 0xA9F9FA;
cmp     ecx, eax			; do they match?
jnz     short BadBoy			; no -> bad boy
push    offset aGoodBoy ; "Good Boy!"
push    offset aTerimaKasihKer ; "Terima kasih kerana mencuba"
jmp     short loc_401111

Simple. The computed value is XOR'ed with 0xA9F9FA and then it is compared with the atoi() of the serial. If both values match then we get the good boy. Putting this all together we can now write a valid keygen for this program. Here it is the C source code of the simple keygen I wrote:

int main(int argc, char **argv)
{
	int namelength, i, serial=0x1908;
	char *name = argv[1];

	if(argc!=2)
	{
		printf("Usage: %s n",argv[0]);
		exit(1);
	}

	namelength=strlen(name);
	if(namelength < 5)
	{
		printf("Name must be at least 5 characters longn");
		exit(1);
	}

	for(i=0;i<namelength;i++)
	{
		serial+=namelength;
		serial*=name[i];
	}
	serial^=0xA9F9FA;
	printf("Serial: %dn",serial);
	return 1;
}


daniel@gargamel:~/crackme2$./keygen_cme2 daniel
Serial: -1860565822

cme2-3


daniel@gargamel:~/crackme2$./keygen_cme2 535246756
Serial: 1791915272

cme2-4

Done!
This is an easy and good one for your first steps at RE because it's got no protections and you have to reverse a simple algorithm.

Hope you found this article useful.
Regards,
Daniel