Serial fishing  + keygen per FontShow 3.0
(serial fishing + keygen writing)


07/05/00

by "aLX"

 

 

UIC's Home Page

Published by Quequero



Il tute è abbastanza carino, ma il form è davvero penoso, la prossima volta usa il notepad, ma un form così ti supplico non ridarmelo, non sono neanche riuscito a correggerlo, ci vorrebbero troppi secoli

 
UIC's form
E-mail: [email protected]
Nick : aLX , ]aLX[
IRC : #crack-it
UIC's form

Difficoltà

(X)NewBies (X)Intermedio ( )Avanzato ( )Master

 

Analizziamo l'algoritmo , troviamo il seriale e scriviamo il relativo keygen.


Serial fishing +keygen per FontShow 3.0
(serial fishing + keygen writing)
Written by aLX

Introduzione

Cercherò di spiegare ogni passo nella maniera più chiara possibile per poi passare alla scrittura del keymaker. L' algoritmo è abbastanza semplice anche se i dati richiesti per la generazione del serial sono più di uno : name & organization.

Tools usati

Softice 4.0
Hex Workshop 3.1
Borland Turbo C++ 3.0 per il keygen

URL o FTP del programma

Io l'ho preso da un cd di PCWorld, probabilmente se cercate un po' per la rete lo trovate.

Notizie sul programma 

Questo programmino visualizza l'anteprima dei fonts installati nel vostro fido computer, non serve a molto, ma per imparare a... ehmm, ci siamo capiti :)).

Essay

Prima parte – Serial Fishing 

Iniziamo avviando il programmino e comparirà il simpatico splash screen che ci informa di utilizzare una versione di valutazione di 30 giorni non registrata (mi sembra ovvio), dopodichè saremo dentro al Fontshow.

Clicckiamo su Help/Register e ci apparirà una finestra con tre box :

 
User Name :
Organization :
Registration :

A questo punto inseriamo nei box quello che ci pare, io ad esempio ho messo come user name : aLX , organization : crack e come seriale 12345.

Prima di cliccare su OK entriamo in softice e piazziamo un breakpoint su hmemcpy, digitanto “bpx hmemcpy”. Usciamo dal debugger con F5 e premiamo OK, a questo punto dovremo essere di nuovo in softice. Premiamo una volta F11 per uscire da hmemcpy e 8 volte F12 per trovarci nel codice del programma.

Dovremo trovarci in questo punto :

 

:004067CC  push 00000032
:004067CF  push 00000066
:004067D2  call ebp
:004067D4  lea eax, dword ptr [esp+10]
:004067D8  push 00000100
:004067DD  push eax
:004067DE  push 67
:004067E0  push edi
:004067E1  call ebp
:004067E3  lea eax, dword ptr [esp+10]

Ora steppiamo con F10 fino ad arrivare qua :

:0040682D  push ebx               in ebx c’è l’organization e
:0040682E  push esi                in esi, il nome
:0040682F  call 0040B340           call che calcola il seriale
:00406834  add esp, 00000008
:00406837  cmp eax, ebp            confronta il seriale immesso con quello vero
:00406839  je 00406859             se sono uguali
:0040683B  push 0000EACF           pusha la stringa qui sotto altrimenti salta alla msgbox
                                   di errore serial

 

* Possible Reference to String Resource ID=05000: " Register FontShow for Windows 95/NT"

                                  |

:00406840  push 00001388

:00406845  push edi

:00406846  call 00404E10

:0040684B  add esp, 0000000C

 

 

Come possiamo notare in esi c’è il nostro nome ed in ebx l’organization proviamo a scrivere “d esi ” / “d ebx” e  ce ne accorgeremo. Vengono pushati nello stack e subito dopo una call, bene…Non ci resta che entrare in quest’ultima con F8 e dovremo essere catapultati qui :

 

:0040B340  mov eax, dword ptr [esp+04]         in eax il nostro nome

:0040B344  push esi

:0040B345  mov esi, dword ptr [00414AA0]       in esi viene copiato un valore fisso

:0040B34B  push eax

:0040B34C  or esi, 00000378                    e precisamente : 0xF95007FF

:0040B352  call 0040B8E0                       call che fa’ i calcoli sul nome

:0040B357  add esp, 00000004

:0040B35A  add esi, eax

:0040B35C  mov eax, dword ptr [esp+0C]

:0040B360  push eax                            in eax l’organization

:0040B361  call 0040B8E0                       call che fa’ i calcoli sull’ organization

:0040B366  add esp, 00000004

:0040B369  add eax, esi

:0040B36B  pop esi

:0040B36C  ret

 

NOTA : il valore che viene messo in esi è F95007FF, che convertito in decimale diventa 4182771711. Se proviamo a lasciare vuoti i box name e organization e inserire come serial quest’ultimo numero vedremo che FonShow si registrerà correttamente!

Magia forse? Be’… non proprio :)).

 

Ora entriamo nella call a 0040B352 :

 

:0040B8E0  push ebx                         in ebx c’è l’organization

:0040B8E1  push esi

:0040B8E2  mov esi, dword ptr [esp+0C]      in esi viene copiato il nome

:0040B8E6  push edi

:0040B8E7  push ebp

:0040B8E8  xor edi, edi

:0040B8EA  push esi                   il nostro nome viene ancora pushato e

:0040B8EB  Call dword ptr [0041C494]  questa call ne calcola la lunghezza

:0040B8F1  test esi, esi

:0040B8F3  je 0040B927

:0040B8F5  test eax, eax              controllo sulla lunghezza del nome

:0040B8F7  je 0040B927                se è 0 non eseguire il loop, salta

:0040B8F9  mov ecx, 00000000             viene azzerato ecx e inizia il loop

:0040B8FE  jle 0040B927

:0040B900  movsx ebx, byte ptr [eax+ecx+00416544]                                |

:0040B908  movsx ebp, byte ptr [esi+ecx]                                          |

:0040B90C  lea edx, dword ptr [ecx+01]                                            |

:0040B90F  imul ebx, ebp                                                          |

:0040B912  movsx ecx, byte ptr [ecx+0041657C]  calcoli vari                        |  

:0040B919  imul ebx, ecx                                                          |  LOOP

:0040B91C  imul ebx, edx                                                           |

:0040B91F  add edi, ebx                                                           |

:0040B921  mov ecx, edx                                                            |

:0040B923  cmp eax, edx                   il nome è terminato?                     |           

:0040B925  jg 0040B900                    se si esci, altrimenti salta sopra       |

:0040B927  mov eax, edi                  

:0040B929  pop ebp

:0040B92A  pop edi

:0040B92B  pop esi

:0040B92C  pop ebx

:0040B92D  ret

 

Bene, siamo arrivati alla parte più succosa  e cioè dove viene manipolato il nostro nome. Da qui in poi dovremo analizzare ogni istruzione in modo da capire l’algoritmo con cui viene generato il serial per poi scrivere il nostro keymaker, quindi attenzione.

Per la spiegazione dell’algoritmo ho preferito evitare i commenti a margine, li scriverò qui sotto in modo che il tute risulti di più facile comprensione.

 

Allora, appena entrati nella call viene spostato in esi il nostro nome. La call a 0040B8EB calcola la lunghezza del nome e viene messa in eax. Se la lunghezza è 0 non viene eseguito il loop, si esce dalla call.

Altrimenti ecx viene posto a zero ed inizia il loop :

 

0040B900 :

a ebx viene assegnato il valore di eax (lunghezza del nome) + ecx (contatore) ,che inizialmente è 0 + un carattere preso da una zona di memoria corrispondente alla lunghezza del nome. Cerco di essere più chiaro; nel mio caso il nome è lungo tre caratteri aLX,  verrà preso quindi dal terzo carattere in avanti contenuto nel buffer in questione. Potrete esaminare la zona di memoria, semplicemente digitando “d 00416544”  e vedrete che è così composta :

 

# , s , e , r , B , & , n , z  ….

 

Attenzione però che al primo carattere (#) è assegnata la posizione 0 e che quindi questo non verra mai preso, utile poiché possiamo farne a meno quando scriveremo il nostro keygen. 

Nella prima iterazione (parlo sempre nel mio caso) ebx conterrà il carattere ‘r’ , nella seconda ‘B’ e così di seguito.

 

0040B908 :

in ebp viene spostato un carattere del nome, nella prima iterazione ebp contiene ‘a’, poi ‘L’ e infine ‘X’ ;credo che questo sia elementare.


0040B90C :

edx = ecx + 1, questo potete capirlo facilmente.

 

0040B90F :

ebx che contiene il famoso carattere viene moltiplicato per il carattere del nome contenuto in ebp e il risultato rimane in ebx.

 

0040B912 :

in ecx viene messo un carattere contenuto in un’altra zona di memoria adiacente, questa volta però il primo carattere lo consideriamo poiché ecx alla prima iterazione è uguale a 0.

 

0040B919 :

ebx che contiene il risultato del calcolo precedente viene moltiplicato per ecx e il risultato viene messo in ebx.

 

0040B91C :

ebx viene ancora moltiplicato, ma questa volta per edx e… indovinate un po’ il risultato dove va a finire ? Be’ lo avrete capito.

 

0040B91F :

questa volta ci troviamo davanti ad una addizione e precisamente tra edi ed ebx (ah… me ne ero dimenticato edi all’ inizio del loop vale 0), il risultato si trova comunque in edi :).

 

0040B921 :

in ecx viene copiato il valore di edx.

 

0040B923/0040B925/0040B927 :

il nome è finito ? se si termina il loop, copia edi in eax ed esci dalla call; altrimenti salta a 0040B900.  Possiamo notare che , alla fine del loop, edi e eax contengono il numero appena calcolato. Mi dispiace per voi, ma non è ancora il serial corretto ! 

 

Usciti dalla call possiamo vedere che ad esi (il numero fisso / serial) viene sommato eax, ma ancora una volta questo non è il serial (almeno in questo caso).  

All’indirizzo 0040B35C (guardare il codice sopra) viene copiata in eax l’organization, viene pushata nello stack e… subito dopo la stessa identica call di prima, quella che manipolava il nome.

La procedura è la stessa di quella del nome, per cui non sto qui a riscriverla. Dico solo che, come prima, alla fine del loop  edi ed eax conterranno il numero calcolato.

Esattamente come in precedenza : a eax viene sommato esi (che contiene ancora la somma di prima). Questa volta però eax conterrà il serial corretto in formato decimale, per vederlo digitate “?eax”.

Vi ricordate quando dicevo di quel valore fisso/serial ? Be’ quel “trucco” funzionava poiché è proprio ad esso che vengono sommati i valori calcolati nelle due call. Quindi se lasciamo i due box vuoti, non si entrerà mai nel loop, eax assumerà il valore zero e quel valore sommato a zero…. Insomma avete capito.

Finalmente ce l’abbiamo fatta ! Ora l’ 80 % del lavoro è compiuto, per scrivere il nostro keygen basterà soltanto tradurre il codice con qualche accorgimento.  

 

 

Seconda parte – Keygen

 

 

Iniziamo a scrivere il nostro keygen, per prima cosa dobbiamo scegliere con quale linguaggio scriverlo, io ho scelto il C, fate voi.

Riassumiamo brevemente l’algoritmo  :

 

- lunghezza del nome in eax, se è 0 non eseguiamo il loop.

- settiamo tutto a 0 tranne edx = 1;

- ebx  = carattere da buffer[lunghezza nome]

- ebp =  carattere del nome[ecx]

- edx  =  ecx +1

- ebx = ebx  * ebp.

- ecx = carattere dal secondo buffer[ecx]

- ebx = ebx * ecx

- ebx = ebx * edx

- edi = edi + ebx

- ecx = edi

- il nome è finito ? se si copiamo edi in eax e andiamo avanti, altrimenti saltiamo sopra

- esi = eax + 0xF95007FF

- facciamo la stessa cosa del nome con l’organization ed infine aggiungiamo ad eax il valore di esi

 

Siamo pronti per scrivere il nostro keymaker, siccome abbiamo bisogno di due buffer, dobbiamo ricostruirli. Apriamo quindi il nostro hex editor preferito (io ho usato Hex Workshop) e cerchiamo le zone di memoria che ci interessano, ci copiamo tutti i caratteri che poi andremo ad inserire nel sorgente C.

Cominciamo a scrivere qualcosa :

 

#include <stdio.h>          

#include <string.h>

#include <conio.h>

 

 

unsigned long ebx,esi,edi,eax,ebp,ecx,edx = 1;

unsigned int count = 0;

char string[54] = {'s','e','r','B','&','n','z','|','m','f','M','1','/','5',

              '(','!','s','d','$','M','q','.','{','s',']','+','s','F',

              'j','t','K','p','z','S','d','t','z','o','X','q','m','b',

              '^','A','l','@','d','v',':','s','?','x','/'};                       

char string2[54] = {'|','b','!','p','z','*','l','s',';','r','n','|','l','f',

              '$','v','i','^','A','x','p','e',')','r','x','5','a','i',

              'c','&','9','/','2','m','5','l','s','i','4','@','0','d',

              'm','Z','w','9','4','c','m','q','p','f','h','w'};

char input[20];

 

unsigned long call(char[]);

 

Ho preferito chiamare le variabili con il nome dei registri usati dal programma cosi che risulti il più simile possibile. Abbiamo così creato i due buffer, tutte le variabili che ci servono e scritto il prototipo della funzione per il calcolo sull’input.

Ora scriviamo la funzione principale main.

 

main()

 

{

clrscr();                                   puliamo lo schermo

printf("\n\tFontShow v3.0 *Keymaker* by aLX\n");

printf("\nUser Name : ");                   chiediamo il nome

gets(input);                                lo riceviamo

eax = call(input);                         chiamiamo la funzione di calcolo   [0040B352]

esi = eax + 0xf95007ff;              sommiamo il valore calcolato con quello fisso  [0040B35A]

printf("\nOrganization : ");               chiediamo l’organizzazione

gets(input);                               la riceviamo

eax = call(input);                         chiamiamo la funzione di calcolo  [0040B361]

eax += esi;                     sommiamo il valore calcolato con quello di prima   [0040B369]

printf ("\n\nThe Registration code is : %lu" ,eax);  scriviamo il serial sul monitor

return 0;                                            fine del programma

}

 

E anche questa è fatta. Come già sappiamo il seriale è in formato decimale, optiamo per gli unsigned long poiché i normali unsigned int non ci bastano, in quanto la lunghezza del codice di registrazione è di 10 cifre.

Implementiamo ora la/e routine di calcolo :

 

unsigned long call(char input[])

 

{

eax = ebx = count = ebp = ecx = edi = 0;       settiamo tutto a 0 tranne edx

edx = 1;

eax = strlen(input);    calcoliamo la lunghezza del nome/organization  [0040B8EB]

if ( eax == 0 )         se è = a 0 non eseguiamo il loop  [0040B8F5]

return eax;

do

{

  ebx = string[(eax-1)+count];     ebx  = carattere da buffer[lunghezza nome/org]  [0040B900]

  ebp = input[count];              ebp =  carattere del nome/org[ecx]          [0040B908]

  ebx *= ebp;                      ebx = ebx  * ebp                            [0040B90F]

  ecx = string2[count];            ecx = carattere dal secondo buffer[ecx]     [0040B912]

  ebx *= ecx;                      ebx = ebx * ecx                             [0040B919]

  ebx *= edx;                      ebx = ebx * edx                             [0040B91C]

  edi += ebx;                      edi = edi + ebx                              [0040B91F]

  ecx = edx;                       ecx = edx                                    [0040B921]

  ++count;                         incrementiamo

  ++edx;                           i contatori

}

while (count < eax);               controlliamo se il nome/org è finito    [0040B923/0040B925]

eax = edi;                         copiamo edi in eax                          [0040B927]

return eax;                        ritorno in main                             [0040B92D]

}

 

 

Dopo tanto lavoro abbiamo veramente finito, non ci resta che provarlo : compiliamo e lanciamo…. Mettiamo un nome e se vogliamo anche l’organizzazione, segnamoci il seriale e vediamo se funziona.

Apriamo FontShow, clicckiamo su Help/Register e inseriamo i dati , a me funziona e a voi?

 

User Name : Keygen by

Organization : aLX

Registration : 4207370081 

                                    

Spero di essere stato chiaro, anche ai meno esperti e comunque per eventuali critiche, suggerimenti e quant’altro vi possa passare per la testa scrivete pure all’indirizzo sopra.

 

                                                                                  Bye

 

                                                                                                      aLX

                                                                                                                

Note finali

Saluto tutti gli amici di #crack-it .

 

Disclaimer

 

Queste informazioni sono solo a scopo puramente didattico.

 


UIC's page of reverse engineering, scegli dove andare:
Home   Anonimato   Assembly    CrackMe   ContactMe   Forum   Iscrizione
Lezioni    Links   Linux   NewBies   News   Playstation
Tools   Tutorial   Search   UIC Faq
UIC