.model tiny .386 org 100h .data GroupLogo DB ' EmailWolf Pro v1.00 *keygen* ',10,13 DB 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ| QUANTICO! |ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',10,13 DB ' ÜÜÜ ÜÜÜ ÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜ ',10,13 DB ' ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛÜÜÜ ',10,13 DB ' ÛÛÛÜ ÛÛÛ ÛÛÛÜ ÛÛÛ ',10,13 DB ' ßßßßßßßßß ßßßßßßßßß ßßß ',10,13 DB 'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ',10,13 DB 'u N I T E D c R A C K I N G f O R C E ',10,13 DB '[wIN95/NT]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Sep 1998]',10,13 db ' ',13,10,'$' IntroMsgOne db 13,10,' [þ] EmailWolf Pro v1.00 - Key Generator by Quantico [þ]',13,10 db '',13,10 db 13,10,' Enter a name : ','$' IntroMsgTwo db 13,10,' Enter a company : ','$' ErrorMsg db 13,10,' Need 5-20 digits, try again...',13,10,'$' ShowCodeMsg db 13,10,' Registration number : EP-' CodeBuffer db 10h dup(0),13,10,'$' NameBuffer db 18h, 50h dup(0) Name4 db 4 dup(0),0h Convert_Digs db '0123456789ABCDEF' EP db 'EP',00h namelength db 0 .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, 1405h ; limits for string input lea edi, NameBuffer ; mov esi, offset namelength 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 int 21h @exit: mov al, 00h ; mov ah, 4Ch ; int 21h ; terminate program main endp keygen proc near mov esi, offset [NameBuffer+2] mov edi, offset [Name4] mov ecx, 04 rep movsb mov esi, offset EP @00410DB1: xor ecx, ecx mov dl, byte ptr [esi] add dl, 0Bh back5lines: mov al, byte ptr [Name4+ecx] imul dl mov byte ptr [Name4+ecx], al inc ecx cmp ecx, 04 jl back5lines mov dl, byte ptr [esi+1] inc esi test dl, dl jne @00410DB1 mov edi, offset NameBuffer+2 mov cl, byte ptr [edi] test cl, cl je @00410DED mov edx, edi @00410DD6: xor eax, eax add cl, 0Bh @00410DDB: xor byte ptr [Name4+eax], cl inc eax cmp eax, 04 jl @00410DDB mov cl, byte ptr [edx+1] inc edx test cl, cl jne @00410DD6 @00410DED: mov edx, dword ptr [Name4] test edx, edx jge @00410DF9 neg edx test edx, edx @00410DF9: jne @00410E00 mov edx, 01 @00410E00: cmp edx, 270Fh jge @00410E15 @00410E08: lea edx, dword ptr [edx+4*edx] shl edx, 1 cmp edx, 270Fh jl @00410E08 @00410E15: cmp edx, 0F423Fh jle correct @00410E1D: mov eax, 66666667h imul edx sar edx, 02 mov eax, edx shr eax, 1Fh add edx, eax cmp edx, 0F423Fh jg @00410E1D correct: mov eax, edx mov edi, offset CodeBuffer mov ecx, 0Ah xor edx, edx call Convert_Num 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 byte ptr [esi], 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 Convert_Num proc near pushf pushAD sub esp, 4 mov ebp,esp cld mov esi, edi push esi ;--- loop for each digit sub bh, bh mov dword ptr [ebp], eax ;save low word mov dword ptr [ebp+4], edx ;save high word sub esi, esi ;count digits Connum1: inc esi mov eax, dword ptr [ebp+4] ;high word of value sub edx, edx ;clear for divide sub ebx, ebx div ecx ;divide, DX gets remainder mov dword ptr [ebp+4],eax ;save quotient (new high word) mov eax, dword ptr [ebp] ;low word of value div ecx ;divide, DX gets remainder ; (the digit) mov dword ptr [ebp], eax ;save quotient (new low word) mov bl, dl mov al, byte ptr [Convert_Digs+ebx] ;get the digit stosb ;store cmp dword ptr [ebp], 0 ;check if low word zero jne Connum1 ;jump if not cmp dword ptr [ebp+4], 0 ;check if high word zero jne Connum1 ;jump if not sub al, al stosb ;store the terminator ;--- reverse digits pop ecx ;restore start of string xchg ecx, esi shr ecx, 1 ;number of reverses jz Connum3 ;jump if none xchg edi, esi sub esi, 2 ;point to last digit Connum2 : mov al, byte ptr [edi] ;load front character xchg al, byte ptr [esi] ;swap with end character stosb ;store new front character dec esi ;back up loopd Connum2 ;loop back for each digit ;--- finished Connum3 : add esp, 4 popad popf ret endp ;Convert_Num ; concatenate 2 strings ; input : ; esi = string one, ecx = length string one ; edi = string two, edx = length string two ; output : ; esi = string one + string two, edx = new length cncstr proc near xor eax, eax ; xor ebp, ebp ; clear register push esi ; save esi add esi, ecx ; set esi at end of string one add ecx, edx ; adjust new length @cnc: mov al, byte ptr [edi + ebp] ; get digit of string two mov byte ptr [esi + ebp], al ; place digit after string one inc ebp ; dec edx ; jnz @cnc ; loop for length of string two pop esi ; restore esi mov byte ptr [esi - 1], cl ; update new length ret cncstr endp ; returns ECX= length of String in DS:ESI - terminated by CHAR in AL ; registers changed: ECX ; Assumes ES=DS strlngth PROC pushf push edi push esi push edx mov edi,esi xor ecx,ecx dec ecx cld repnz scasb xor edx,edx sub edx,ecx dec edx mov ecx,edx pop edx pop esi pop edi popf Ret strlngth endp end main