Hacks, Cracks And More!
  3
 

Construction of Keygenerators


Table of Contents:
A) Introduction
B) Programs to be cracked
C) Tools you need
D) Notes


 

INTRODUCTION


Even though there are many tutorials on writing keygens out there nowadays, I still feel there is a need to teach the very beginners how to do them, else how can we learn and become more advanced ? Many of the keygen tutorials are aimed at the intermediate or advanced crackers in which the protection scheme in the chosen program is well beyond the capabilities of most newbies. There have been some good tutorials however, for the newbies, written by guys like CoRN2, pain and Vizion. Since I have only recently begun to make keygens myself, the information contained in this tutorial won't be too advanced.


PROGRAMS :

  1) HTMASC 2.2  
  2) J-Write 2.3  
  3) Crypto 3.1


TOOLS :

  1) Our beloved softice to see the code 'real time' ( any version, I use 3.2 ) 
  2) Wdasm for looking at large code snippets ( I suppose any version would do ) 
  3) Regedit & notepad ( to unregister the programs  
  4) Turbo PASCAL, ASM and TLINK, and a knowledge of a 'little' programming in PASCAL and ASM. 
  5) Patience 



NOTES

Programs' protections get *slightly* more complex through the tutorial so don't skip to number 3 straight away, take your time and understand the other two first. They are much easier. If I tell you the 3rd app uses internal data lookup tables, don't be put off, its the most interesting

Feel free to write the keygens in whatever language you want to. I can only code a little in PASCAL and ASM so that's what I will write the keygen's with. I hope I can explain the protection for each app well enough so you can go straight and write it with C or whatever you want.

This essay does not cover how to set up softice, place breakpoints or anything else like that, it is assumed you have some useful knowledge of softice and the assembler language. If not, then go and get Ed!son's, exact's and CoRN2's softice tutorials and learn them well.



One thing I cannot emphasize enough, to build keygens you must always understand COMPLETELY the protection of your target.

Little bits of code in a target may seem insignificant during run-time but they may have an enormous effect on the end code.

Then you have to reproduce what the program does to the data you enter to make a keygen.

Make sure you have softice set up according to how many other tutorials tell you with symbols from user32.dll loaded. For this tutorial you will only need 2 regular breakpoints: GetDlgItemTextA and Hmemcpy.



LETS BEGIN



I have a certain method I use when attempting to make a keygen.



1) Find your REAL code (if possible) in the program to see the format of it (numbers ? letters ? dashes ?). 
2) Test the real code to make sure it isn't a temp code or something else nasty which programmers might do. 
3) Go through the program code step by step, understanding it, writing down notes and values of registers (eax etc.). 
4) Write the keygen in whatever language is most suitable. 
5) TEST the beast



TARGET 1 : HTMASC 2.2


As you should always do, run the program and see what sort of protection it is. Then enter your name and a fake reg number, enter softice, place your breakpoints.


:bpx getwindowtexta ( for 32bit program)

:bpx getdlgitemtexta


and return back to HTMASC with ctrl-d. Press OK and......nothing happens apart from the stupid box saying your code is wrong. So it wasn't either of those two. When that happens, set a breakpoint on hmemcpy and try again.

(NOTE: you can tell this is a Borland app (Delphi I think) by looking the the OK & Cancel buttons, they do not look like normal ones. Borland apps do not usually use getwindowtexta or getdlgitemtexta but they ALWAYS use hmemcpy so it is safe to breakpoint on it.)

Softice should have snapped this time and if you press ctrl-d to try and let it read the other box with hmemcpy again, it doesn't snap. So, press OK again and stay in softice. Press F12 ( 7 times ) until you get back to the HTMASC code and then use F10 to step past 6 RETs. You are now back in the main HTMASC code where all the interesting stuff happens.

:00460B0D E8FE8FFBFF

 call 00419B10 ;

 you land back after this call 

:00460B12 8B45F8

 mov eax, dword ptr [ebp-08] ;

 put our name into eax 

  
* Possible StringData Ref from Code Obj ->"2.0 Registration valid for minor updates"

:00460B15 BA440C4600

 mov edx, 00460C44 ;

put the above string into edx 

:00460B1A E855EBFEFF

 call 0044F674 ;

interesting call 

:00460B1F 8BF0

 mov esi, eax 

 

:00460B21 3BF7

 cmp esi, edi ;

 and what might this be ?

:00460B23 0F85C1000000

  jne 00460BEA

 



 
The important lines are highlighted in red. I will do this throughout the tutorial.



Just before the call to 00460C44, it moves our name and another string into eax and edi respectively. So that call probably contains the serial calculation and there is a CMP almost straight after the call. Remember what I said earlier, find your real code first if you can to see what format it is in. Step past the call and onto the line with the cmp. Type '? edi' and you will see your code. Type '? esi' and you will see another number. Lets not patch the jump. Instead, disable your breakpoints, exit softice, type the number into the reg code box and press OK. If you did it correctly, the program should now be registered to you.



So we know the registration code is a simple number, no characters, dashes or other symbols. Time to make the keygen. 

To save you a while of looking for how to unregister the program, I'll tell ya. Go to your windows directory and edit the file called Htmasc32.ini. Delete the registration section at the bottom of the file. And restart the program. 

Repeat the above steps until you get to the important call and use 't' to trace into it.


====== cut a bit of rubbish to save space =====

:0044F684

55 push ebp 

 

:0044F685 68F6F64400

push 0044F6F6 

 

:0044F68A 64FF30

 push dword ptr fs:[eax] 

 

:0044F68D 648920

mov dword ptr fs:[eax], esp

 

:0044F690 BB0F020000

 mov ebx, 0000020F ;

ebx = 20F hex or 527 dec

:0044F695 8BD6

mov edx, esi ;

copy name into edx

:0044F697 8D45F8

lea eax, dword ptr [ebp-08] 

 

:0044F69A E80140FBFF

call 004036A0 ;

unimportant (I hope) 

:0044F69F 8D45F8

lea eax, dword ptr [ebp-08] 

 

:0044F6A2 8BD7

mov edx, edi ;

put '2.0 Registration' string in edx 

:0044F6A4 E8DF40FBFF

call 00403788 ;  

joins name and other string 

:0044F6A9 8B45F8

mov eax, dword ptr [ebp-08] ;

put the new string in eax

:0044F6AC 8D55FC

 lea edx, dword ptr [ebp-04] 

 

:0044F6AF E8446BFBFF

call 004061F8 ;

convert string to upper case

:0044F6B4 8B45FC

mov eax, dword ptr [ebp-04] ;

put it in eax 

 :0044F6B7 E8C440FBFF

 call 00403780 ;

 get length of string and store in eax 

 :0044F6BC 84C0

 test al, al ;

 was length zero?

 :0044F6BE 761B

 jbe 0044F6DB ;

 if it was then clear off 

 :0044F6C0 B201

 mov dl, 01 

 




* Referenced by a (C)onditional Jump at Address: (just the loop jumping back)

|:0044F6D9

:0044F6C2 33C9

xor ecx, ecx ;

clear ecx 

:0044F6C4 8ACA

mov cl, dl ;

low edx (dl) is used as a counter 

:0044F6C6 8B75FC

mov esi, dword ptr [ebp-04] ;

put long string in esi (uppercased) 

:0044F6C9 0FB64C0EFF

movzx ecx, byte ptr [esi+ecx-01] ;

get byte+counter out of it

:0044F6CE 03D9

add ebx, ecx ;

add it to ebx

:0044F6D0 81C3D2040000

add ebx, 000004D2 ;

add 4D2 (1234) to it 

:0044F6D6 42

inc edx ;

increase counter 

:0044F6D7 FEC8

dec al ;

length-1

:0044F6D9 75E7

jne 0044F6C2 ;

end of string 

 

 

; if not, go back.


..............

  :0044F6F5 C3                        ret 


Once the above loop has finished, the program soon RETurns to where we first entered the call after moving ebx ( the proper code) into eax. I left out a little code at the end of the call as it is unimportant and I have described above basically what it does.


AFTER CALL RETURN:
 

:00460B1A E855EBFEFF

call 0044F674  

 

:00460B1F 8BF0

mov esi, eax ;

we come back here 

:00460B21 3BF7

cmp esi, edi ;

compare good/bad codes 

:00460B23 0F85C1000000

jne 00460BEA ;

go away bad_guy if not equal 


  

Here is a summary of the protection scheme:



1) Join your name with the string "2.0 Registration valid for minor updates" 
2) Convert all the characters to upper case ( if they are lower case, -20 from their ascii code ) 
3) Set your code variable to 527 or hex 20F 
4) Add the code for each digit to the variable followed by 1234 or hex 4D2 



Here is my PASCAL source. Feel free to do it in ASM or C or whatever, preferably not cobol



program HTM_keygen;

uses crt;



var 
count : integer; { only need small numbers } 
code : longint; { need bigger number here } 
ch : char; 
name, dummystr : string;



begin;

Writeln('HTMASC keygen by Quantico Mex/C4N'); 
Write('Enter your name: '); 
readln(name); { um....read the name!} 
dummystr := '2.0 Registration valid for minor updates'; 
dummystr := name + dummystr; {join the name and the dummy string} 
code := 527; { this is what ebx starts at in program} 
for count := 1 to length(dummystr) do 


 

begin



ch := char(dummystr[count]); { get 1 digit of string at a time } 
ch := Upcase(ch); { make sure it is upper case } 
code := code + Ord(ch); { add the number to code } 
code := code + 1234; { add 1234 to code } 
end;

writeln;

writeln('Your code is: ', code); { write the reg code }

End.



This code just consists of a loop that goes through all the digits of the joined string, adds the ascii code for each digit to a variable called code followed by 1234. When it exits the loop it writes the code to the screen and exits.



NOTE ABOUT UPPERCASE:



Remember this ?

:0044F6AF E8446BFBFF

call 004061F8 ;

convert string to upper case

:0044F6B4 8B45FC

mov eax, dword ptr [ebp-04] ;

put it in eax 


I'll explain this call just so you understand it if you ever meet it again. It is a common procedure for converting strings to uppercase. This is part of the call.

:00406219 8A02

mov al, byte ptr [edx] ;

byte of string 

:0040621B 3C61

cmp al, 61 ;

is it already uppercase? 

:0040621D 7206

 jb 00406225 ;

if so then jump 

:0040621F 3C7A

cmp al, 7A ;

higher than z? | 

:00406221 7702

ja 00406225 ;

if so then jump 

:00406223 2C20

 sub al, 20 ;

convert to lower case 


* Referenced by a (C)onditional Jump at Addresses: ----------------------|

|:0040621D(C), :00406221(C)

|

:00406225 8806

mov byte ptr [esi], al 

 

:00406227 42

inc edx ;

 increase edx to get next char 

:00406228 46

inc esi ; 

 

:00406229 4B

dec ebx ;

decrease string length counter 

:0040622A 85DB

 test ebx, ebx ;

reach end of string ? 

:0040622C 75EB

jnz 00406219 ;

if not, jump back for more 





This tests each character to see if it is lower than 'a' in which case it is already an upper case letter or a symbol, jumps to get the next letter of it is or if not then tests the upper limit and if it is between these two numbers, 61h and 7Ah then it is a lower case letter so subtract 20h from it to convert it to an upper case letter. (check your ascii chart to see for yourself ). I just explain this here as MANY programs use it to convert to uppercase and I know some newbies who get confused when they see something like this, they think it is part of the main protection routine. That's it for the first app. Lets move on.

 Target 2 here 


 
   
 
This website was created for free with Own-Free-Website.com. Would you also like to have your own website?
Sign up for free