You are on page 1of 7

raZZia's Tutorial on Key Generators

presented by Bibliothek.dl.am
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: Sanline S!i"tsearh #.$!
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, :<--re*e*ber #62 ha. the length of the
3e 004024(# : 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(# xor esi, esi .C!! Clear $SI
:004024#0 xor eax, eax .C!! Clear $'5
:004024#2 test e.i, e.i
:004024#4 3le 00402442
:004024#7 *o-sx b8te ptr ecx, [ebp + eax - 2C] .C!! $C5 is loaded with a
letter of the name we entered
:004024#0 a.. esi, ecx .C!! 'dd the letter to $SI
:004024#( inc eax .C!! Increment $'5 to get ne-t letter
:004024## c*p eax, e.i .C!! Did we reach the end of the string9
:00402440 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] .C!! Boad $'5 with the address of the reg number we
entered
:00402449 push 00000000
:0040244: push eax .C!! *ush $'5 (as a parameter for the following
function)
:0040244, call 0040%90 .C!! Well, what do you think this function does9 .)
:00402444 a.. esp, 0000000C
:0040%002 c*p eax, esi .C!! DeyE
:0040%004 3e 0040%020
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
J
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:00 :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
call 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
contain the right registration number )ut since we want to know D7W the reg + is calculated we
will trace inside the function (using #) We will then try to find out D7W the contents of $'5 got in
there
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 004002 and will
ha:e 0x,4CC as its initial :alue )
:0040442N *o-sx b8te ptr e.i, [ebx + e.x] .C!! *ut first letter of the name in $DI
:0040442: lea esi, [e.x+01] .C!! $SI gets the Gletter!numberG
:0040442C call 00404490 .C!! Call function
:004044%1 i*ul e.i, eax .C!! $DII$DIJ$'5 (ea- is the return :alue of the the
pre:ious call)
:004044%4 call 00404490 .C!! Call function
:004044%: *o- e.x, esi
:004044%0 *o- ecx, 44444444
:00404440 i*ul e.i, eax .C!! $DII$DIJ$'5 (ea- is the return :alue of the pre:ious call)
:0040444% i*ul e.i, esi .C!! $DII$DIJ$SI ( esi is the number of the letter position)
:00404447 a.. ebp, e.i .C!! $)*I$)*K$DI (beware that $)* will finally contain the
right reg+)
:0040444 *o- e.i, ebx .C!!these lines compute the lenght of the name we entered
:0040444, sub eax, eax .C!!these lines compute the lenght of the name we entered
:0040444C repnM .C!!these lines compute the lenght of the name we entered
:0040444( scasb .C!!these lines compute the lenght of the name we entered
:0040444# not ecx .C!!these lines compute the lenght of the name we entered
:004044N0 .ec ecx .C!! $C5 now contains the lenght of the name
:004044N1 c*p ecx, esi
:004044N% 3a 0040442N .C!! If its not the end of the name , go do the same with the ne-t letter
:004044NN *o- eax, ebp .C!! S'L$ $)* #7 $'5 EEEE
:004044N9 pop ebp
:004044N pop e.i
:004044N: pop esi
:004044N, pop ebx
:004044N0 ret
MMMMM

:00404490 *o- eax, [004002] .C!! *ut GkeyG in $'5
:0040449N *ul eax, eax, 01N,4#%N .C!! $'5I$'5 J ,6'2$16
:00404490 inc eax .C!! $'5I$'5 K ,
:0040449C *o- [004002], eax .C!! &eplace the GkeyG with the new :alue of $'5
:0040441 an. eax, 94440000 .C!! $'5I$'5 NN HFFF????
:0040447 shr eax, 10 .C!! $'5I$'5 OO,?
:004044: ret
#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