Hello and welcome to my first tutorial, please excuse my gramatical faults, my english could
be better ;) Today, we want to make a keygen for HappyIcon v2.01, you can download from
http://www.logipole.com! The algorithm is very easy, so if you can keygen this will be no
challenge, but my tutorial is not for beginners, you should have fished some serials before.
You will need Softice and Pascal to code our keygen, download both from crackstore.com
you also can use the keygen source for Delphi, just change some things. Ok, that's all!
Start:
Let's begin .. start softice and set breakpoint on hmemcpy by typing 'bpx hmemcpy'. First,
disable your bp, because we want to enter our data without jumping to softice. Now start
HappyIcon, open register-screen and enter you name, first name and serial, i enter:
Name : ucaze
First Name : TNT
Serial : 11229966
Enable hmemcpy .. and press register-button. You will notice softice will break 3 times,
so press 2x F5, then F11 to get out of the call. Now you should be in Kernel32.dll, we want
in HappyIcon.exe, so press F12 until you see on the bottom line 'HAPPYICON!.text+...'
Now we are in HappyIcon.exe, now it should look like this: (code taken from w32dasm)
:0041403D test eax, eax ; eax=length of fake serial
:0041403F jne 00414079 ; if not zero, jump to 00414079
:00414041 push 00000010 ; else...
:00414043 push 0042490C ; push error messages
:00414048 push 004248BC ; for ..
:0041404D push ebp
:0041404E Call dword ptr [004202AC] ; .. MessageBox
:00414054 push 00000471
:00414059 push ebp
:0041405A Call dword ptr [004202B0]
:00414060 push eax
:00414061 Call dword ptr [004202B4]
:00414067 mov eax, 00000001 ; eax=1 => bad boy
:0041406C pop edi ; stack .. blabla
:0041406D pop esi
:0041406E pop ebp
:0041406F pop ebx
:00414070 add esp, 00000784
:00414076 ret 0010 ; leave call with eax=1
:00414079 mov ebx, dword ptr [004202F4] ; we land here if serial is entered
:0041407F lea edx, dword ptr [esp+14] ; edx=name
:00414083 push edx
:00414084 lea eax, dword ptr [esp+6C] ; eax=first name
:00414088 push 00422178 ; push 'HappyIcon' (constant)
:0041408D push eax
:0041408E lea ecx, dword ptr [esp+5A0]
:00414095 push 004248B4 ; push '%s%s%s'
:0041409A push ecx
:0041409B call ebx ; this call make our new string
:0041409D lea edi, dword ptr [esp+5A8] ; and mov it to edi
:004140A4 or ecx, FFFFFFFF
:004140A7 xor eax, eax
:004140A9 add esp, 00000014
:004140AC repnz
:004140AD scasb
:004140AE not ecx
:004140B0 sub edi, ecx
:004140B2 lea edx, dword ptr [esp+00000190]
:004140B9 mov eax, ecx
:004140BB mov esi, edi
:004140BD mov edi, edx
:004140BF shr ecx, 02
:004140C2 repz
:004140C3 movsd
:004140C4 mov ecx, eax
:004140C6 lea eax, dword ptr [esp+190] ; new string to eax
:004140CD and ecx, 00000003
:004140D0 repz
:004140D1 movsb
:004140D2 mov cl, byte ptr [esp+190] ; CALCULATION BEGINS HERE
:004140D9 test cl, cl ; cl=ascii of first char
:004140DB je 004140FC ; if there's no ascii jmp
:004140DD cmp byte ptr [eax], 5F ; cmp ascii with 5Fh ('_')
:004140E0 jne 004140E5 ; if so, ...
:004140E2 mov byte ptr [eax], 20 ; ascii is 20h (' ')
:004140E5 movsx ecx, byte ptr [eax] ; ascii to ecx
:004140E8 xor ecx, dword ptr [esp+10] ; xor ecx with [esp+10]
:004140EC xor ecx, 13579ACE ; xor ecx with 13579ACEh
:004140F2 inc eax ; eax(name) + 1 (next char)
:004140F3 mov dword ptr [esp+10], ecx ; [esp+10] = ecx
:004140F7 cmp byte ptr [eax], 00 ; cmp name with 00 .. LOOP
:004140FA jne 004140DD ; if there're some chars, jump back .. LOOP
:004140FC lea edx, dword ptr [esp+0BC] ; fake serial to edx
:00414103 push edx
:00414104 call 0041637C ; fake serial testet (if avaible etc.)
:00414109 mov ecx, dword ptr [esp+14] ; mov [esp+10] (from calculation) to ecx
:0041410D add esp, 00000004
:00414110 xor ecx, 2468BDF0 ; xor ecx (= [esp+10]) with 2468BDF0h
:00414116 cmp eax, ecx ; cmp fake serial(? eax) with real(? ecx)
:00414118 je 00414148 ; :)
Ok, now the analyse .. we start with 0041409B. Here you see 'call ebx', in this call our
entered data are added to one string. Type 'd edi' to see it, my new string is:
TNTHappyIconucaze
So syntax is: first_name/HappyIcon(constant)/name
004140D2: calculation begins. Here the ascii of first char is moved to cl and tested if a
name is entered, if not, jump nearly direct to serial comparation (when no serial is
generated it's 100% wrong ;). Then ascii is in eax, eax is compared with 5Fh, the ascii for
'_', if it's '_', eax is ' ' (20h), else we go on without changes. This means:
'ucaze_TNT' would be the same as 'ucaze TNT'
On 004140E5 ascii (in eax) move to ecx. Then ecx is xored with [esp+10]. You see the value
of this register by typing 'd esp+10'. Look at hex-code and you will see FFFFFFFF (-1).
After this ecx is xored with 13579ACEh. On 004140F3 you see that [esp+10] is now ecx, so on
next loop it will be another value ;)
004140F2: inc eax ... you know our name is in eax, when you inc eax, it can look like this:
eax = ucaze
inc eax
eax = caze
So he take the next char when he make a loop. When eax is 00, he quit loop and go on!
When he finished loop, our fake serial is tested in call 0041637C, but it's uninteresting.
The next line our value which was calculated in the loop move to ecx. Then ecx is xored
with 2468BDF0h ... and ... our serial is complete. Now type '? eax' to see our fake serial
and '? ecx' you see your REAL SERIAL!!!
Fisnish:
Now we need a keygen that you can release your work! I made a pascal script, you also can use
it for delhpi, but pascal files are smaller (~7kb). Perhaps there are ways to make it better
but i used this code all the time ;)
uses crt; ; standart
var ; declare variables
name, fname, endname: string ; all strings
ecx, i : longint; ; register as longint
esp: longword; ; MUST BE longword ...
; or you get negative code
begin ; code start
writeln('KeyGen for HappyIcon v2.01 by ucaze / TNT!'); ; Text blabla
writeln;
write('Name: ');
readln(name); ; read in your name
write('First Name: ');
readln(fname); ; read in first name
endname:= fname, 'HappyIcon', name; ; make string
esp:= $FFFFFFFF; ; first value of esp
For i:= 1 to length(endname) do ; start loop
begin
ecx:= ord(endname[i]); ;\
If ecx = $5F then ecx:= $20; ; \
ecx:= ecx ord esp; ; > Calculation
ecx:= ecx ord $13579ACE; ; /
esp:= ecx; ;/
end;
esp:= esp xor $2468BDF0; ; xor loop result
writeln('Serial: ', esp); ; post serial
end.
So, that's it. If you don't understand something don't hesitate writing me emails or
visit #tntcrackers on IRC EFnet and talk with me ;) If my tutorial is bad or whatever,
just write to me, i like feedback :P
regards, ucaze (TNT!Crack!Team http://kickme.to/tnt)