You are on page 1of 7

raZZia's Tutorial on Key Generators

Tools! For tools you need a minimum of debugger like SoftIce for Windows (hence WinIce), and a C compiler with Dos libraries

Content! In this tutorial I will show how to make a key!gen for I"e and Swiftsearch #he protection that these programs use is the well known $nter!%ame!and!&egistration!%umber method 'fter selecting (register(, a window pops up where you can enter your name and your registration number #he strategy here is to find out where in memory the data you enter is stored and then to find out what is done with it )efore you go on make sure you configure the SoftIce dat file according to the *WD tutorial +,

Part 1: Scanline Swiftsearch 2.0! Swiftsearch is a useful little program that you can use to search on the web I will e-plain step by step how to crack it step , Start the program .) step /. Choose register from the menus 0ou will now get a window where you can enter your name and your registration number step 1. $nter SoftIce (ctrl!d) step 2. We will now set a breakpoint on functions like 3etWindow#e-t(a) and 3etDlgItem#e-t(a) to find out where in memory the data that we 4ust entered is stored #he function that is used by this program is 3etDlgItem#e-ta (trial and error, 4ust try yourself .) so, in SoftIce type )*5 3etDlgItem#e-ta and e-it SoftIce with the g command step 6. %ow type a name and a registration number (I used ra""ia and ,/126) and press 78, this will put you back in SoftIce Since you are now inside the 3etDlgItem#e-ta function press F,, to get out of it 0ou should see the following code. lea eax, [ebp-2C] :<--- we are looking for this location push eax push 00000404 push [ebp+0 ] call [!"#$%2&'et(lg)te*+ext,] *o- e.i, eax :<--- eax has the length of the string an. is store. in e.i for later usage/ We see that $'5 is loaded with a memory address and then pushed to the stack as a parameter for the function 3etDlgItem#e-t' Since the function 3etDlgItem#e-t' is already been run we can look at $)*!/c (with $D $D*!/c) and see that the name we entered is there %ow we know where the name is stored in memory, normally it would be wise to write that address down, but we will see that in this case it wont be necessary

So, what ne-t9 %ow we ha:e to allow the program to read the registration number we entered ;ust type g and return and when back in SoftIce press F,, 0ou should see the following code. push 00000000 lea ecx, [ebp-1 ] : <--"o, ebp-1 is where the reg/ nu*ber push ecx : is store./ push 0000042, push [ebp+0 ] call [!"#$%2&'et(lg)te*+ext,] *o- ebx, eax : <--sa-e the lenght of string in #02 test e.i, e.i : <--re*e*ber #() ha. the lenght of the 3ne 00402404 : na*e we entere.5 We see that the registration number is stored at location $)*!,< , check it with $D $)*!,< 'gain, normally it would be wise to note that address down 'lso we see that it is checked if the length of the name we ga:e was not "ero If it is not "ero the program will continue Step =. 7k, now we know where the data we entered is stored in memory What ne-t9 %ow we ha:e to find out what is D7%$ with it >sually it would we wise to put breakpoints on those memory locations and find out where in the program they are read )ut in this case the answer is 4ust a few F,?(s away *ress F,? until you see the following code . c*p ebx, 0000000, 3e 004024(# :<--re*e*ber #62 ha. the length of the : registration co.e we entere.5

#hese two lines are important #hey check if the length of the registration code we entered is e@ual to ,? If not the registration number will be considered wrong already #he program wont e:en bother to check it Aodify $)5 or the FB'3 register in the register window to allow the 4ump Continue *ressing F,? until you get to the following code (note that the adresses you will see could be different) . :004024(# :004024#0 :004024#2 :004024#4 :004024#7 :004024#0 :004024#( :004024## :00402440 xor esi, esi .C!! Clear $SI xor eax, eax .C!! Clear $'5 test e.i, e.i 3le 00402442 *o-sx b8te ptr ecx, [ebp + eax - 2C] .C!! $C5 is loaded with a letter of the name we entered a.. esi, ecx .C!! 'dd the letter to $SI inc eax .C!! Increment $'5 to get ne-t letter c*p eax, e.i .C!! Did we reach the end of the string9 3l 004024#7 .C!! If not, go get the ne-t letter

Well, we see that the program adds together all the letters of the name we entered 8nowing that $SI contains the sum of the letters, lets continue and find out what the program does with that :alue . :00402442 push 0000000, :00402444 lea eax, [ebp-1 ] :00402449 push 00000000 :0040244: push eax :0040244, call 0040% 90

.C!! Boad $'5 with the address of the reg number we entered .C!! *ush $'5 (as a parameter for the following function) .C!! Well, what do you think this function does9 .)

:00402444 a.. esp, 0000000C :0040%002 c*p eax, esi :0040%004 3e 0040%020

.C!! DeyE

We see that a function is called and when &$#urned $SI is compared with $'5 Dmm, lets look at what(s in $'5 ' (9 $'5( re:eals . ????1?1F ?????,/126 G?FG

)ingo #hat(s what we entered as the registration number It should ha:e been what(s inside $SI 'nd we know what(s inside $SI, the sum of the letters of the name we enteredE Step H. %ow we know how the program computes the registration code we can make a key!gen )ut we should not forget that the program checks also that the registration number has ,? digits ' simple C code that will compute the registration number for this program could look like this.

;inclu.e <st.io/h< ;inclu.e <string/h< *ain=> ? char @a*e[100]A int @a*eBength,CffsetA long int $eg D 0, (u**82 D 10A int (u**8 D 0A int Bengt(u**8 D 1A int Bengt , +ellerA printf=E"canline "wift"earch 2/0 crack b8 raFFia/GnE>A printf=E#nter 8our na*e: E>A gets=@a*e>A @a*eBengthDstrlen=@a*e>A HI the for lus calculates the su* of the letters in @a*e IH HI an. places that -alue in $eg IH for =CffsetD0ACffset<@a*eBengthACffsetDCffset+1> ? $egD$eg+@a*e[Cffset]A J HI the while lus calculates the lenght of the figure in IH HI $eg an. places it in Bengt IH while =(u**8 &D 1> ? if = $eg < (u**82 > ? Bengt D Bengt(u**8 A (u**8 D1A J else ? Bengt(u**8DBengt(u**8 + 1A (u**82D(u**82I10A J JA printf=EGnKour registration nu*ber is : E >A HI 4irst print 10-Bengt ti*es a 0 IH BengtD10-BengtA for =+ellerD1A+eller<DBengtA+ellerD+eller+1> printf=E0E>A HI +hen print the registration nu*ber IH

printf=ELluGnE,$eg>A

Case 2 )Me 2/04 fro* 'a.getware I"e from 3adgetware is a cute little program that will put a pair of eyes on your screen which will follow your mousepointer It has a register function where you can enter your name and a registration number #he strategy in this case is still the same . Find out where in memory the entered information is stored and then find out what is done with that information Step ,. Start I"e Chose register and enter a name and a number I used (ra""ia( and (,/126( Sterp /. $nter (C#&B!D) Softice and set a breakpoint on 3etDlgItem#e-t' Step 1. Bea:e SoftIce and press 78 #his will put you back in Softice 0ou will be inside the 3etDlgItem#e-t' function #o get out of it press F,, 0ou should see the following code . *o- esi, [esp + 0C] push 00000074 push 0040C%,0 .C!!7n this memory location the %'A$ we entered will be stored *o- e.i, [!"#$%2&'et(lg)te*+ext,] .C!!Boad edi with adress of 3etDlgItem#e-t' push 00004##: push esi call e.i .C!! Call 3etDlgItem#e-t' push 00000074 .C!! (you should be here now) push 0040C210 .C!!7n this memory location the %>A)$& we entered will be stored push 00004##, push esi call e.i .C!! Call 3etDlgItem#e-t' We see that the function 3etDlgItem#e-t' is called twice in this code fragment #he first call has already happened With $D 2?C1'? we can check that the name we entered is stored on that location #o allow the program to read in the number we entered we type 3 and enter %ow we are inside the 3et! DlgItem#e-t' function again and we press f,, to get out of it We check memory location 2?C/,? and we see the number we entered is stored there %ow we know the locations were the name and the number are stored,we note those downE Step 2. 7k, what ne-t9 We now know where in memory the name and the number are stored We need to find out what the program does with those :alues In order to do that we could set breakpoints on those memory locations to see where they are read )ut in this case it wont be necessary #he answer is right after the abo:e code .

push 0040C210 .C!!sa:e the location of the number we entered (as a parameter for the ne-t call) call 004044:0 .C!! call this unknown function a.. esp, 00000004 *o- e.i, eax .C!! sa:e $'5 (hmmmm) We see a function being called with the number!location as a parameter We could trace into the function and see what it does, but that is not needed With your e-perience of the Swiftsearch e-ample you should be able to guess what this function does It calculates the numerical :alue of the registration number and puts it in $'5 #o be sure we step further using F,? untill we are past the call and check the contents of $'5 (with 9 $'5) In my case it showed . ????1?1F ?????,/126 G?FG 8nowing that $DI contains our registration number we proceed. push 0040C%,0 :C!! sa:e the location of the name we entered (as a parameter for the ne-t call) push 0040:0 0 :C!! sa:e an unknown memory!location (as a parameter for the ne-t call) call 00404%00 .C!!call to an unknown function a.. esp, 0000000 c*p e.i, eax .C!!compare $DI (reg + we entered) with $'5 (unknown, since the pre:ious changed it) 3ne 00401 ,1 .C!!4ump if not e@ual We see that a function is called with two parameters 7ne of the parameters is the location of the name we entered #he other we dont know, but we can find out with $D 2?F?<? We see the te-t (I"e( #his function calculates the right registration number using those two parameters If you 4ust want to crack this program, you can place a breakpoint right after the call and check the contents of $'5 It will will there contain the right registration number )ut since we want to know D7W the reg + is calculated we trace inside the function (using #) We will then try to find out D7W the contents of $'5 got in

call

Step 6. 7nce inside the interesting function you will see that we are dealing with a rather long function It wont be necessary for me to include the complete listing of this function, because we wont need all of it to make our key!gen )ut in order find out which part of the code is essential for the computation of the right registration number, you ha:e to trace S#$* by S#$* and figure out what $5'C#B0 is going onE 'fther doing this i found out that the first part of the function computes some kind of GkeyG #hen this GkeyG is stored in memory and in that way passed on to the second part of the function #he second part of the function then computes the right registration number, based on this GkeyG '%D the name we entered #he code that is essential and that we need for our key!gen is the following. ( %ote that before the following code starts, the registers that are used will ha:e the following :alues. $)5 will point to the first letter of the name we entered,

$D5 will be "ero, $)* will be "ero, #he GkeyG that we talked about earlier is stored in memory location 00400 2 ha:e 0x,4CC as its initial :alue )

and will

:0040442N :0040442: :0040442C :004044%1 pre:ious call) :004044%4 :004044%: :004044%0 :00404440 :0040444% :00404447 right reg+) :0040444 :0040444, :0040444C :0040444( :0040444# :004044N0 :004044N1 :004044N% :004044NN :004044N9 :004044N :004044N: :004044N, :004044N0 MMMMM :00404490 :0040449N :00404490 :0040449C :004044 1 :004044 7 :004044 :

*o-sx b8te ptr e.i, [ebx + e.x] .C!! *ut first letter of the name in $DI lea esi, [e.x+01] .C!! $SI gets the Gletter!numberG call 00404490 .C!! Call function i*ul e.i, eax .C!! $DII$DIJ$'5 (ea- is the return :alue of the the call 00404490 .C!! Call function *o- e.x, esi *o- ecx, 44444444 i*ul e.i, eax .C!! $DII$DIJ$'5 (ea- is the return :alue of the pre:ious call) i*ul e.i, esi .C!! $DII$DIJ$SI ( esi is the number of the letter position) a.. ebp, e.i .C!! $)*I$)*K$DI (beware that $)* will finally contain the *o- e.i, ebx sub eax, eax repnM scasb not ecx .ec ecx c*p ecx, esi 3a 0040442N *o- eax, ebp pop ebp pop e.i pop esi pop ebx ret *o*ul inc *oan. shr ret .C!!these lines compute the lenght of the name we entered .C!!these lines compute the lenght of the name we entered .C!!these lines compute the lenght of the name we entered .C!!these lines compute the lenght of the name we entered .C!!these lines compute the lenght of the name we entered .C!! $C5 now contains the lenght of the name .C!! If its not the end of the name , go do the same with the ne-t letter .C!! S'L$ $)* #7 $'5 EEEE

eax, [00400 2 ] eax, eax, 01N,4#%N eax [00400 2 ], eax eax, 94440000 eax, 10

.C!! *ut GkeyG in $'5 .C!! $'5I$'5 J ,6'2$16 .C!! $'5I$'5 K , .C!! &eplace the GkeyG with the new :alue of $'5 .C!! $'5I$'5 NN HFFF???? .C!! $'5I$'5 OO,?

#he abo:e code consists of a loop that goes trough all the letters of the name we entered With each letter some :alue is calculated, all these :alues are added up together (in $)*) #hen this :alue is stored in $'5 and the function &$#urns 'nd that was what we were looking for, we wanted to know how $'5 got its :alueE Step =. %ow to make a key!gen we ha:e to translate the abo:e method of calculating the right reg+ into a c program It could be done in the following way . (%ote . I am a bad c programmer .)

;inclu.e <st.io/h< ;inclu.e <string/h< *ain=> ? char @a*e[100]A int @a*eBength,CffsetA unsigne. long Better,(u**8,A unsigne. long Oe8 D 0xa4ccA unsigne. long @u*ber D 0A printf=E)Me 2/04 crack b8 raMMiaGnE>A printf=E#nter 8our na*e: E>A gets=@a*e>A @a*eBengthDstrlen=@a*e>A for =CffsetD0ACffset<@a*eBengthACffsetDCffset+1> ? BetterD@a*e[Cffset]A (u**8,DOe8A (u**8,D(u**8,I0x1Na4e%NA (u**8,D(u**8,+1A Oe8D(u**8,A (u**8,D(u**8, P 0x9fff0000A (u**8,D(u**8, << 0x10A BetterDBetterI(u**8,A (u**8,DOe8A (u**8,D(u**8,I0x1Na4e%NA (u**8,D(u**8,+1A Oe8D(u**8,A (u**8,D(u**8, P 0x9fff0000A (u**8,D(u**8, << 0x10A BetterDBetterI(u**8,A BetterDBetterI=Cffset+1>A @u*berD@u*ber+BetterA J printf=EGnKour registration nu*ber is : LluGnE,@u*ber>A J

Final %otes For feedback and suggestions pls contact me .)

raZZia

You might also like