Multimedia Builder MP3 4.6, 4.7 & 4.8
Keygenerator Sources
Pincopall non dimentica mai =)

Data

by " Pincopall "

 

05/07/2002

UIC's Home Page

Published by Quequero


1. L'unione Fa la forza.

Facciamo cosi, te lo commento quando mi mandi la final release del keygen ok? :PPPP

2. Chi fà da se fà per tre.

3. Se ne deduce che ...

http://pincopall.cjb.net
E-mail: [email protected]
Pincopall on #crack-it #hackmaniaci #tcc ecc..

4. ...L'unione fà la forza solo se si è in più di tre, sennò fatevi le cose da soli =)

Difficoltà

Non ne avrete se conoscete l'assembler

 

Introduzione


Salve, come spero qualcuno di voi ricorderà, avevo scritto un tutorial sul MultiMedia Builder MP3 4.7, ripromettendomi poi di farci pure un keygenerator, ovviamente poi ho lasciato stare, data la mia indole pigra come poche, poi un giorno mi arriva una e-mail dove mi si chiede aiuto per la versione 4.8 di Multimedia Builder, coooosa? la 4.8? è già uscita una nuova versione? Basta..nn posso più tergiversare =)

Ecco i sorgenti commentati del keygenerator.
Per compilare il sorgente avrete bisogno del TASM 5.0 o superiore, dovete copiare il file import32.lib nella directory tasm/bin, le istruzioni di compilazione sono:

tasm32 -ml -m5 -q c:\tasm\prog\demon
tlink32 -Tpe -aa -x -c c:\tasm\bin\demon ,,, import32

Routine da Keygenerare


Vi ricordo brevemente quella che era la routine di calcolo del seriale che faceva il programma:
Allora, innanzitutto il nome deve avere una lettera, e deve contenere il carattere "@", quindi se vogliamo mettere una lettera sola questa deve essere la "@", già, come user name vuole una e-mail.
Il serial deve avere la forma 1-******-***.
La parte centrale del serial è data dal corrispondente decimale della differenza fra il numero esadecimale (fisso) 438CA e la somma dei valori esadecimali di ogni carattere ascii del nostro user name.
L'ultima parte infine è il corrispondente decimale del numero esadecimale che si ottiene sommando tra loro i valori esadecimali appunto di "1-******".
Bhè questa è la routine, vediamo come creare un semplice Keygen in asm =))

The Keygerator Source Code



.386
locals
jumps
.model flat,STDCALL

extrn GetModuleHandleA:Proc ; chiamiamo tutte le API necessarie e le 
extrn MessageBoxA:Proc      ; definiamo come procedure esterne
extrn ExitProcess:Proc
extrn CreateWindowExA:Proc
extrn RegisterClassA:Proc
extrn GetMessageA:Proc
extrn DispatchMessageA:Proc
extrn TranslateMessage:Proc
extrn PostQuitMessage:Proc
extrn DefWindowProcA:Proc
extrn CloseHandle:Proc
extrn GetWindowTextA:Proc
extrn GetProcAddress:Proc
extrn PostQuitMessage: Proc

CS_VREDRAW          EQU 0001h     ; definiamo i caratteri delle finestre
CS_HREDRAW          EQU 0002h     
CS_GLOBALCLASS      EQU 4000h     ; classe globale della finestra
COLOR_WINDOW        EQU 019h      ; colore di bakground cioè grigio
NULL                EQU 0         ; questa è molto utile ;)

MB_OK               EQU 00000000h ; vengono definite tutte le icone per 

MB_OKCANCEL         EQU 00000001h ; i messagebox
MB_ICONHAND         EQU 00000010h 
MB_ICONQUESTION     EQU 00000020h 
MB_ICONEXCLAMATION  EQU 00000030h
MB_ICONASTERISK     EQU 00000040h
CW_USEDEFAULT       EQU 8000h    ; posizione di default della finestra
WS_OVERLAPPED   EQU 000000000h   ; qui definiamo se la finestra deve
WS_THICKFRAME   EQU 000040000h   ; avere i bordi, un menu, se deve essere
WS_DLGFRAME     EQU 000400000h   ; visibile ecc...In pratica tutte le
WS_BORDER       EQU 000800000h   ; caratteristiche necessarie
WS_CAPTION      EQU 000C00000h    
WS_VISIBLE      EQU 010000000h
WS_CHILD        EQU 040000000h
WS_SYSMENU      EQU 000080000h   ; line 40

BS_DEFPUSHBUTTON EQU 0001h

WM_DESTROY      EQU 0002h        ; definiamo l'evento WM_DESTROY che viene
                                 ; chiamato da winzoz ogni volta che si chiude una finestra

WM_COMMAND      EQU 0111h        ; l'evento WM_COMMAND si verifica invece ogni volta che si preme un pulsante


; definiamo una struttura (copiato e pastato da windows.inc)

WNDCLASS struc
        clsStyle          dd ?   ; class style
        clsLpfnWndProc    dd ?
        clsCbClsExtra     dd ?
        clsCbWndExtra     dd ?
        clsHInstance      dd ?   ; instance handle
        clsHIcon          dd ?   ; class icon handle
        clsHCursor        dd ?   ; class cursor handle
        clsHbrBackground  dd ?   ; class background brush
        clsLpszMenuName   dd ?   ; menu name
        clsLpszClassName  dd ?   ; far ptr to class name  
 
WNDCLASS ends

POINT   struc             ; definiamo la struttura che ci permetterà 

    ptX             dd ?  ; di dire a winzoz le coordinate dei componenti
    ptY             dd ?  ; della finestra

POINT   ends

MSGSTRUCT struc  ; altra struttura

    msHWND          dd ?
    msMESSAGE       dd ?
    msWPARAM        dd ?
    msLPARAM        dd ?
    msTIME          dd ?
    msPT            POINT 
MSGSTRUCT ends

.data

pass            db 'uic',0 ;55h, 49h, 43h
wc              WNDCLASS 
msg             MSGSTRUCT 
AppHWnd         dd 0       ; l'handle dell'applicazione
NewHWnd         dd 0       ; l'handle della nostra finestra 
ButtonHWnd      dd 0       ; l'handle del bottone
EditHWnd        dd 0       ; l'handle dell'edit box

; da qui in poi verranno definite tutte le caption, i testi dei messagebox
; ed i nomi di tutti i pulsanti
EditClass       db "Edit",0
WindowCaption   db "Multimedia Builder MP3 v4.6, 4.7 & 4.8 Keygenerator - - Coded by Pincopall/^LocklesS^",0
WndClassName    db "Asm",0
ButtonCaption   db "Generate",0

ButtonClass     db "Button",0
classwindow     db "Asm",0

Serial          db 'This is Your Serial !! ;)',0
capt3           db 'Nooooooooooo!!!',0
error	       db 'Error!',0
noname          db 'Scrivi un nome, deve contenere "@" e deve essere di almeno una lettera!',0
senzaat         db 'Il nome deve contenere una "@"',0
kernel          db 'kernel32.dll', 0
undoc           db 'RegisterServiceProcess',0     ; funzione non documentata
serialprima     db '1-',0
HIDE	       dd      ?
NULL            EQU     0

.code

Start:
        push    0h
        call    GetModuleHandleA      ; troviamo l'handle dell'applicazione
        mov     [AppHWnd],eax         ; salviamolo in AppHWnd 
        mov     [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
        mov     [wc.clsLpfnWndProc], offset WndProc
        mov     [wc.clsCbClsExtra], 0
        mov     [wc.clsCbWndExtra], 0
        mov     eax, [AppHWnd]
        mov     [wc.clsHInstance], eax    ; l'handle dell'applicazione
        mov     [wc.clsHbrBackground], COLOR_WINDOW + 1
        mov     dword ptr [wc.clsLpszMenuName], 0  ; non vogliamo menu
        mov     dword ptr [wc.clsLpszClassName], offset WndClassName
        push    offset wc                 ; offset della classe appena riempita
        call    RegisterClassA            ; registrala
        
        ; Creiamo la finestra
        push    0                      ; lpParam
        push    [AppHWnd]              ; hInstance
        push    0                      ; menu
        push    0                      ; parent hwnd
        push    160                    ; altezza
        push    600                    ; larghezza
        push    CW_USEDEFAULT          ; coordinata y 
        push    CW_USEDEFAULT          ; coordinata x
        push    WS_OVERLAPPED OR WS_DLGFRAME OR WS_SYSMENU OR WS_VISIBLE; Stili
        push    offset WindowCaption   ; Titolo della finestra
        push    offset WndClassName    ; Nome della classe
        push    0                      ; stili extra = no
        call    CreateWindowExA        ; creiamo la finestra
        mov     [NewHWnd], eax

        

        
        
        

        ; Creiamo il  pulsante "Generate"
        push    0                      ; lpParam
        push    [AppHWnd]              ; hInstance
        push    20h                    ; ID del bottone
        push    [NewHWnd]              ; parent hwnd
        push    30                     
        push    170                    
        push    20                     ; y
        push    215                    ; x
        push    WS_BORDER OR WS_VISIBLE OR WS_CHILD 
        push    offset ButtonCaption 
        push    offset ButtonClass     
        push    0                      
        call    CreateWindowExA
        mov     [ButtonHWnd], eax
     
        

; Creiamo l'edit Box
        push    0                      ; lpParam
        push    [AppHWnd]              ; hInstance
        push    40h                    ; ID dell'edit
        push    [NewHWnd]              ; parent hwnd
  	  push    20                    
        push    360             
        push    80                     ; y
        push    120                    ; x
        push    WS_BORDER OR WS_VISIBLE OR WS_CHILD 
	  push    0
        push    offset EditClass     
        push    0                     
        call    CreateWindowExA
        mov     [EditHWnd], eax




        
      

msg_loop:                        ; questo loop consente di far

        push    0                ; "vivere" la nostra finestra
        push    0                ; in pratica la "tiene su" e non
        push    0                ; la fa sparire, nel modificare 
        push    offset msg       ; questo codice fate sempre tornare
        call    GetMessageA      ; il controllo qui invece di far
        cmp     ax, 0            ; terminare una chiamata con
        je      end_loop         ; call ExitProcess oki?
        push    offset msg
        call    TranslateMessage
        push    offset msg
        call    DispatchMessageA
        jmp     msg_loop
end_loop:
        
        ;push    AppHWnd
        ;CALL    CloseHandle      
        push    NULL
        call    ExitProcess

;=================================================================================
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
cmp     [wmsg], WM_DESTROY  ; si è verificato l'evento WM_DESTROY?
je      wmdestroy           ; se si salta alla relativa routine
cmp     [wmsg], WM_COMMAND  ; si è verificato l'evento WM_COMMAND?
je      wmcommand           ; se si salta alla relativa routine
push    [lparam]            ; salviamo tutti i vari parametri
push    [wparam]
push    [wmsg]
push    [hwnd]
call    DefWindowProcA      ; questa funzione assicura che sia processato
ret                         ; il messaggio

wmdestroy:
push    0
call    PostQuitMessage     ; la funzione PostQuitMessage indica a winzoz
mov     eax, 0              ; che un processo ha chiesto di essere terminato 
ret
 
wmcommand:
        cmp     [wparam],20h    ; Il primo pulsante è stato premuto?
        jne     fine            ; No? Continua il check con gli altri pulsanti, ma non ce ne sono=)
        jmp     CalcolaSeriale       ; si? Salta all'apposita routine  
      
fine:
        xor     eax,eax        ; azzera eax        
        ret
WndProc endp
;=================================================================================

CalcolaSeriale      proc  
      push 50			; max caratteri	
      push ebx     		; buffer d testo	
      push [EditHWnd] 		; handle dell'edit
      Call GetWindowTextA
      
      cmp eax, 1   ; il nome ha almeno una lettera?
      jl nonvabene ; no? allora non va bene
      xor edi, edi ; azzera edi
      mov edi, eax ; mettici dentro il numero di caratteri del nome, che dopo la chiamata a
	          ; getwindowtexta stà sempre in eax  
      xor eax,eax  ; azzera eax
      xor ecx,ecx  ; ed anche ecx che useremo come contatore
ciclo1:      mov al, byte ptr[ebx+ecx]  ; si parte con il primo ciclo in cui controlleremo se
			  	   ; almeno uno dei caratteri è "@",ovvero ha valore
				   ; decimale pari a 64.
				   ; Cominciamo allora mettendo in al il 1° carattere
             inc ecx         ; incrementiamo il contatore
      	    cmp al,64       ; il carattere è "@"?             
	    je metteunsegno ; se si gli facciamo mettere una specie di segno
             jmp senzasegno  ; altrimenti non glielo facciamo mettere e lo facciamo saltare 		
metteunsegno:
        mov ah,10 ; il nostro segnale se almeno uno dei char è @ sarò ah=10
senzasegno:
        cmp ecx,edi ; quì controlla se i caratteri del nome sono finiti, se nn lo sono...
        jle ciclo1  ; ricomincia il ciclo di controllo
        cmp ah,10   ; quì controlla se ah=10, ovvero se abbiamo rovato,alla fine del nostro 
		  ; ciclo,almeno un carattere del nome che sia la @
        jne civuolelachiocciola ; e se la chiocciolina non c'è, avvisiamo il nostro utente=)
        		              ; che la suddetta è necessaria =)
        xor ecx,ecx	     ; riazzeriamo sia ecx che eax che edx
        xor eax,eax
        xor edx,edx
ciclo2:         mov al, byte ptr[ebx+ecx] ; ed arriviamo al secondo ciclo dove, riusando ecx
					  ; come contatore, sommeremo i valori decimali
	add edx,eax		  ; di ogni carattere del nostro nome, facendo finire
         inc ecx		           ; la somma in edx,
	cmp ecx,edi		  ; ovviamente il ciclo cesserà quando ecx sarà uguale
	jle ciclo2		  ; al numero dei caratteri.
	mov eax,276682       ; muoviamo ora in eax il numero hex 438CA
         sub eax,edx	   ; da cui sottraiamo poi la somma precedentemente ottenuta.
	
call daEsaInDec        ; questa differenza ottenuta va ora portata in base dieci, per chi avesse
		     ; già letto il mio tutorial sul keygenerator di Engenius 4.0.1, vi avviso
		     ; che questa routine sarà diversa da quella sviluppata in quel tutorial,
		     ; perkè là il numero da portare in base dieci era di 2 cifre, quà il numero
		     ; è ben più grande, ma vederte che non varierà un granchè =).

	mov esi,offset serialprima ; muoviamo in esi la stringa "1-"
	mov eax,[ebp]              ; poi tramite eax mettiamo in esi+2
	mov [esi+2],eax	         ; la 2a parte del serial,che sarà di 6 cifre, quindi
	mov ax,[ebp+4]             ; ci costerà due passaggi, una volta occupando un dword (eax)
	mov [esi+6],ax		; ed un'altra una word (ax).
	mov [esi+8],45		; Il nono carattere deve essere "-".
call ultimaParte                 ; Con questa call ci calcoliamo ora la ultima parte del serial
call daEsaInDec			   ; e con questa la portiamo in base dieci.
	mov eax,[ebp]		   ; Come prima, tramite eax portiamo la ultima parte	
	mov [esi+9],eax		   ; del serial in esi+9
	mov byte ptr[esi+12],00	   ; e disponiamo che il 13esimo carattere sia "null", ovvero diciamo al keygenerator di fermarsi ad esi+11 compreso nel
				   ; prendere i caratteri che poi visualizzeremo nella msg box
				   ; del serial.	
push MB_OK OR MB_ICONEXCLAMATION   ; Message Box che andremo subito a creare =)
push offset Serial
push offset esi
push NULL
Call MessageBoxA
jmp  msg_loop
CalcolaSeriale endp
;===========================================================================

; Bhè abbiamo quì la creazione delle due message box di errore, che compaiono ovviamente a
; seconda dell'errore =).

nonvabene:
push MB_OK OR MB_ICONEXCLAMATION
push offset error	
push offset noname
push NULL
Call MessageBoxA
jmp msg_loop

civuolelachiocciola:
push MB_OK OR MB_ICONEXCLAMATION
push offset error	
push offset senzaat
push NULL
Call MessageBoxA
jmp msg_loop

daEsaInDec proc    ; ecco la call che porta da esadecimale in decimale il nostro numero
	push eax   ; pushiamo i registri il cui attuale valore ci servirà anche dopo
	push edx
	push ecx
	mov ecx, 10       ; e muoviamo in ecx 10 (0Ah)
	mov [ebp],eax     ; ed in ebp, il valore di eax, che è poi il numero da mettere in dec.
ciclo3:
	xor edx, edx        ; azzeriamo edx
	div ecx		  ; e dividiamo eax per ecx, con il quoziente che và a finire in eax ed
			  ; il resto che và a finire in edx
	add dl, 48	  ; resto a cui aggiungiamo 48 ( 30h ), e se avete a disposizione una	
			  ; tavola ascii capite il perchè =)
	cmp dl, 58          ; e che poi confrontiamo con 58, ovvero con il valore decimale del primo 
			  ; carattere nn numerico nell'ordine delle tabelle ascii ovviamente.
	jb decrementaEbp    ; Se più piccolo si salta
	add dl, 07	  ; altrimenti se è più grande gli si aggiunge un 07. 
decrementaEbp:
	dec ebp		  ; Decrementiamo ebp
	mov [ebp],dl	  ; ed in ebp decrementato si mette il numero ottenuto.
	or eax, eax         ; Se eax non è ancora zero
         jne ciclo3          ; si ricomincia il ciclo.
	pop ecx             ; Alla fine si poppa tutto stando attenti alla regola del LIFO
	pop edx		  ; (Last In First Out) per quanto riguarda lo stack...
	pop eax
	ret		  ; e si ritorna =)
daEsaInDec endp

ultimaParte proc	; Questa è la call con cui calcoliamo l'ultima parte del serial

push ebp		; Questi sono gli unici due registri di cui ci interessa conservare
push esi		; il valore attuale,
xor ecx, ecx		; gli altri azzeriamoli tranquillamente =)
xor eax, eax
xor ebx, ebx
ciclo4:			 ; evvia con l'ultimo ciclo
	
	mov bl,[esi+ecx]   ; usiamo ecx come contatore ( eggià è un vizio :P ), mettiamo in bl
			 ; il valore hex della cifra nesima della parte iniziale e della 
			 ; parte centrale del serial.
	inc ecx		 ; Incrementiamo ecx.

	add eax,ebx        ; E sommiamo di volta in volta i valori esadecimali.
	cmp ecx,7	 	 ; Finchè non arriviamo a sommare l'ottavo carattere, infatti poi
	jle ciclo4	 ; il ciclo finisce =)
pop esi
pop ebx
ret
ultimaParte endp	; cosiccome la chiamata


End Start		; ed il programma =))

;Saludos,
;Pincopall =)


Note finali


Spero abiiate capito tutto per benino, nel caso nono ci aveste capito niente..rileggetelo =)

Oggi Dediche tutti al femminile:

adelayde, che lavora sempre pooooooovera, (povera? ma se manco il veleno per i topi la uccide, ha l'immortalita' e tu la chiami povera? TSK :P NdQue)
Bluetta, di cui tutti su #hackmaniaci e non solo bramano le foto che jeyone custodisce gelosamente (egoist..egoist..:PP) (Quequero frega le mani con aria sospetta :P NdQue)
Raffaella, che mi all'hm mi occupava il pc sempre occupato per chattare!!

Ebbè non può mancare un saluto a Cup..erm Andreageddon =), Quequero, +Xoanon, unics, Guzura (ma che bella maglietta che avevi all'hm :P), Xanthic, JEYoNE, lesion, reef, +Malattia, LittleJohn, TheMr, BigAlex, inquis, Quake2^AM, Berserk, GiPoco, Ra1n, beb0s, C1CC10 ed a tutti gli altri che ho conosciuto all'ultimo hackmeeting...miiiii siete trooooppi da mettere tutti =)

Infine un grazie a Luc, l'autore della mail che mi ha fatto ripensare alla promessa di fare un keygen per multimedia Builder che mi ero fatto un po' di tempo fà =).
Ciauz

Disclaimer

Vorrei ricordare che questo software vaà comprato e non rubato e o crakkato capito?
Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e NON a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.

Capitoooooooo????? Bhè credo di si ;))))