quequero.org Forum Index quequero.org
UIC Forum
 
 UIC HomeUIC Home FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups 
 ProfileProfile   You have no new messagesYou have no new messages   Log out [ Zero_G ]Log out [ Zero_G ]   

Ritornando alla S***vision...

 
Post new topic   Reply to topic    quequero.org Forum Index -> Reverse Engineering
View previous topic :: View next topic  
Author Message
Zero_G
Moderator
Moderator


Joined: 20 May 2004
Posts: 886
Location: Dark Side of the Moon

PostPosted: Sat Apr 30, 2005 5:21 pm    Post subject: Ritornando alla S***vision... Reply to topic Reply with quote Edit/Delete this post Delete this post

Oh via, dopo una settimanetta niente male (un compito ed un orale a fila), ho riguardato il tanto acclamato BigRace, anche perché shrek2, piratino e michfigo si sono praticamente innamorati di quest'aggeggio infernale... Shocked

Una volta appurato con PEiD che il fetente è scritto in Delphi, andate a casa di DeDe e fatevi dare un bel "bigrace.map" alla fragola, con dentro tutti i riferimenti alle funzioni dell'oracolo (non li fanno più i gelati di una volta! Laughing ); tornate a casa e con il GODup plugin che avete sul comodino fate mangiare il map-gelato a OllyDbg, che vi mostrerà tutta la sua gratitudine offrendovi in cambio un bel disassemblato commentato e pieno di utili labels. Mr. Green

Giusto per sfizio, mentre voi lavorate al tavolino, potete mettere IDA a fare la cyclette sull'eseguibile principale in modo da avere ancora più informazioni a disposizione; che donna! Laughing

Prima mossa, come sempre, la ricerca delle stringhe: seguite il precedente su BigMatch per le linee guida, cmq è semplice, basta cercare "Il codice" e vi troverete subito a 0072E171; risalite fino a 0072DF94 che è l'inizio della procedura assegnata al click del bottone (lo vedete il TFormUnlock@SbloccaClick di DeDe? Wink )

Lanciate BigRace da dentro il debugger, inserite nome/seriale a caso, cliccate su "Sblocca" ed Olly entra in scena; si capisce bene che i programmatori hanno riusato il codice già scritto per BigMatch, dato che questa funzione è del tutto identica, solo l'offset da cui comincia è diverso. Rolling Eyes

Lo StrLen a 0072DFDE serve a controllare che il nome sia lungo almeno 8 caratteri, spazi esclusi, quindi con "Pinco Pallino" ce la caviamo; si prosegue a 0072DFF7, dove in EAX viene caricato un parametro che si trova nello stack poco sopra il nostro nome (EBP-118) e la successiva CALL lo memorizza in una area di memoria riservata (verificatelo entrando con F7 dentro la CALL).

continuando più in basso, lo stesso valore viene caricato anche in ECX, DL viene settato a 1 e la stringa "TCripter" viene messa in EAX come parametro per la successiva CALL che si trova a 0072E00F (controllate sempre la status bar che fornisce un sacco di utili informazioni sull'istruzione attuale)
Code:
0072DFF7 > LEA     EAX,SS:[EBP-118]  ; carica in EAX il valore di init
0072DFFD > CALL    <LoadStuff()>     ; e ci inizializza il crypter
0072E002   LEA     ECX,SS:[EBP-118]
0072E008   MOV     DL,1
0072E00A   MOV     EAX,DS:[5F2264]   ; EAX = "TCripter"
0072E00F > CALL    <TCripter()>      ; esegue la codifica del seriale

per quanto sono riuscito a capire finora, quelle 2 CALL impostano i parametri del TCripter che di lì a poco verrà messo in funzione e per questo ho messo le label. Wink

A 0072E032 c'è il fatidico GetText() del codice che viene piazzato nello stack poco più in basso del ESP, dopo il nostro nome, mentre a 0072E043 c'è una misteriosa UnknownProc... Twisted Evil
Code:
0072E02C > MOV     EAX,DS:[EBX+300]    ;  *TFormUnlock.EditCodice:TEdit
0072E032 > CALL    004504EC            ;  ->TControl.GetText(TControl):TCaption;
0072E037   MOV     EDX,SS:[EBP-120]
0072E03D   LEA     ECX,SS:[EBP-5]
0072E040   MOV     EAX,SS:[EBP-4]
0072E043 > CALL    <cryptserial()>     ;  ->Unit_005F2264.Proc_005F2594


Se entriamo dentro quella CALL con F7, vedrete un FOR che mette 167 * 2 = 334 zeri nello spazio dello stack riservato alle variabili locali della funzione:
Code:
005F2598  |.  MOV     ECX,0A7
005F259D  |>  /PUSH    0
005F259F  |.  |PUSH    0
005F25A1  |.  |DEC     ECX
005F25A2  |.^ \JNZ     SHORT 005F259D

il nostro seriale per ora è in EDX, ma a 005F25AC viene copiato in [LOCAL.1], cioè nella prima variabile locale che è in fondo a quella grande pila appena allocata; la situazione dello stack è questa:
Code:
ESP ==> 00000000  (LOCAL.334)
        00000000  (LOCAL.333)
        .......
        *seriale  (LOCAL.1)
EBP --> indirizzo di rientro

PS: in realtà le variabili locali di questa funzione arrivano a 336 perché ci sono sempre le due locazioni riservate a EBP e ECX pushati all'inizio della procedura.

L'algoritmo del TCripter è molto lungo e comprende un sacco di operazioni sulle parti costitutive del seriale; ve ne rendete man mano che steppate perché quei 334 posti cominciano a riempirsi di risultati intermedi.

Alla fine della fiera, il risultato sono 8 bytes che corrispondono al nome generato a partire dal seriale, cioè, contrariamente a quanto si poteva immaginare, è il seriale a corrispondere ad un nome, più precisamente a 8 caratteri ASCII. Idea

Per vedere dove si trovano, basta lasciar terminare l'algoritmo (CTRL+F9 due volte) e rientrare nel flusso principale a 0072E048; se date un occhiata allo stack, TCripter posiziona l'indirizzo contenente la codifica del seriale subito sotto l'indirizzo del seriale stesso... a questo basta cliccarc isopra con il destro e scegliere "Follow in Dump" per scoprire quanto vale.
Code:
(STACK)    (VALUE)
0012E864   00E98D64  ASCII "123456789012345678901234567890123456"
0012E868   00E98E3C  <--- fate "Follow in Dump" di questo valore
0012E86C   1345A711
0012E870   7525A956
0012E874   00E97010  ASCII "Pinco Pal"
0012E878   00E97028  ASCII "PincoPal"


Nel mio caso, il 'nome' calcolato corrisponde a "19 DA 21 1F A8 CE B7 16"

Proseguendo con il debugging, le istruzioni da 0072E048 a 0072E06A prendono i primi 8 caratteri di questa serie di valori calcolati e li mettono nello stack sopra il seriale immesso (bel compilatore, erano già 8 seguiti da zeri! Laughing )

Da 0072E083 a 0072E0C0 ci sono il GetText() del nome immesso (un'altra volta!? ma ce l'aveva già nello stack... Crying or Very sad ), la rimozione degli spazi (0072E09A) e l'uppercase (0072E0C0); subito sotto, i due indirizzi (nome immesso e nome generato dal serial) vengono passati come argomenti allo StrCmp a 0072E0CC:
Code:
0072E0C5   MOV     EDX,SS:[EBP-128]     ;  EDX = entered name
0072E0CB   POP     EAX                  ;  EAX = calculated name
0072E0CC > CALL    0040581C             ;  ->System.@LStrCmp;
0072E0D1   JNZ     0072E171

beh se non avete azzeccato a caso le 36 cifre che corrispondono al vostro nome, dubito che l'esito del compare sia positivo... Rolling Eyes

Quindi qual'è il problema? un keygen a partire da un seriale in genere qui non funziona, perché è difficile che 36 cifre a caso generino 8 bytes che rientrano nel range degli ASCII (infatti il nome 'giusto' del mio seriale non si può scrivere con la tastiera... Evil or Very Mad ) ed è proprio questo a cui si sono attaccati i programmatori: gli unici seriali giusti sono quelli che generano 8 caratteri ASCII. Killlllll

In conclusione, è un algoritmo irreversibile che ha bisogno di un brute force che scorra i numeri che vanno 0 a 10^36 - 1 e ne trovi uno che con quello schema di codifica generi 8 numeri compresi 40h e 7Ah (range ASCII delle lettere).
Evil

Se il nome supera questo controllo, a 0072E0E3 ci riè il GetText (errare è umano, perserverare è Delphi... Cool ) che passa il nome immesso alla CALL a 0072E0EE, la quale a sua volta procede nuovamente a troncare a 8, togliere gli spazi e portare in maiuscolo, dopodiché fa la somma dei valori dei caratteri (il FOR da 005F245F a 005F246A) e la mette in EAX; dopo, a 0072E0F3, questo valore (nel mio caso era 56) viene confrontato con quello che si trova in [EBP-5], che tuttora devo capire da dove diavolo salta fuori (io c'avevo 31).
Francamente, non so per quale motivo debba essere fatto, dato che il nome è già stato confrontato con quello giusto... Confused

Se volete patchare l'eseguibile per farlo andare, seguite le stesse istruzioni che avevo scritto per BigMatch, tanto la filosofia è esattamente la stessa; se invece volete fare un bel lavoretto, sfruttate il codice assembler di quella funzione per fare un bel brute forcer, anche se credo che 36 cifre siano davvero tante e l'incremento esponenziale delle combinazioni a questo livello è letale. Ignorance

beh, per ora è tutto... vado a trovare quegli altri rincoglioniti di Nt, Lone, Xoa... that's all folks! Wink

-=[Zero_G]=-

PS: IDA... ci sei ancora?? IDA?? oddio, è morta sulla cyclette... Shocked
_________________
"To see a World in a grain of Sand,
Hold Infinity in palm of your Hand."
Back to top
View user's profile Send private message Send e-mail Visit poster's website MSN Messenger
piratino
Newbie
Newbie


Joined: 20 Feb 2005
Posts: 45

PostPosted: Sun May 01, 2005 12:31 pm    Post subject: Reply to topic Reply with quote Edit/Delete this post Delete this post

Grazie Zero_G Smile allora ho capito dalla tua plendida "lezione" che non è possibile trovare un seriale giusto Sad

grazie, piratino Smile
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    quequero.org Forum Index -> Reverse Engineering All times are GMT + 1 Hour

Page 1 of 1
Watch this topic for replies
 
Delete this topic Move this topic Lock this topic Split this topic 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum
You can moderate this forum


Powered by -=Quequero=-