Fractal eXtreme 1.60b | ||
Data |
by "ZedTec" |
|
29/02/2001 |
Published by Quequero | |
|
Il programma non era difficile da crackare ma devo riconoscere che l'idea di usare HLA per il keygen è stata davvero una bella pensata, bravo zed :) |
|
.... |
E-mail: [email protected] |
.... |
Difficoltà |
(*)NewBies ( )Intermedio ( )Avanzato ( )Master |
Troveremo tramite un minimo uso di SIce il seriale giusto e creeremo con HLA un piccolo key-maker.
Introduzione |
Tools usati |
URL |
Notizie sul programma |
Essay |
Calcolare la lunghezza di una stringa immessa
(preso da: Basic Tutorials on Key Generation and Key File Routines by Dr.ME! liberamente tradotto da me)
xxxx:00406587 mov ecx, FFFFFFFF
N.B. Ogni volta che vedrai il
valore FFFFFFFF spostato in ecx,
quasi sicuramente ti troverai all'inizio di una routine che determinerà
la lunghezza di stringhe o numeri.
xxxx:0040658C sub eax, eax xxxx:0040658E repnz ; ripeti affinchè 0 xxxx:0040658F scasb ; confronta AL con il byte a ES:DI ; e setta il flag. ; Questa è una istruzione comune ; per quanto riguarda il calcolo ; della lunghezza della stringa xxxx:00406590 not ecx ; ecx = lunghezza stringa + 1 xxxx:00406592 dec ecx ; lunghezza stringa xxxx:00406593 je 004066A4 ; se ecx=0 salta a 4066A4 ; altrimenti continua
Questo codice calcola il numero dei caratteri da noi immessi; il risultato sarà 'salvato' in ECX.
FRACTAL eXtreme 1.60b (by ZedTec)
...aprendo il programma noteremo con
finto stupore un nag che ci ricorda che non siamo registrati...
Andiamo ora a vedere come funziona la registrazione.
Innanzitutto, bisogna compilare una form (da Help ---> Purchase Fractal eXtreme
---> I Accept) con i nostri dati; Dopo come tipo di pagamento scegliete Check(By
Mail Only) ossia di volere comprare il prodotto tramite posta.(oppure, se avete
pazienza scegliete una carta di credito e riempite gli appositi spazi)
A questo punto dopo aver cliccato su DONE, il prog creerà il file rsagent.ini
nella directory c:\windows.
Se aprite il file con un editor di testo (tipo notepad) vedrete che contiene
tutte le informazioni da noi inserite più il nostro codice personale.
Qui il codice può essere cambiato a nostro piacimento(!), infatti il
prog al momento della registrazione non verificherà se questo corrisponde
ai dati inseriti prima.
Ora torniamo al prog e andiamo a registrarlo (HELP ---> PURCHASE FRACTAL
EXTREME) apparirà una form con i dati del nome, cognome immessi prima,
il codice personale e la spazio appunto, per inserire il codice.
* fondamentale
*
Inserite un seriale di 10 (dieci) caratteri e date O.K.
bpx getdlgitemtexta
... ora uscite da SIce (X e invio
oppure F5) e premete su OK (sempre con il falso codice seriale da 10 cifre
inserito) entreremo in SIce, premiamo F11 per tornare all'istruzione chiamante
e vediamo che siamo dentro la DLL RSAGNT32.
(per meglio dire, il debugger è entrato in funzione nella parte di
codice per la generazione del seriale, contenuto appunto nella DLL)
Noteremo la routine per la lunghezza della stringa.
call EBP ---> mov ECX, FFFFFFFF ---> sub EAX, EAX ---> ROUTINE CALCOLO repnz scasb ---> LUNGHEZZA STRINGA not ECX ---> dec ECX ---> cmp ECX, 0A ---> qui controlla che il seriale immesso da noi sia ---> di 10 cifre (Ah = 10 decimale) jz 10029460 ---> se = 10 cifre salta altrimenti continua ... mov EDI, 10029460 ---> copia il codice personale in EDI mov ECX, FFFFFFFF sub EAX, EAX REPNZ SCASB not ECX sub EDI, ECX mov EAX, ECX shr ECX, 02 mov ESI, EDI ---> copia il codice personale in ESI lea EDI, [ESP+000000D8] REPZ MOVSD mov ECX, EAX and ECX, 03 REPZ MOVSB lea ECX, [ESP+0000010C] ---> * sposta il seriale giusto in ECX!! * mov EAX, 1002EA34 push ECX
basterà steppare (F10) fino all'istruzione successiva e digitare
d ecx (invio)
per vedere il contenuto di ecx, ossia il seriale.
Questo è possibile solamente
se prima avete eseguito il punto * fondamentale *
altrimenti il seriale giusto non verrà generato.
La generazione del seriale avviene nelle istruzioni successive.
add EAX, B6 lea ECX, [ESP+000000DC] push EAX ---> immette la stringa per generare il seriale ---> Gy549nmwF2 (contenuta nell'eseguibile) push ECX call 1004CB0 ---> chiamata alla routine che genera il seriale lea ecx, [esp+00000118] add ESP, 0C push 1002F630 ---> seriale inserito da noi push ECX ---> seriale giusto
Andiamo a vedere in che modo viene
generato il seriale.
Arrivati con F10 sopra alla call, premiamo F8 ovvero step into (salta dentro).
(nel caso vi appaiano tutte scritte INVALID, premete di nuovo F8)
Il codice per la generazione del seriale è il seguente (preso con W32dasm):
CALL at Addresses:
|:10001FAB , :100046D4
|
:10004CB0 sub esp, 00000018
* StringData Ref ->"PQYZMERUOA" | :10004CB3 mov ecx, 10021D78 ---> copia in ECX la stringa PQYZMERUOA :10004CB8 lea edx, dword ptr [esp] :10004CBC push ebx :10004CBD push esi :10004CBE mov eax, dword ptr [ecx] ---> copia in EAX 4 byte (caratteri) di ECX :10004CC0 push edi :10004CC1 mov ebx, dword ptr [ecx+04] ---> copia in EBX 4 byte dal quarto ---> byte di ECX :10004CC4 push ebp :10004CC5 mov dword ptr [edx], eax ---> copia in EDX 4 byte di EAX :10004CC7 mov bp, word ptr [ecx+08] ---> copia in BP il valore dall'ottavo ---> byte di ECX :10004CCB mov al, byte ptr [ecx+0A]
* StringData Ref ->"JIKLICBXZC" | :10004CCE mov ecx, 10021D6C ---> copia in ECX la stringa JIKLICBXZC :10004CD3 mov dword ptr [edx+04], ebx ---> copia al quarto byte di EDX ---> il valore in EBX :10004CD6 mov word ptr [edx+08], bp ---> EDX ritorna al valore PQYZMERUOA :10004CDA mov ebx, dword ptr [ecx+04] ---> copia dal 4 byte di ECX ---> 4 byte in EBX :10004CDD mov bp, word ptr [ecx+08] ---> ...e via dicendo... :10004CE1 mov byte ptr [edx+0A], al :10004CE4 lea edx, dword ptr [esp+1C] :10004CE8 mov eax, dword ptr [ecx] :10004CEA xor di, di :10004CED mov dword ptr [edx], eax :10004CEF mov al, byte ptr [ecx+0A] :10004CF2 mov esi, dword ptr [esp+34] :10004CF6 mov ecx, dword ptr [esp+30] ---> copia in ECX la stringa per la ---> generazione del seriale ---> (quella immessa poco prima ---> della chiamata) Gy549nmwF2
N.B. La stringa è presente non in questa DLL ma nell'eseguibile e la sua lunghezza è maggiore di 10 caratteri ma per la generazione del seriale vengono usati solamente i primi 10 ossia Gy549nmwF2. Molto probabilmente la stringa viene usata in tutta la sua lunghezza per generare il codice personale.
:10004CFA mov dword ptr [edx+04], ebx :10004CFD mov word ptr [edx+08], bp ---> in questo punto si ha in EDX il ---> valore copiato all'inizio ---> in ECX: JIKLICBXZC :10004D01 mov byte ptr [edx+0A], al
* Jump at Address: |:10004D4B(C) | :10004D04 mov eax, dword ptr [esp+2C] ---> copia il codice personale in EAX :10004D08 mov dl, 19 :10004D0A movsx ebp, di ---> contatore :10004D0D mov bl, 19 :10004D0F mov al, byte ptr [ebp+eax] ---> copia una cifra (carattere) del ---> codice personale in AL :10004D13 xor al, byte ptr [esp+ebp+10] ---> XOR tra cifra e PQYZMERUOA :10004D17 xor al, byte ptr [ebp+ecx] ---> XOR con la stringa per la ---> generazione del seriale G.. :10004D1B sub ah, ah :10004D1D div dl :10004D1F mov al, ah :10004D21 mov dl, byte ptr [esp+ebp+1C] ---> copia un carattere di J.. in DL :10004D25 add al, 41 ---> aggiunge 41h in AL :10004D27 mov byte ptr [ebp+esi], al ---> copia il risultato in [ebp+esi] :10004D2B xor dl, byte ptr [ebp+ecx] ---> XOR tra un carattere di J.. e ---> un carattere della stringa G.. :10004D2F xor dl, al ---> XOR tra risultato precedente e AL :10004D31 mov al, dl ---> copia il risultato in AL :10004D33 sub ah, ah ---> sottrae :10004D35 div bl ---> divide :10004D37 mov al, ah ---> copia :10004D39 add al, 41 ---> aggiunge 41h e si ha il N ---> carattere del seriale giusto :10004D3B cmp al, 4F ---> lo confronta con il carattere "O" :10004D3D jne 10004D41 ---> se diverso, salta :10004D3F mov al, 58 ---> altrimenti diventa il carattere "X"
* Jump at Address: |:10004D3D(C) | :10004D41 inc di :10004D43 mov byte ptr [ebp+esi], al :10004D47 cmp di, 000A ---> verifica se DI = A (10 in decimale) :10004D4B jl 10004D04 ---> salta se minore (DI < 10) :10004D4D mov [esi+0A], 00 :10004D51 pop ebp :10004D52 pop edi :10004D53 pop esi :10004D54 pop ebx :10004D55 add esp, 00000018 :10004D58 ret ---> ritorna
Riassumendo, i punti fondamentali per la generazione del seriale sono:
(oltre alla sottrazione di AH e divisione di BL):
1. XOR tra N carattere del codice personale e il relativo N carattere della stringa "PQUIZMERUOA" 2. XOR tra risultato precedente e relativo N carattere della stringa "Gy5..." 3. XOR tra N carattere stringa "JIKLICBXZC" e relativo N carattere della stringa "Gy5..." 4. XOR tra risultato precedente e risultato punto 2 6. Aggiungere 41h al risultato della sottrazione e divisione 7. Eventuale modifica del carattere del seriale in caso fosse una "O", diventa una "X"Ora, creiamoci un rudimentale keymaker con HLA.
path=c:\percorso dove avete installato HLA;%path set lib=c:\percorso dove avete installato HLA\hlalib;%lib% set include=c:\percorso dove avete installato HLA\include;%include% set hlainc=c:\percorso dove avete installato HLA\include set hlalib=c:\percorso dove avete installato HLA\hlalib\hlalib.lib
Non aspettatevi un granchè di key-maker, e comunque è una applicazione per la console non una strafigata con la gui :-(
Ecco il sorgente:
/* PURAMENTE A SCOPO DIDATTICO Non mi assumo nessuna responsabilità dell'uso di questa merda di sorgente. Siete pregati di non distribuire né questo né possibilmente l'eventuale eseguibile.*/
program keyz1; //diamo
un nome al programma
#include("stdlib.hhf");
// qui dichiariamo le variabili
static
codice:string; readonly
testo:string:="Fractal eXtreme 1.xx KeyMaker by ZedTec"; testo2:string:="Inserisci il codice personale: "; stringa1:string:="PQYZMERUOA"; stringa2:string:="JIKLICBXZC"; stringa3:string:="Gy549nmwF2"; // fine dichiarazione variabili
begin keyz1;
//inizio programma
forever //iniziamo il ciclo dei controlli
console.cls(); //puliamo lo schermo
stdout.put(testo); //visualizziamo l'intestazione
stdout.newln(); //andiamo a capo (saltiamo la riga corrente)
stdout.put(testo2); //visualizziamo il messaggio per l'input
stdin.a_gets(); //attendiamo per il codice personale (che
viene spostato in EAX)
mov(eax,codice); //e qui invece lo spostiamo nella stringa
'codice'
if((type str.strRec[eax]).length != 10) then //controlla se il codice //e' diverso ( != ) //di 10 cifre
//di consequenza scrive (sulla barra del nome) il relativo messaggio di errore console.setTitle("Il codice personale deve essere di 10 cifre"); else //altrimenti try //inizio controllo eccezioni conv.strToi64(eax,0); //prova a fare una conversione numerica del codice immesso break; //se a buon fine esce dal ciclo exception(ex.ConversionError) //altrimenti segnala un errore console.setTitle("Il codice personale deve essere NUMERICO"); endtry; //fine controllo eccezioni endif; //fine ciclo endfor; //fine ciclo controlli
stdout.put(nl,"Il seriale e': "); //salta una riga e scrive il testo
//questa e' l'intera routine per la generazione //del seriale 'convertita' per HLA, infatti come potete notare //non si ha una sintassi DESTINATARIO,SORGENTE //ma una SORGENTE,DESTINATARIO tipica del PASCAL. //Inoltre bisogna specificare che si tratta di valori esadecimali tramite il prefisso $. //Commenterò solamente i cambiamenti apportati da me
mov(stringa1,ecx);
lea((type dword [esp]),edx);
push(ebx);
push(esi);
mov((type dword[ecx]),eax);
push(edi);
mov((type dword [ecx+$04]),ebx);
push(ebp);
mov(eax,(type dword [edx]));
mov((type word [ecx+$08]),bp);
mov((type byte [ecx+$0A]),al);
mov(stringa2,ecx);
mov(ebx,(type dword [edx+$04]));
mov(bp,(type word [edx+$08]));
mov((type dword [ecx+$04]), ebx);
mov((type word [ecx+$08]),bp);
mov(al,(type byte [edx+$0A]));
lea((type dword [esp+$1C]),edx);
mov((type dword [ecx]), eax);
xor(di,di);
mov(eax,(type dword [edx]));
mov((type byte [ecx+$0A]), al);
mov((type dword [esp+$34]),esi);
mov(stringa3,ecx);
mov(ebx,(type dword [edx+$04]));
mov(bp,(type word [edx+$08]));
mov(al,(type byte [edx+$0A]));
routine: //inizio
routine calcolo seriale
mov(codice, eax);
mov($19,dl);
movsx(di,ebp);
mov($19,bl);
mov((type byte [ebp+eax]),al);
xor((type byte [esp+ebp+$10]),al);
xor((type byte [ebp+ecx]),al);
sub(ah,ah);
div(dl);
mov(ah,al);
mov((type byte [esp+ebp+$1C]),dl);
add($41,al);
xor((type byte [ebp+ecx]),dl);
xor(al,dl);
mov(dl,al);
sub(ah,ah);
div(bl);
mov(ah,al);
add($41,al);
if(al='O') then //confronta se il N carattere del seriale contenuto il al mov($58,al); //sia una O, in tal caso lo fa diventare una X endif;
inc(di); //incrementa di stdout.putc(al); //nella routine originale gli N caratteri del seriale //veniva copiati in [esi+ebp], io per comodità glieli faccio visualizzare //uno alla volta
if(di<10) then //controlla se di è minore di 10 jmp routine; //salta all'inizio della routine endif; stdout.newln(); //salta una riga stdout.put("- PREMI INVIO PER FINIRE -"); stdin.a_gets(); end keyz1; //fine programma Per compilare ora questo sorgente basterà scrivere: hla (nome che avete dato al sorgente)
ZedTec
Note finali |
Indubbiamente poteva venir fatto qualcosa di meglio...e forse con meno codice, scusate... Questo tut è stato "testato" sia sulla versione 1.21 che sull'ultima (al 15/02/2001), ovvero la 1.60b. Credo che funzioni in tutte le versioni. Dedico questo tutorial a: - Michela per avermi sopportato da quando ci conosciamo. - P. Luca per aver creato qualcosa di più potente (quasi) dei Twilight!!! (il mitico P.UTILITY). - ...e gli altri amici cazzoni...(Domenico e Gianluca questo è per voi) - quel bastardo di Bejelit_Scarlatto che se non dice all'amica sui che è molto carina, utilizzerà presto il suo hard-disk come posacenere. Volevo inoltre ringraziare chi ha permesso la pubblicazione di questo tutorial e chiunque abbia apportato correzioni o miglior delucidazioni...(ma come cazzo parlo?)
Disclaimer |
NON MI ASSUMO NESSUNA RESPOSABILITA' RIGUARDANTE IL CONTENUTO DI QUESTA PAGINA.