; 1) not sure why the prog keeps a 'clean' copy of the name (included anyway) ; 2) only added enough datatable for the 16 digit code. Can add more if needed (table replicates) ; 3) spent ages debugging faults, all cleared now. Needed to clear eax and edx before the idiv ; otherwise a divide overflow occurs ; 4) code is not optimized ; 5) keygen calculates both valid codes but the one calculated by the idiv's is presented 1st ; because it is easier to read. The other is only to give the user another option. .model tiny .386 org 100h .data GroupLogo db 13,10 db ' . a . n . e . w . b . r . e . e . d .',13,10 db ' ',13,10 db ' ²',13,10 db ' Üß ß±Ûß ßÜÜ',13,10 db ' ° ÜÜ ÜÜ ÜßÜÛÜ Û ° ',13,10 db ' ÜßÜ ÛßßÜ Û ÜÜ ÜÜÜÜÜÜ ÜÜ ÜÜÜÜ ÜÜßÜß Û ÜÛ ÜÛ ßÜ ÜÜÜÜ ',13,10 db ' ° Û ÛÛ ÜÛÛÛ ÛßÜ ÛÜßßÜÜÜ ÜÜßßßßßÜÜßÛßßÜÜÜ ÛÝ Ûß Û ÛÛÜÛÛÛÛÛß ßß ÜÜÜßÜ ° ',13,10 db ' °±±±²²Û Û²ÛÛÛ²ÛÛ ÜÛÛ ßÜÛÛÛÛÛÛ ßÛÜÜÜÛß ÜÛÛÛÛÛÛ ÛÛ ÜÛß ÛÛ ÛÛÝ ÜÛÛÛÛÛÛ Û²±°°',13,10 db ' Û Û²Ûß Û±ÛÛßÛ²Û ÜÛÛß ÛÛ ÛÛÛ ÜÛÛß ÛÛ ÛÛÛÜß ÛÛÛ ÛÛÛ ÜÛÛß ÛÛ Û ° ',13,10 db ' ± Û Û±Û ÛÛß SÛ²Û ÛÛÜÜÛß ÜÛÛÛÛÛ ÛÛÜÜÛß ÛÛÛ Ü ÛÛÛ ÛÛÛÛ ÛÛÜÜÛß ÞÝ ± ',13,10 db ' ² ßÜ ß ß aÛ±Û ßÛÛ²²±° ßÛß ßÛÛ ßÛÛÛ²²±° þßÛÛß ÛßRVßÛÛßß ßÛÛÛ²²± Û ² ',13,10 db ' ßþ--ÄÄÄÄÄCßÛÛ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ---þß ',13,10 db ' ',13,10 db ' -----=====----- ',13,10 db ' [þ] UltraEdit v5.20 - Key Generator by Quantico [þ] ',13,10 db ' -----=====----- ',13,10 db ' ',13,10,'$' IntroMsgOne db 13,10,'Enter a name : ','$' ErrorMsg db 13,10,' Need 6-21 digits, please try again...',13,10,'$' Namealtered db 18h, 19h dup(0) Nameclean db 18h, 19h dup(0) fullcode1 db 3Ch dup(2Eh) fullcode2 db 3Ch dup(2Eh) notresult db 0 datatable db 6Eh,35h,0F7h,74h,0DEh,6Fh,32h,85h,0FFh,36h,0A8h,59h,0DEh,0DEh,79h,88h namelength db 0 ShowCodeMsg db 13,10,13,10,'--=[Valid registration numbers]=-- ',13,10 db 13,10,'[CODE 1] : ' Code2Buffer db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,10 db 13,10,'[CODE 2] : ' Code1Buffer db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,10,'$' .code .startup main proc near mov ah, 09h ; lea edx, GroupLogo ; int 21h ; show group logo mov ah, 09h ; lea edx, IntroMsgOne ; int 21h ; show intro and ask for input mov bx, 1506h ; limits for string input lea edi, Namealtered ; call getstr ; read user input jc @error ; xor eax, eax ; clear eax call keygen ; create serial number mov ah, 09h ; lea dx, ShowCodeMsg ; int 21h ; print serial number jmp @exit ; finished, quit @error: mov ah, 09h lea dx, ErrorMsg ; wrong input int 21h @exit: mov al, 00h ; mov ah, 4Ch ; int 21h ; terminate program main endp keygen proc near mov eax, offset Namealtered+2 mov esi, offset Nameclean mov ebx, offset namelength movsx ebx, byte ptr [ebx] notendofname: mov cl, byte ptr [eax] mov byte ptr [esi], cl inc eax inc esi dec ebx jnz notendofname mov eax, offset namealtered+2 mov byte ptr [eax+2], 09 mov bl, byte ptr [eax+5] or bl, 55h mov byte ptr [eax+5], bl mov esi, offset fullcode1 mov ebx, offset namelength movsx ebx, byte ptr [ebx] notallcopied: mov cl, byte ptr [eax] mov byte ptr [esi], cl inc eax inc esi dec ebx jnz notallcopied mov byte ptr [esi], 00 mov esi, offset namelength movsx esi, byte ptr [esi] xor ecx, ecx xor eax, eax notalladded: add al, byte ptr [fullcode1+ecx] inc ecx cmp ecx, esi jnz notalladded not al mov byte ptr [notresult], al xor esi, esi esinot60: mov ecx, offset fullcode1 mov edx, offset notresult mov dl, byte ptr [edx] mov al, byte ptr [datatable+esi] xor al, dl inc al xor byte ptr [ecx+esi], al xor eax, eax xor edx, edx mov al, byte ptr [ecx+esi] cmp esi, 08 jge @0040BF99 ; my brain was too tired to think of ; a more interesting name to jump to ; push 1Ah ; replaced ; pop ecx xor ecx, ecx mov cl, 1Ah idiv cx add dl, 41h jmp @0040BFA1 @0040BF99: ; push 0Ah ; replaced ; pop ecx xor ecx, ecx mov cl, 0Ah idiv cx add dl, 30h @0040BFA1: mov byte ptr [fullcode2+esi], dl inc esi cmp esi, 3Ch jl esinot60 xor edx, edx xor ebx, ebx edxnot3c: mov cl, byte ptr [fullcode1+edx] lea eax, dword ptr [fullcode1+edx] cmp cl, 80h jb lessthan80 add cl, 80h mov byte ptr [eax], cl lessthan80: mov cl, byte ptr [eax] cmp cl, 7Fh jl lessthan7f sub cl, 7Fh mov byte ptr [eax], cl lessthan7f: mov cl, byte ptr [eax] cmp cl, 21h jg morethan21 add cl, 21h mov byte ptr [eax], cl morethan21: cmp byte ptr [eax], 22h jne not22 mov byte ptr [eax], 23h not22: cmp byte ptr [eax], 27h jne not27 mov byte ptr [eax], 28h not27: cmp byte ptr [eax], 2Eh jne not2e mov byte ptr [eax], 2Fh not2e: cmp byte ptr [eax], 60h jne not60 mov byte ptr [eax], 61h not60: cmp byte ptr [eax], 7Ch jne not7c mov byte ptr [eax], 6Ch not7c: inc edx cmp edx, 3Ch jl edxnot3c mov eax, offset fullcode1 mov esi, offset Code1Buffer mov ecx, 10h fillmore: mov dl, byte ptr [eax] mov byte ptr [esi], dl inc eax inc esi dec ecx jnz fillmore mov ecx, 10h mov eax, offset fullcode2 mov esi, offset Code2Buffer fillmore2: mov dl, byte ptr [eax] mov byte ptr [esi], dl inc eax inc esi dec ecx jnz fillmore2 ; THATS IT! ret keygen endp ; get string from user ; input : ; edi = pointer to buffer ; bl = min length ; bh = max length ; output : ; CF error, cx number of bytes read getstr proc near push dx ; save dx mov dx, di ; mov ah, 0Ah ; int 021h ; get user input movsx ecx, byte ptr [edi+1] ; get number of digits mov byte ptr [edi+ecx+2], 00h cmp cl, bh ; check maximum jg @@0 cmp cl, bl ; check minimum jl @@0 mov [namelength], cl ; store length xor ch, ch clc ; clear CF jmp @@1 @@0: stc ; set CF (carry flag) @@1: pop dx ; restore dx ret getstr endp end main