VBox 4.6 Manual Unpacking usando come target Macromedia Flash MX

Salve! Eccoci di nuovo qua alle prese con un'altra protezione commerciale, stavolta vbox 4.6.3, una delle più stupide che esistono. Ma andiamo con calma, iniziamo ad analizzare il nostro bel target, quindi scaricatelo, installate falsh mx (2 ore di installazione), eseguitelo, e tanto per aiutare di più il reverser di turno, appare una bella finestra con tanto di pubblicità su vbox (notate la scritta vbox in basso a sinistra :)), che ci informa del tempo rimanente per provare flash, con i 3 classici pulsanti, try, quit e information, bene facciamo click su try e flash parte, be questo lo sapevamo :), iniziamo ad unpackare il target.
Per prima cosa ci serve l'oep, e trovarlo non sarà un problema, facciamo partire flash, quando appare la finestra di vbox mettiamo un bpx su GetVersion, e facciamo click su try, dopo un po' apparirà il softice, fate F12 e qualche istruzione più sopra avrete l'ep (VA: 00828864), ok mettetici un break, uscite da softice e uscite da flash, è arrivato il momento di dumpare il programma. Aprite hiew (o il vostro editor preferito, considerando che ci servirà in seguito vi consiglio di prendervi PEditor e LordPE), fate F8 e poi F6 (in disasm mode) e segnatevi la dimenzione delle varie sezioni (PhysSize non VirtSize), notate quanto è carina la sezione PREVIEW in bella vista, sarà mica la sezione del vbox? noooooooo :), vabbe dopo che vi siete segnati il vsize delle sezioni, brekkate di nuovo sull'oep, e dumpate tutto con icedump (le sezioni .rsrc e .reloc potete pure evitare di dumparle), ecco le informazioni che vi serviranno:

.text - RVA: 1000, PhysSize: 6B6000
.rdata - RVA: 6B7000, PhysSize: FB000
.data - RVA: 7B2000, PhysSize: 4D000
.idata - 8E6000, PhysSize: 6000

ecco i comandi per dumpare invece:

/dump 00401000 6B6000 c:\flash.text
/dump 00AB7000 FB000 c:\flash.rdata
/dump 00BB2000 4D000 c:\flash.data
/dump 00CE6000 6000 c:\flash.idata


Ok, adesso abbiamo le nostre belle sezioni dumpate, quindi fate una copia di flash.exe e chiamatelo crack.exe, e usate il mio programmino per sostituire le sezioni dumpate con quelle originali (lo trovate nei download, ), il suo funzionamento è semplice:

frep file1 file2 offset size

Dove file1 è il file originale, offset è l'offset a partire dal quale vengono sostituiti i dati, file2 è il file da usare per la sostituzione, size è la dimensione dei dati da sostituire, quindi prendetevi tutti gli offset (sempre usando hiew), e fate:

frep crack.exe flash.text 1000 6B6000
frep crack.exe flash.rdata 6B7000 FB000
frep crack.exe flash.data 7B2000 4D000
frep crack.exe flash.idata 7FF000 6000


Ok, adesso dobbiamo mettere l'oep al suo posto, quindi aprite il file con PEditor o LordPE o ProcDump (insomma un pe editor), e mettete l'oep al posto dell'ep, quindi al posto di 00C73210 metterete 00428864, salvate il file.
Ok, adesso viene il bello, se analizzate la sezione .idata (verso l'offset 8003A8), noterete che gran parte delle funzioni sono risolte (quelle che come indirizzo hanno BFxxxx o altri indirizzi che puntano dentro delle dll), però ne manca ancora una parte consistente, come faremo a risolvere le altre funzioni? Semplice, siccome il vbox non brilla certo per l'inteligenza :), faremo in modo che sia lui a sistemarci le api non risolte (grazie Brothers per il consiglio! (ma è questo il tuo vero nick?)), così alla fine avremo una iat con tutti gli indirizzi a posto, tranne due entry che risolveremo a mano (sono due funzioni che vengono usate per comunicare con il vbox), allora per far ciò, assembleremo un piccolo pezzo di codice a runtime che dopo aver fatto risolvere l'api al vbox ci metterà il suo ep nella iat, quindi brekkate sull'entry point, e assemblate questo codice:

:a 00828874
0187:00828874 mov eax, 00CE73A4 ; eax contiene l'inizio della iat meno una dword
0187:00828879 add eax, 04 ; ora eax punta alla prima entry
0187:0082887E cmp eax, 00CE85A8 ; controlliamo se siamo arrivati alla fine della iat
0187:00828883 jz 008288A0 ; se si andiamo alla fine
0187:00828885 mov ebx, [eax] ; prende l'entry corrente
0187:00828887 cmp ebx, 00 ; controlliamo se è 0
0187:0082888A jz 00828879 ; se si va alla prossima entry
0187:0082888C cmp ebx, 02FFFFFF ; controlla se ebx è maggiore di 02FFFFFF (le api da risolvere sono comprese tra 02000000 e 02FFFFFF)
0187:00828892 ja 00828879 ; se è maggiore va alla prossima entry
0187:00828894 cmp ebx, 02000000 ; controlla se ebx è minore di 02000000
0187:0082889A jb 00828879 ; se è minore va alla prossima entry
0187:0082889C call [eax] ; se è un'api da risolvere, allora la chiama, così il vbox ce la risolve
0187:0082889E jmp 00828879 ; dopo aver risolto l'api torneremo qui
0187:008288A0 jmp 008288A0 ; invece qui ci arriviamo quando abbiamo finito di risolvere

Ok, ora dobbiamo forzare il vbox a risolverci l'api, quindi se seguite una call di un'api non risolta, vedrete una cosa del genere:

call 0700E5CC

Quella call non fa altro che passare il controllo alla funzione che risolve l'api, quindi metteremo un jmp sull'entry point di quella funzione, che salterà ad un pezzo di codice che salverà l'indirizzo nella iat da risolvere, per prenderlo in seguito e metterci l'entry point dell'api corretta, quindi assembliamo un jmp a 0700E5CC:

:a 0700E5CC
0187:0700E5CC jmp 00CE7000 ; salta in un punto vuoto in cui assembleremo del codice

:a 00CE7000
0187:00CE7000 push ebx
0187:00CE7001 mov ebx, 00CE73A0 ; ebx punta ad una dword vuota in cui salveremo l'entry nella iat da risolvere
0187:00CE7006 mov [ebx], eax ; eax contiene l'entry appunto
0187:00CE7008 pop ebx
0187:00CE7009 push ebp ; ripristiniamo il codice originale
0187:00CE700A mov ebp, esp
0187:00CE700C sub esp, 10
0187:00CE700F jmp 0700E5D2 ; torniamo dove eravamo rimasti

Ok, adesso se vedete a 0700E5D2 pusha un po' di valori, e poi fa una call 0700E606 che risolve l'api, mettendo in eax l'entry point, quindi noi dopo la call, assembleremo un jmp che salta ad un'altro nostro pezzo di codice, che metterà l'entry point al posto giusto, quindi assembliamo sto jmp:

:a 0700E5F4
0187:0700E5F4 jmp 00CE7020 ; il jmp che ci porta al nostro pezzo di codice

:a 00CE7020
0187:00CE7020 push ebx
0187:00CE7021 mov ebx, [00CE73A0] ; riprendiamo il valore che avevamo salvato prima
0187:00CE7027 mov [ebx], eax ; e al suo posto invece dell'api non risolta ci mettiamo l'indirizzo di quella risolta
0187:00CE7029 pop ebx
0187:00CE702A add esp, 10 ; ripristina il codice
0187:00CE702D mov eax, [ebp-04]
0187:00CE7030 mov ebx, [ebp-08]
0187:00CE7033 mov ecx, [ebp-0C]
0187:00CE7036 mov edx, [ebp-10]
0187:00CE7039 pop ebx
0187:00CE703B leave
0187:00CE703E add esp, 04
0187:00CE7043 push 0082889E ; pushiamo il valore di ritorno
0187:00CE7048 ret ; continua a risolvere

Ok, adesso se volete tracciate un po' dentro il codice per vedere come fa, ma poi mettete un bpx su 008288A0 e quando il softice apparirà avrete la iat quasi completamente risolta. Quindi fate come ho detto, e appena poppa il softice, dumpate la iat in questo modo:

/dump 00CE73A8 1200 c:\flash.iat

Quindi sostituite la iat dumpata con quella originale (usando un hex editor o di nuovo il mio programma, l'offset della iat è 8003A8), e provate a far partire... noterete che il programma parte (il popup iniziale appare), però crasha misteriosamente subito dopo aver mostrato la finestra di flash, uhm..., controllate l'eip del crash, potrebbe essere o 0700EB50 oppure 0700EBBF, ma questi non sono indirizzi dentro il vbox? esatto! Lanciate il programma originale, e mettete un break su quei due indirizzi, noterete che il programma ci brekka sempre, e se controllate, vedrete che quei due indirizzi, wrappano nel api GetMessage e PeekMessage, in questo modo il programma controlla la presenza del vbox ad ogni messaggio! pazzesco! un rallentamento incredibile, fortuna che ci siamo qui noi a sistemare le cose :), allora, prendete gli indirizzi di GetMessage e PeekMessage di user32.dll (da softice basta che fate d GetMessageA e d PeekMessageA) e metteteli nella iat al posto di 0700EB50 (GetMessage) e di 0700EBBF (PeekMessage), per trovare dove metterli basta che vi guardate la iat di user32 e notere due entry diverse dalle altre, al loro posto mettete gli indirizzi giusti (BFF5573D per GetMessageA e BFF5580D per PeekMessageA, ovviamente se avete un'altra versione di windows cambiano, questi indirizzi sono relativi alla versione Win98 SR 2), salvate tutto, fate partire e... funziona!!!!!!!!!!! che protezione demente! ora avete il vostro bel flash mx che non scade più!
Però c'è un'ultima cosa da fare, ricostruire una IT a partire dagli indirizzi nella iat, per far ciò useremo ImportReconstructor, quindi lanciatelo, dalla lista dei processi selezionate il file crack.exe, e dopo un po' apparirà la lista dei moduli caricati, fate click su IAT auto search e vi verrà fuori un valore sballato ma non fa niente, al suo posto mettete 008E73A8 e come dimensione mette 1200, fate Get Imports, controllate se ci sono tutte (dovrebbero esserci, però in caso che ci sia qualche entry non risolta avete sbagliato qualcosa durante il procedimento per forzare il vbox a risolverle per noi, in questo caso provate a rifare tutto), e poi fate fix dump, selezionate il file crack.exe e ImportReconstructor creerà un file chiamate crack_.exe, che sarà quello fixato, fatelo partire e vi accorgerete che funzionerà perfettamente, sia su Win98 sia su nt (quindi anche xp e 2k), beh, con questo avremmo finito, però siccome non mi piace lasciare le cose a metà :), cancelleremo la sezione PREVIEW per togliere completamente di mezzo il vbox, quindi aprite il PEditor 1.7, selezionate il file crack_.exe, poi su sections e cancellate la sezione PREVIEW, ora aprite LordPE, selezionate il file crack_.exe e fategli fare un rebuild completo del file (dovrebbe gia averlo come opzioni di default), a questo punto fate partire il file su nt (su Win98 funziona senza problemi) e se siete fortunati funzionerà perfettamente :).

Ok, adesso abbiamo finito veramente, spero che questo tutorial (semplice) vi sia piaciuto, in caso contrario siete autorizzati a mandarmi maledizioni in qualsiasi lingua (soprattutto latino :)) via email :).

Ciao!

Quake2