Posted by ShADe on 1/20/2000, 11:42 pm
, in reply to "ShADes Thread"
203.57.68.13
Here is the assembler source code for just the generation section of my assembly keygen. Rather than cut and use the original Acoustica routines I have re-written them in my own code making
the whole process (I think)is easier to understand. I have commented the program as much as possible
and an explanation of how the keygen routine works is contained in the header.I will post the full source code and the program at my site here:
for a couple of days, should anybody be interested.
I have not compressed the program so that you can trace it in W32Dasm should you so desire.
Hopefully this is clear enough but I will be happy to answer any questions I can.
;This is used with _wsprintf for converting from hex to dec. See API ref
fmat db "%lu",0
;This is the default if no name is entered
No_Name db 'Enter Name!',0
Name_IN db 80h dup (?) ;Name (Max. 80h chars);This is the multiplicands converted to ascii. I am afraid my assembler
;is still in its infancy and apart from pushing each dword individually
;I did not know how else to get the values into memory
multi1 db 'html won't let me post these but they are basically',0
multi2 db 'the ascii char conversion of the num strings shown
below',0
;for our calculated # before appending to AC200-
temp db 80h dup (?)
;Holds the company edit box text
Company db 80h dup (?)
;Key- the asterix make sure theres enough free memory for our final number
the_key db 'AC200-**********',0.CODE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%% Summary of Keygen routine %%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;% 1 Read each letter of name %
;% 2 multiply it by its equivalant+1 value %
;% in the multi string. So 1st letter %
;% is multiplied by (eb)2nd by (0c) %
;% 3 add the result to a total %
;% 4 do this for each letter of name %
;% 5 Repeat this using Company and multi2 %
;% Still adding to same total %
;% 5aDivide by 186A0h keeping only remainder %
;% 6 Convert the result to decimal %
;% 7 Append it to the AC200- string %
Note: if the name or company is greater than 15 then the extra is stripped away
and the remainder is used to find the equivalent position in the multi string
ie a name length of 20d = 14h by anding 14h with 0fH we leave only the 04h so
the fourth byte of multi is used. multi1 4th byte= 7c .Remember the positions
start from 0 in strings so the 4th byte is in fact byte5.
The multi strings are written as below in memory:pos# 3 2 1 0
offset
0x00 bd0ceb2ah
0x04 c53d7d7ch
0x08 fa7c01c9h
0x0c 7da268d4h
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%Original Multi values%%%%%%%%%%%%
;% %
;% Mutli1:2aeb0cbd7c7d3dc5c9017cfad468a27d %
;% Multi2:ea142b3f579cf07c0d0eff02364a190e %
;% %
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GetKey proc
push edx ;save registers
push ebx
push ebp
push ecx
xor esi,esi ;clear esi;First we calculate the name
mov edx, offset Name_IN;Name_In holds the name from the edit box
push edx ;put it on the stack
call lstrlenA ;get the length of the name
test eax,eax
je comp ;If name is empty skip calcs
mov ecx,eax ;save the length in ecx
multiply1:
;for ease I calculate the serial
;number in reverse. So we take the last letter of name and its equivalent
;from the multiplicand string and work towards the first letter
mov ebx,ecx ;use ebx for multi string counter
and ebx,0000000Fh ;so name & comp can be >16 chars
;we use only lower byte for pos of
multi1
movsx eax, byte ptr [offset Name_IN+ecx-1] ;letter from name. ecx=name length
movsx edx, byte ptr [offset multi1+ebx] ;letter from multiplicand
imul edx ;multiply them, result in eax
add esi,eax ;add result to total
dec ecx ;so as to select the next letter
test ecx,ecx ;check to see if we are done
jne multiply1 ;if not go againcomp:
;Now we do the company
mov edx, offset Company
push edx
call lstrlenA ;get the length of the name
test eax,eax ;Ensure there is a vaule in
je convert ;company and skip if not
mov ecx,eax ;save the length in ecx
;I had a problem here because the 8th digit was 0dh which is
;carriage return and it caused problems with the compiler
;so i replaced 0dh with an asterix in the string and here
;I patch it directly into the address.
mov dword ptr[ebx+8],02ff0e0dh
multiply2:
mov ebx,ecx
and ebx,0000000Fh
movsx eax, byte ptr [offset Company+ecx-1];Doing it backwards for ease so
movsx edx, byte ptr [offset multi2+ebx];put last letter of company and multi2
imul edx
add esi,eax
dec ecx
test ecx,ecx
jne multiply2
convert:
mov eax, esi ;Why this number beats me but what
mov ecx, 000186A0h ;we are doing here is dividing our result
xor edx, edx ;by this # and only using the remainder
div ecx ;so we use only the part less then 186a0h;begin conversion to decimal
push edx ;put our hex ser# on stack
push offset fmat ;conversion format string
push offset temp ;address for result
call _wsprintfA ;Convert it see API ref for details
pop ebp ;just cleaning up a bit
pop ebp
pop ebp
;Now we need to append our string to AC200-
xor eax,eax ;zero eax so we can use it to count
mov edx,offset temp ;our decimal ser#
mov ebx,offset the_key ;AC200-**********makekey:
;In assembler we cannot copy directly from one memory location to another we
;have to go through a register. So here we use 'cl' as the intermediary.
mov cl, byte ptr[edx+eax] ;read byte from our number
mov byte ptr[ebx+6+eax],cl ;write it to the end of AC200-
inc eax ;eax is used to select the next address
cmp byte ptr[edx+eax-1],00h ;-1 because we want it to append 00h
jne makekey ;go again if we are not donepop ecx ;Put the registers back how they were
pop ebp
pop ebx
pop edx
ret ;go and show it