Welcome to Flu[X] Cracking tutor #7
In this One ill show you how to make another keygen

LEVEL: Simple/Intermediate

Tools Needed
-SoftICE
-Brains
-W32Dasm [OPTIONAL]
-DLL Demon v1.0    (http://members.aol.com/progency)

OK lets begin. Download the app and install it.
Under the help button there is a button that says register.
Click this and bring the window up...

We notice it asks for a Name and a Key and it also generates a
unique Serial# for each user.. 

OK Lets begin our trace... Enter Softice and set the Breakpoint
on hmemcpy. Enter in our names and Fake Serial and hit enter.
Softice Should Break.. hit F5 once then we can begin our
trace.. F12 until you get into The process of DLL Demon.
Soon you will come accross this code:


:00461AC3 8B45F4                  mov eax, dword ptr [ebp-0C]
:00461AC6 8D4DF8                  lea ecx, dword ptr [ebp-08]
:00461AC9 B201                    mov dl, 01
:00461ACB E8FC5B0000              call 004676CC               <-single User Keygeneration call
:00461AD0 8B55F8                  mov edx, dword ptr [ebp-08]
:00461AD3 58                      pop eax
:00461AD4 E8B721FAFF              call 00403C90
:00461AD9 745C                    je 00461B37
:00461ADB 8D55FC                  lea edx, dword ptr [ebp-04]
:00461ADE 8B83F8010000            mov eax, dword ptr [ebx+000001F8]
:00461AE4 E84BEBFBFF              call 00420634
:00461AE9 8B45FC                  mov eax, dword ptr [ebp-04]
:00461AEC 50                      push eax
:00461AED 8D55F4                  lea edx, dword ptr [ebp-0C]
:00461AF0 8B83F4010000            mov eax, dword ptr [ebx+000001F4]
:00461AF6 E839EBFBFF              call 00420634
:00461AFB 8B45F4                  mov eax, dword ptr [ebp-0C]
:00461AFE 8D4DF8                  lea ecx, dword ptr [ebp-08]
:00461B01 33D2                    xor edx, edx
:00461B03 E8C45B0000              call 004676CC               <-Site License Keygen call
:00461B08 8B55F8                  mov edx, dword ptr [ebp-08]


OK, we notice both calls call the same address.. meaning it
uses that area more than once.

Lets trace into the first call..


  Making a Single USER Key
  ========================

Ok soon we come accross this code...



:004676CC 55                      push ebp
:004676CD 8BEC                    mov ebp, esp
:004676CF 83C4BC                  add esp, FFFFFFBC
:004676D2 53                      push ebx
:004676D3 894DF4                  mov dword ptr [ebp-0C], ecx
:004676D6 8855FB                  mov byte ptr [ebp-05], dl
:004676D9 8945FC                  mov dword ptr [ebp-04], eax
:004676DC 8B45FC                  mov eax, dword ptr [ebp-04]
:004676DF E850C6F9FF              call 00403D34
:004676E4 33C0                    xor eax, eax
:004676E6 55                      push ebp
:004676E7 6813784600              push 00467813
:004676EC 64FF30                  push dword ptr fs:[eax]
:004676EF 648920                  mov dword ptr fs:[eax], esp
:004676F2 33DB                    xor ebx, ebx
:004676F4 8B45FC                  mov eax, dword ptr [ebp-04]
:004676F7 E884C4F9FF              call 00403B80
:004676FC 85C0                    test eax, eax
:004676FE 7E13                    jle 00467713
:00467700 BA01000000              mov edx, 00000001


This Area Sets the Strings Up for some part. We notice that
It appends the Serial # to the end of our Name..

Example If this is your values  name:JoeBob     Serial: 122351

Then this is the String it passes in:  JoeBob122351


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00467711(C)
|
:00467705 8B4DFC                  mov ecx, dword ptr [ebp-04]
:00467708 0FB64C11FF              movzx ecx, byte ptr [ecx+edx-01] <-get character
:0046770D 03D9                    add ebx, ecx                     <-add ascii to EBX
:0046770F 42                      inc edx                          <-increase position in string
:00467710 48                      dec eax                          <-decrease counter of letters left
:00467711 75F2                    jne 00467705                     <-repeat if more letters left


The above lines of code are simple .. they add up all
the ascii values of the string passed into it with EBX being
used as the accumulator.


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004676FE(C)
|
:00467713 807DFB00                cmp byte ptr [ebp-05], 00       <-test if generating Sitelicense (is no this time arround)
:00467717 7475                    je 0046778E
:00467719 8B45F4                  mov eax, dword ptr [ebp-0C]
:0046771C 50                      push eax

* Possible StringData Ref from Code Obj ->"DSU"
                                  |
:0046771D B828784600              mov eax, 00467828
:00467722 8945BC                  mov dword ptr [ebp-44], eax <-Put "DSU" into "buffer"
:00467725 C645C00B                mov [ebp-40], 0B
:00467729 8BC3                    mov eax, ebx                <-move accumulated ascii into eax
:0046772B B90D000000              mov ecx, 0000000D           <-move Dh (13 decimal) into ecx
:00467730 99                      cdq                         <-Convert Double -> Quad
:00467731 F7F9                    idiv ecx                    <-divide Eax by Ecx (13 decimal)
:00467733 83C259                  add edx, 00000059           <-add 59h to remainder
:00467736 8955C4                  mov dword ptr [ebp-3C], edx <-put Value of EDX into Buffer
:00467739 C645C800                mov [ebp-38], 00
:0046773D C645CC2D                mov [ebp-34], 2D            <-2Dh = "-" letter
:00467741 C645D002                mov [ebp-30], 02
:00467745 895DD4                  mov dword ptr [ebp-2C], ebx <-put Sum of ascii into Buffer 
:00467748 C645D800                mov [ebp-28], 00
:0046774C 8BC3                    mov eax, ebx                <-move accumulated ascii into eax
:0046774E 2503000080              and eax, 80000003           <-Logical AND the ascii by 80000003h
:00467753 7905                    jns 0046775A
:00467755 48                      dec eax
:00467756 83C8FC                  or eax, FFFFFFFC
:00467759 40                      inc eax


Ok an explanation of this code..

We first notice that ALL Single User Serials Start with the letters "DSU"
Next we take a look at the maths part.

It uses the sum of all ascii as before explained.
It divides the Sum of the ascii values by 13.  When you use idiv operand
it puts the WHOLE number of divides into EAX and the remainder into EDX.
For example...

say EAX was equal to 33 in the above code

then after the Idiv  EAX=2(whole divides)  and EDX =7 (remainder)

So what the above code does is get all your ascii values
added up and divide it by 13 and take the remainder.
To the remainder it adds 59 HEX  NOT DEcimal!

It also Takes your Accumulated ascii and logical AND's it
with 80000003 HEX.




* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00467753(C)
|
:0046775A 8945DC                  mov dword ptr [ebp-24], eax  <-move result of AND into buffer
:0046775D C645E000                mov [ebp-20], 00
:00467761 C645E42D                mov [ebp-1C], 2D             <-add another "-" to String
:00467765 C645E802                mov [ebp-18], 02
:00467769 8BC3                    mov eax, ebx                 <-move accumulated ascii into eax
:0046776B B903000000              mov ecx, 00000003            <-mov 3 into ecx to divide by
:00467770 99                      cdq
:00467771 F7F9                    idiv ecx                     <-divide by 3
:00467773 8945EC                  mov dword ptr [ebp-14], eax  <-move Result into string
:00467776 C645F000                mov [ebp-10], 00
:0046777A 8D55BC                  lea edx, dword ptr [ebp-44]
:0046777D B906000000              mov ecx, 00000006



So we see the BASIC Alogorithm for the Single User Key is:

GIVEN
=====
NAME And Serial combined into 1 string
X= Sum of all ascii values of NAme and Serial Combined

THEN...

Single USER Serial# =  DSU + (remainder(X/Dh)+59h) + "-" + X + X AND 80000003h + "-" + Floor(X/3)






    Making a SITE License Key
    =========================


Ok, trace into the second call you will ciom accross this...

This Area Sets the Strings Up for some part. We notice that
It appends the Serial # to the end of our Name..

For The Site License it Simply Takes your Name and the 
Serial # Does NOT Matter!



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00467711(C)
|
:00467705 8B4DFC                  mov ecx, dword ptr [ebp-04]
:00467708 0FB64C11FF              movzx ecx, byte ptr [ecx+edx-01] <-get character
:0046770D 03D9                    add ebx, ecx                     <-add ascii to EBX
:0046770F 42                      inc edx                          <-increase position in string
:00467710 48                      dec eax                          <-decrease counter of letters left
:00467711 75F2                    jne 00467705                     <-repeat if more letters left


The above lines of code are simple .. they add up all
the ascii values of the string passed into it with EBX being
used as the accumulator.


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004676FE(C)
|
:00467713 807DFB00                cmp byte ptr [ebp-05], 00       <-test if generating Sitelicense (is YES this time arround)
:00467717 7475                    je 0046778E                     <-This Time it is True so it Jumps to BElow Code




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

:0046778E 8B45F4                  mov eax, dword ptr [ebp-0C]    
:00467791 50                      push eax
:00467792 B84C784600              mov eax, 0046784C
:00467797 8945BC                  mov dword ptr [ebp-44], eax <-Move 'DS' into Buffer
:0046779A C645C00B                mov [ebp-40], 0B
:0046779E 8BC3                    mov eax, ebx                <-Move added Ascii into eax
:004677A0 B909000000              mov ecx, 00000009           <- Get ready to divide by 9
:004677A5 99                      cdq
:004677A6 F7F9                    idiv ecx                    <-Divide by 9
:004677A8 83C243                  add edx, 00000043           <-Add 43h to remainder of divide
:004677AB 8955C4                  mov dword ptr [ebp-3C], edx <-move remainder+43h into buffer
:004677AE C645C800                mov [ebp-38], 00
:004677B2 C645CC2D                mov [ebp-34], 2D            <- put a "-" in the serial
:004677B6 C645D002                mov [ebp-30], 02
:004677BA 895DD4                  mov dword ptr [ebp-2C], ebx <-put Sum of ascii in serial buffer
:004677BD C645D800                mov [ebp-28], 00
:004677C1 8BC3                    mov eax, ebx                <-move sum of ascii into EAX
:004677C3 B905000000              mov ecx, 00000005           <-Get ready to divide by 5
:004677C8 99                      cdq
:004677C9 F7F9                    idiv ecx                    <-Divide by 5
:004677CB 8955DC                  mov dword ptr [ebp-24], edx <-put Remainder int Serial buffer
:004677CE C645E000                mov [ebp-20], 00
:004677D2 C645E42D                mov [ebp-1C], 2D            <-Put another "-" into serial buffer
:004677D6 C645E802                mov [ebp-18], 02
:004677DA 85DB                    test ebx, ebx
:004677DC 7903                    jns 004677E1
:004677DE 83C303                  add ebx, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004677DC(C)
|
:004677E1 C1FB02                  sar ebx, 02                 <-Similar to SHR
:004677E4 895DEC                  mov dword ptr [ebp-14], ebx <-Put result of SAR into Serial Buffer
:004677E7 C645F000                mov [ebp-10], 00
:004677EB 8D55BC                  lea edx, dword ptr [ebp-44]
:004677EE B906000000              mov ecx, 00000006




So we see the BASIC Alogorithm for the Site License Key is:

GIVEN
=====
X= Sum of all ascii values of Name

THEN...

Single USER Serial# =  "DS" + (remainder(X/9)+43h) + "-" + X + remainder(X/5) + "-" + X SHR 2





BElow is MY KEYGEN SOURCE CODE.. Yeah im a shitty PAS programmer but it works!

===Start Code===




var
 name:string;
 secondc:integer;
 serialn:string;
 eax,ecx,edx:longint;
 pos:integer;

begin


 writeln('DLL Demon v1.0 Keygen');
 writeln('Flu[X]/PC98');
 writeln('12/21/98');
 writeln(' ');
 write('Enter Name : ');
 readln(name);
 write('Enter Serial Number : ');
 readln(serialn);
 writeln('');
 write('Site License Key: ');

  {Generate Site License Key}
 pos:=1;
 ecx:=0;
 while pos <= length(name) do
 begin
  ecx:= ecx+ord(name[pos]);
  pos:=pos+1;
 end;
 eax:=ecx;
 edx:=0;
  while ecx >=9 do
  begin
   ecx:=ecx-9;
  end;
  ecx:=ecx+$43;
  write('DS',ecx,'-',eax);
  ecx:=eax;
  while ecx >=5 do
  begin
   ecx:=ecx-5;
  end;
  write(ecx,'-');
  ecx:=eax;
  ecx:=ecx SHR 2;
  writeln(ecx);
  write('Single User Key : ');


  {Single User Generation}
  name:=name+serialn;
  pos:=1;
  ecx:=0;
  while pos <= length(name) do
  begin
   ecx:= ecx+ord(name[pos]);
   pos:=pos+1;
  end;
  eax:=ecx;
  while ecx >=13 do
  begin
   ecx:=ecx-13;
  end;
  ecx:=ecx+$59;
  write('DSU',ecx,'-',eax);
  ecx:=eax;
  ecx:= ecx AND $80000003;
  write(ecx,'-');
  ecx:=eax;
  edx:=0;
  while ecx >=3 do
  begin
   ecx:=ecx-3;
   edx:=edx+1;
  end;
  writeln(edx);

end.


===END CODE===






I hope to see you again in Flu[X] tutor #8
As always if you like a program buy it!  Thi essay is for
educational purposes ONLY! Software authors deserve your support!

Flu[X]/PC98
http://tuts98.cjb.net
pcflux@hotmail.com
