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