;**************************************************************************************************** ;Description: ;Input: NameBuffer ;Output: ClrNameBuffer, HashString ;A depth analysis: ;1) In HashString it appends the NameBuffer without space chars at the head, also the space chars in ; the 'middle' are substituted by ONE space char; ;2) In ClrNameBuffer it puts the string appended at the end of HashString without digit chars; ;**************************************************************************************************** _CleanName: xor esi,esi ; i use esi as index of NameBuffer xor edi,edi ; i use edi as index of HashString xor ebx,ebx ; ebx is a simply flag used to recognize space chars at the begin of NameBuffer xor ecx,ecx ; ecx is a index of ClrNameBuffer _Loop: mov al,[NameBuffer + esi] ; al = current Char of NameBuffer test al,al ; if al == 0, we arrive at the end of NameBuffer je _EndProc push eax call _CheckRange1 ; if al == ' ', ... test al,al pop eax je _Next inc esi mov ebx,1 ; ... i sets ebx and repeat the _loop until al <> ' ' jmp _Loop _Next: ; we arrive here after the loop test edi,edi ; test edi; if edi == 0, -> we are at the beginning of the scan and we don't insert... jz @f ; ...' ' char in the HashStrings test ebx,ebx ; test ebx; if ebx == 1 and edi > 0 we are in the middle of NameBuffer... jz @f mov [HashString + 40h + edi],20h ; ... then, we must put only ONE space char in a [HashString + 40h] inc edi @@: mov [HashString + 40h + edi],al ; also, we insert the next char pointed by esi in HashString push eax call _IsDigitChar test al,al pop eax jnz _Leave @@: mov [ClrNameBuffer + ecx],al ; here, we put the current char in ClrNameBuffer if it's not a digit inc ecx _Leave: inc edi inc esi xor ebx,ebx ; reset the flag, so we are ready to recognise the next sequence of ' ' chars jmp _Loop _EndProc: mov [HashString + 40h + edi],0 mov [ClrNameBuffer + ecx],0 ret ;**************************************************************************************************** ;Description: ;Input: esi, eax ;Output: eax ;A depth analysis: ;1) esi, the first parameter, has a UPPARCASE char; ;2) eax, the second parameter, is a DWORD value; its bits are used to know the 2' powers by multiply. ; If a j-esim bit is setted, esi is multiplied by 2^j; ;3) eax, as result of this proc, stores: esi * ( 2^i xor 2^j xor ... ) ( Galois multiplication ). ;**************************************************************************************************** _Galois: push edi push ecx xor edi,edi ;edi == temp value; mov ecx,20h ;init ecx, ecx is a bit counter of a dword stored in eax; @@: dec ecx js _GaloisEnd ;if ecx < 0, i jump to the end; shl eax,1 ;here i test if the most bit, stored in carry flag,... jnc @b ;... are setted; if no,i repeat the loop; push esi ; save esi on the stack; shl esi,cl xor edi,esi ;Galois Multiplication... pop esi ;i restore the original value of esi ( the first parameter); jmp @b _GaloisEnd: mov eax,edi ;At the end, i return the temp value in eax; pop ecx pop edi ret ;**************************************************************************************************** ;Description: ;Input: al; ;Output: 1 or 0 in eax; ;A depth Analysis: ;1) al, as paramater, is a simply ASCII coded byte; ;2) eax, as the return value, is a BOOlEAN; if eax = 1, then 09h < ASCII byte < 0Dh ; or ASCII byte = space char; in the other case eax = 0; ;**************************************************************************************************** _CheckRange1: cmp al,09h jl @f cmp al,0Dh ja @f mov eax,1 ret @@: cmp al,20h ; NO COMMENT .... ;) ; jnz @f mov eax,1 ret @@: xor eax,eax ret ;**************************************************************************************************** ;Description: ;Input: al; ;Output: 1 or 0 in eax; ;A depth Analysis: ;1) al, as paramater, is a simply ASCII coded byte; ;2) if ASCII coded byte is a literal ( in uppercase or downcase), then EAX = 1 else 0; ;**************************************************************************************************** _CheckRange2: cmp al,61h jl @f cmp al,7Ah ja @f mov eax,1 ret @@: cmp al,41h ;Very simple to understand.... ; jl @f cmp al,5Ah ja @f mov eax,1 ret @@: xor eax,eax ret ;**************************************************************************************************** ;Description: ;Input: al; ;Output: 1 or 0 in eax; ;A depth Analysis: ;1) al, as paramater, is a simply ASCII coded byte; ;2) if ASCII coded byte is a digit, then EAX = 1 else 0; ;**************************************************************************************************** _IsDigitChar: cmp al,30h jl @f cmp al,39h ja @f ; See above .... ;) ; mov eax,1 ret @@: xor eax,eax ret ;**************************************************************************************************** ;Description: ;Input: al; ;Output: al; ;A depth Analysis: ;1) al, as paramater, is a simply ASCII coded byte; ;2) if ASCII coded byte is a downcase literal, this proc converts it in uppercase and return in eax ;**************************************************************************************************** _UppercaseChar: cmp al,61h jl @f cmp al,7Ah ja @f add al,0E0h @@: ret ;**************************************************************************************************** ;Description: ;Input: edx; ;Output: eax; ;A depth Analysis: ;1) edx, as parameter, is the offset of the String; ;2) eax is the Lengh of String; ;**************************************************************************************************** _StringLengh: push esi xor eax,eax ;eax stores the chars of a String; xor esi,esi ; esi is the counter of StringLengh; @@: mov al,[edx + esi] ;al == current char of StringLengh; inc esi ;esi = esi + 1; test al,al jnz @b ;i repeat the loop until al == 0 ( end of String ); dec esi mov eax,esi ;eax stores the counter pop esi ret ;**************************************************************************************************** ;Description: ;Input: ebx,edx,ecx; ;Output: eax; ;A depth Analysis: ;1) edx, as parameter, stores the Init Value; ; ebx, as paramenter, is the offset of a String; ; ecx, as parameter, is 0 or 1 or 2; i use it to select a different hash calculation ;2) eax, as result of this proc, is the Hash index; ;**************************************************************************************************** _HashIndex: push esi push edi ;i save esi edi on the stack; xor edi,edi ;init edi; edi is the index of string buffer; _HashIndexLoop: mov al,[ebx + edi] ;al = current ascii coded byte of String buffer; test al,al ;if we arrive at the end of the String,... jz _HashIndexEnd ;...we jump! call _UppercaseChar ;we begin the hash calc... movzx esi,al mov eax,[GaloisDwords + 4*ecx] ;by ecx, i select a different Dword to calculate a Hash value! call _Galois or ecx,ecx jne _HashIndexs23 ;HashIndex1 xor eax,edx mov edx,eax shl eax,1 shr edx,1fh test edx,edx jz @f or eax,1 @@: mov edx,eax inc edi jmp _HashIndexLoop _HashIndexs23: cmp ecx,1 je _HashIndex2 ;HashIndex3 imul edx,13h add edx,eax inc edi jmp _HashIndexLoop _HashIndex2: imul edx,25h add edx,eax inc edi jmp _HashIndexLoop _HashIndexEnd: mov eax,edx pop esi pop edi ret ;**************************************************************************************************** ;Description: ;Input: ecx,eax ;Output: eax ;A depth analysis: ;1) ecx, the first parameter, is a simply counter; ;2) eax, the second parameter, is a String's offset ;3) eax, as result of this proc, stores the Hash value that depends by CDATA.bin file ;**************************************************************************************************** _CDATAHash: push edx ;well... i simply rip the original code... ;) push edi push esi push ebx xor edi,edi mov edx,eax or esi,0ffffffffh @@: mov ebx,esi shr ebx,8 mov al,[edx + edi] call _UppercaseChar and eax,0ffh and esi,0ffh xor eax,esi mov esi,dword [CDATA + 4*eax] xor esi,ebx inc edi dec ecx jnz @b not esi mov eax,esi ;EAX = final result; pop ebx pop esi pop edi pop edx ret ;**************************************************************************************************** ;Description: ;Input: cl,edx ;Output: edx ;A depth analysis: ;1) cl, the first parameter, is a simply UPPERCASE char; ;2) edx, the second parameter, is a String's offset; ;3) edx, as result of this proc, stores the even position that char has in the String; ;**************************************************************************************************** _EvenIndex: push eax xor eax,eax @@: cmp byte [edx],cl je _EvenIndexEnd add edx,2 inc eax jmp @b _EvenIndexEnd: mov edx,eax pop eax ret ;**************************************************************************************************** ;Description: ;Input: SerialBuffer,HashString ;Output: eax ;A depth analysis: ; This proc generates a CRCHash from SerialBuffer[15h:10h] and stores the DWORD in eax ;**************************************************************************************************** _CRCHash: xor esi,esi ;esi is a counter; its step is 4 units; xor eax,eax ;eax is the temp register; mov edi,10h ;edi is the index of Serial Buffer; @@: mov cl,[SerialBuffer + edi] mov edx,HashString call _EvenIndex mov ecx,esi add esi,4 shl edx,cl or eax,edx inc edi cmp esi,18h jb @b mov ecx,6 mov edx,987AC16Bh @@: mov esi,edx ;save edx in esi; shl esi,5 sub esi,edx ;esi == edx * 1Fh; mov edx,eax ;save eax in edx; and edx,0Fh ;take the last nibble of edx; xor edx,esi ;edx = {esi[31:04],(dl xor esi[3:0])}; shr eax,4 ;after the last calc., the first nibble of eax is superflous; dec ecx jnz @b mov eax,edx ret ;**************************************************************************************************** ;Description: ;Input: SerialBuffer,HashString ;Output: SerialBuffer[15h:10h] ;A depth analysis: ; This proc generates a pseudorandom chars stored in SerialBuffer[15h:10h]; ;**************************************************************************************************** _InitSerialBuffer: mov ecx,6 ;ecx is a counter's loop; mov esi,10h ;esi is the SerialBuffer's index; xor eax,eax ;eax is the index of HashString; invoke GetTickCount and eax,1Fh shl eax,1 @@: xor edx,edx ;i use edx as data store; mov dl,byte [HashString + eax] mov [SerialBuffer + esi],dl add eax,2 and eax,1Fh inc esi dec ecx jnz @b ret ;**************************************************************************************************** ; MAIN PROCEDURE ;**************************************************************************************************** _Generate: call _CleanName ;i set SerialBuffer[15h:10h]; call _InitSerialBuffer ;i calculate the SerialBuffer[18h:16h]; call _CRCHash xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 16h],cl mov edx,eax shr edx,5 and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 17h],cl shr eax,0Ah and eax,1Fh mov cl,[HashString + 2*eax] mov [SerialBuffer + 18h],cl ;i calculate the SerialBuffer[08h] and SerialBuffer[0Eh]; xor ecx,ecx mov edx,[InitDwords + 4*ecx] mov ebx,ClrNameBuffer call _HashIndex xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 08h],cl shr eax,5 and eax,1Fh mov cl,[HashString + 2*eax] mov [SerialBuffer +0Eh],cl ;i calculate the SerialBuffer[0Fh],SerialBuffer[0Bh] and SerialBuffer[03h]; mov ecx,1 mov edx,[InitDwords + 4*ecx] mov ebx,ClrNameBuffer call _HashIndex xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 0Fh],cl mov edx,eax shr edx,5 and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 0Bh],cl shr eax,0Ah and eax,1Fh mov cl,[HashString + 2*eax] mov [SerialBuffer + 03h],cl ;i calculate the SerialBuffer[09h],SerialBuffer[01h],SerialBuffer[0Ah] and SerialBuffer[0Ch]; mov ecx,2 mov edx,[InitDwords + 4*ecx] mov ebx,ClrNameBuffer call _HashIndex xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 09h],cl mov edx,eax shr edx,5 and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 01h],cl mov edx,eax shr edx,0Ah and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 0Ah],cl shr eax,0Fh and eax,1Fh mov cl,[HashString + 2*eax] mov [SerialBuffer + 0Ch],cl ;i calculate the SerialBuffer[00h],SerialBuffer[04h],SerialBuffer[06h],SerialBuffer[02h], ; SerialBuffer[07h],SerialBuffer[0Dh] and SerialBuffer[05h]; mov edx,ClrNameBuffer call _StringLengh mov ecx,eax mov eax,ClrNameBuffer call _CDATAHash xor eax,0A29DC94Dh xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer],cl mov edx,eax shr edx,5 and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 04h],cl mov edx,eax shr edx,0Ah and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 06h],cl mov edx,eax shr edx,0Fh and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 02h],cl mov edx,eax shr edx,14h and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 07h],cl mov edx,eax shr edx,19h and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 0Dh],cl shr eax,1Eh mov cl,[HashString + 2*eax] mov [SerialBuffer + 05h],cl ;i finally calculate the SerialBuffer[1Dh:19h]; mov ecx,19h mov eax,SerialBuffer call _CDATAHash xor eax,1982D18Ch xor ecx,ecx mov edx,eax and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 19h],cl mov edx,eax shr edx,5 and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 1Ah],cl mov edx,eax shr edx,0Ah and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 1Bh],cl mov edx,eax shr edx,0Fh and edx,1Fh mov cl,[HashString + 2*edx] mov [SerialBuffer + 1Ch],cl shr eax,14h and eax,1Fh mov cl,[HashString + 2*eax] mov [SerialBuffer + 1Dh],cl mov [SerialBuffer + 1Eh],0 retn