Hello!
Welcome, to this very little and lame tutorial about tHE ANALYST's keygen-me 1

Yesterday I spoke with a good friend of mine, chopun who told be that he wanted to begin keygening
but that he needed some help. Today, when I joined #Cracking4Newbies, I saw ANAL's (It seems everyone
loves to call you anal :) new k4n site in topic. So I decided to take a newbie keygen-me and write a tute
for chopun.
In fact this KGME is very very easy and it should'nt be a problem for most of you. I'll probably write
other tutes for chopun soon, and I may do it with ANAL's nice KGME but of a harder level, this time!

Okay, go on with the show!

Seeing the size of the target, we already know it has been coded in some high level language, so expect
some strange assembly :)

Okay, let's break on GetWindowTextA (high level languages often use this rather than GetDlgItemTextA)

And we land there (Dead listing provided by Harlequin's ver of w32dasm):

* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0066, ""
                                  |
:00401085 6A66                    push 00000066
:00401087 53                      push ebx

* Reference To: USER32.GetDlgItem, Ord:0000h
                                  |
:00401088 E8159C0000              Call 0040ACA2		; Get the Handle of our edit box
:0040108D 6A64                    push 00000064		; max count = 64h ?? Should be 50d!
:0040108F 8D9548FFFFFF            lea edx, dword ptr [ebp+FFFFFF48]
:00401095 52                      push edx		; Where to store our name
:00401096 50                      push eax


* Reference To: USER32.GetWindowTextA, Ord:0000h	; get The name
                                  |
:00401097 E8129C0000              Call 0040ACAE

Let's trace over (with F10)


* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0068, ""
                                  |
:0040109C 6A68                    push 00000068
:0040109E 53                      push ebx

* Reference To: USER32.GetDlgItem, Ord:0000h
                                  |
:0040109F E8FE9B0000              Call 0040ACA2			; Here we get the handle of our edit box
:004010A4 6A64                    push 00000064
:004010A6 8D8DE4FEFFFF            lea ecx, dword ptr [ebp+FFFFFEE4]
:004010AC 51                      push ecx
:004010AD 50                      push eax


* Reference To: USER32.GetWindowTextA, Ord:0000h		; to use it for GetWindowText
                                  |
:004010AE E8FB9B0000              Call 0040ACAE



* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0067, ""
                                  |
:004010B3 6A67                    push 00000067
:004010B5 53                      push ebx

* Reference To: USER32.GetDlgItem, Ord:0000h
                                  |
:004010B6 E8E79B0000              Call 0040ACA2
:004010BB 8BF0                    mov esi, eax
:004010BD 8D8548FFFFFF            lea eax, dword ptr [ebp+FFFFFF48]
:004010C3 50                      push eax
:004010C4 E867050000              call 00401630
:004010C9 59                      pop ecx
:004010CA 8945D8                  mov dword ptr [ebp-28], eax	; Our Name length!
:004010CD 8D95E4FEFFFF            lea edx, dword ptr [ebp+FFFFFEE4]
:004010D3 52                      push edx
:004010D4 E857050000              call 00401630
:004010D9 59                      pop ecx
:004010DA 68EAB04000              push 0040B0EA
:004010DF E84C050000              call 00401630
:004010E4 59                      pop ecx
:004010E5 680EB14000              push 0040B10E
:004010EA E841050000              call 00401630
:004010EF 59                      pop ecx
:004010F0 837DD803                cmp dword ptr [ebp-28], 00000003
:004010F4 7E7B                    jle 00401171		; Minimal lenght of serial
:004010F6 90                      nop
:004010F7 90                      nop
:004010F8 90                      nop
:004010F9 90                      nop
:004010FA 33C9                    xor ecx, ecx
:004010FC 33D2                    xor edx, edx
:004010FE 33DB                    xor ebx, ebx
:00401100 33C0                    xor eax, eax
:00401102 837DD832                cmp dword ptr [ebp-28], 00000032	; Hey, 32h is 50d
:00401106 7D69                    jge 00401171	; This checks the maximum lenghth of the serial
:00401108 90                      nop
:00401109 90                      nop
:0040110A 90                      nop
:0040110B 90                      nop



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040111C(C)
|

Oh my god, a serial generation routine!

At this point eax = ecx = edx = 0


:0040110C movsx eax, byte ptr [ebp+ecx-000000B8] ; Get the first char
:00401114 inc ecx				 ; inc ecx so next time we get another char
:00401115 xor eax, ecx				 ; Some evil stuff...
:00401117 add ebx, eax				 ; .....
:00401119 cmp ecx, dword ptr [ebp-28]		 ; All chars done?
:0040111C jne 0040110C				 ; If not, go one more time
:0040111E imul eax, 00000006			 ; Still evil stuff...
:00401121 shl ebx, 07				 ;
:00401124 add eax, ebx				 ;
:00401126 mov dword ptr [ebp-38], eax		 ;
:00401129 push [ebp-38]				 ; Push our serial

* Possible StringData Ref from Data Obj ->"%lX"

And now we even have our format string! Look! ^^

                                  |
:0040112C 6838B44000              push 0040B438
:00401131 8D8D80FEFFFF            lea ecx, dword ptr [ebp+FFFFFE80]
:00401137 51                      push ecx
:00401138 E8873D0000              call 00404EC4
:0040113D 83C40C                  add esp, 0000000C
:00401140 8D8580FEFFFF            lea eax, dword ptr [ebp+FFFFFE80]
:00401146 50                      push eax
:00401147 8D95E4FEFFFF            lea edx, dword ptr [ebp+FFFFFEE4]
:0040114D 52                      push edx

* Reference To: KERNEL32.lstrcmpA, Ord:0000h
                                  |
:0040114E E8339C0000              Call 0040AD86
:00401153 85C0                    test eax, eax
:00401155 750D                    jne 00401164

* Possible StringData Ref from Data Obj ->"Congratulations! IF this number "
                                        ->"comes *FROM YOUR* keygen, Write "
                                        ->"a tutorial dude ;)."

Heh, that's what I'm doing :p

Ok, now I think you've got all what you need to write a keygen. Here's the proc :

GenKey proc _hDlg:dword
uses ebx, edx
	push	51d			; The max length of our string
	push	offset szName		; Our name pointer
	push	IDC_EDIT1		; Where I whant to get the name
	push	_hDlg			; The handle of our Dialog
	call	GetDlgItemTextA		; Let's get the nam

	cmp 	eax, charmini		; Enough chars ?
	jb	minchars		
	cmp	eax, charmaxi
	je	tropdechar		; Less than 50 chars ? I use a je there because we can't have
	mov	edx, eax		; more than 50 chars because of the last GetDlgItemTextA param
	xor	ecx, ecx
	xor	ebx, ebx
serial_loop1:				; Here is an exact copy of what is being done by the proggy
	movsx	eax, byte ptr [szName + ecx]
	inc	ecx
	xor	eax, ecx
	add	ebx, eax
	cmp	ecx, edx
	jnz serial_loop1
	imul	eax, 6
	shl	ebx, 7
	add	eax, ebx
	
	push	eax			; Our serial is in EAX
	push	offset format		; Our format string (%01X)
	push	offset szSerial		; Our serial
	call	_wsprintfA		; Let's format!
	
	push	offset szSerial		; And
	push	IDC_EDIT2		;
	push	_hDlg			;
	call	SetDlgItemTextA		; Display it!
	mov	eax, 1			;
	ret				;
tropdechar:
	push	offset maxtext		; Too many chars ?
	push    IDC_EDIT2
	push    _hDlg
	call	SetDlgItemTextA
	ret				;

minchars:				; Less than 4 chars ?
	push	offset mintext
	push    IDC_EDIT2
	push    _hDlg
	call	SetDlgItemTextA
	ret				;return
GenKey endp

Okay, I hope you've learned something, go on with next KG4N crackme !

Greets to (no order) : Chopun, Dimedrol, Magic Chose, TaM', GanJa, tHE ANALYST, CrackZ, evil-risc, Recca,
Seifer and all my other friends!

I wrote this tute + keygen in less that 15 minutes, so I know it's lame, sorry :/
Don't hesitate to ask you something you would'nt have understood.

								- TiTi
