OutLook Express E-mail Saver v5.1.438
P-Code Reversing & Cracking

17-12-2003

by Pincopall

 

UIC's Home Page

Published by Quequero


AUGURI
UIC

Grazie pinco, e ringrazia anche maria per i colori stile Tyson-Eye-Punch ;pppp


AUGURI
#Crack-it

BUON NATALE

Home page se presente: http://navig8.to/pincopall
E-mail: [email protected]
Pincopall on #crack-it #hackmaniaci #asm ecc..

BUON 2004

Difficoltà

( )NewBies (P)Intermedio ( ) Avanzato ( )Master

 

In questo tutorial cercheremo di capire meglio come sconfiggere il P-Code e di reversare un programma da questi protetto e analizzeremo anche in cosa consiste la protezione data dal P-Code, "Cos'è il P-Code?" vi domanderete, bhè, andate avanti nella lettura e lo scoprirete =).


Outlook Express E-mail Saver v5.1.438
P-Code Reversing & Cracking
Written by Pincopall

Introduzione


Il tutorial che andrete a leggere si propone, più che di farvi vedere come reversare il programma Outlook Express E-mail Saver, di darvi un'idea su come comportarsi di fronte ad un programma in P-Code, non un modus operandi valido in ogni caso ma..qualcosa che gli somigli =)

Tools usati


WktVbDebugger  --- Un debugger per programmi scritti in P-Code
ExDec  --- Il disassemblatore per programmi scritti in P-Code creato da JosephCo_


URL o FTP del programma

Il programma è scaricabile in versione time trial a 7 giorni da www.mazepath.com.

Notizie sul programma

Bhè, il nome del programma ne suggerisce già l'utilizzo, l'autore dice di lui:

"Outlook Express Email Saver is a versatile tool for managing your email. It can provide automatic schedule backup, deletion of duplicate emails, and even backup your Address Book!
The simple interface allows you to save your email folders to any drive, diskette, zip drive, or even a write-able CD! Please remember that you must first format a CD to be used as a drive before attempting to save your archives to it."

Essay


Dunque, prima di partire lancia in resta, vediamo di capire cosa è questo P-Code:

CENNI SUL P-CODE

Dunque, come voi sapete, e se nn lo sapete ve lo dico io, i programmi in VB possono essere compilati in due modi, in P-Code (pseudo-codice) o in codice nativo, questo almeno a partire dal Visual Basic 5, in effetti, fico al 4 la compilazione in P-Code era l'unica consentita. Il codice nativo è quello eseguito direttamente dal processore, mentre il P-Code è un codice intermedio che ha bisogno di un'ulteriore elaborazione da parte delle librerie di run-time del Visual Basic, prima fra tutte la famosa msvbvm60.dll (per la versione 6), un po' come avviene per i file CLASS di Java.
Questa dll contiene procedure utili ad esempio per l'avvio e la chiusura dell'applicazione, oppure per la conversione dei tipi di dati. Essa si occupa, tra l'altro, anche di convertire lo pseudo-codice in codice nativo: in effetti lo pseudo-codice è un codice interpretato.
Anche le applicazioni compilate direttamente in codice nativo hanno bisogno dei servizi offerti da questa libreria: è per questo che assieme a un'eseguibile creato in Visual Basic vengono distribuite anche le librerie di run-time, i vari .ocx .dll ecc... per intenderci, che non sempre risultano già installate nei pc dell'utente.
Una differenza sostanziale tra i due è inoltre che il codice nativo risulta essere più veloce del P-Code infatti, quando il codice è compilato direttamente in un file eseguibile, viene subito tradotto in linguaggio macchina, mentre per il P-Code si deve passare da un interprete, proprio della piattaforma di progettazione, che traduca il tutto in un linguaggio macchina eseguibile dal processore.
Un programmatore intelligente quindi (a parte che, dato che usa il VB ci sarebbe da discutere sulla sua intelligenza ..ma cmq..:p) che motivo avrebbe di usare il P-Code in VB6? mica vorrà rallentare il programma da lui creato facendoci perdere tempo? Bhè, il primo motivo che mi viene in mente è che un programma generato in P-Code occupa un 40-50% in meno rispetto a una applicazione in codice nativo, ma un secondo motivo è proprio quello di proteggere il suo programma da voi, maledetti reversers, utilizzando i tools convenzionali infatti, IDA come disasm e SoftIce come debugger, non si cava un ragno dal buco dato che le istruzioni che andremo a leggere non corrisponderanno, ed anche utilizzando il fido SmartCheck come si fa quando si ha a che fare con un prog in VB si riceve un triste messaggio dove il debugger ci informa che il programma che stiamo analizzando è P-Compilato e che lui non può darci nessun aiuto.
Ma perchè non vediamo niente? o almeno, nn vediamo operazioni corrispondenti a quelle realmente presenti nel codice del programma? Bhè perchè abbiamo degli opcode diversi, ma se noi abbiamo una macchina virtuale (Microsoft Visual Basic Virtual Machine)che processa gli opcode interpretandoli e rendendoli in linguaggio macchina, allora è certo che questi opcodes hanno un significato uguale a quelli che siamo abiutati a vedere, basterebbe solo sapere a che operazione corrisponde un determinato opcode, e qui ci viene in aiuto o un articolo presente sul sito della Microsoft all'indirizzo http://msdn.microsoft.com/library/backgrnd/html/msdn_c7pcode2.htm, ma che ora è stato rimosso, o il WktVbDebugger, e di quest'ultimo parleremo in seguito. Dalla lettura dell'articolo comunque si viene a sapere che il P-Code ha 255 opcodes "standard" più altri 256 meno usati, che possono essere disposti in combinazioni di 4 o meno bytes.
"Minchia, ma allora è possibile fare un disassembler?" Esatto! e non solo si può fare un disassembler, ma c'è pure chi ci ha già pensato =) trattasi di JosephCo_, il creatore dell'exdec, che è per l'appunto un disassemblatore per programmi compilati in p-code =))
Da notare che all'interno del file .zip dell'exdec troverete anche dei file Msvbvm50.pdb Msvbvm60.pdb e, dipende da dove lo scaricate, io nn ce li ho trovati =(, Msvbvm50.nms e Msvbvm60.nms che non sono altro che simboli per il debugger da caricare con il Symbol Loader per poter debuggare i prog scritti in p-code con SoftIce.
Ma qua c'è da fare un appunto, se il programma che volete debuggare è scritto in Visual Basic 5 e poi compilato in P-code, allora, dopo aver caricato i simboli Msvbvm50.nms, per poter debuggare dovete solo mettere un bpx doexdisp, chiudere SoftIce, avviare il prog e mettere un bpm sull'offset su cui volete brekkare, come ci insegna ogni tut che troviamo (pochini) sul p-code, compreso uno su Incomedia 5 di Niutron che sta proprio alla UIC =), il problema sorge se il prog è scritto in Visual Basic 6, perchè anche una volta caricati i simboli Msvbvm60.nms con il Symbol Loader, il bpx doexdisp non lo riconosce visto che il VB6 non ha questo simbolo, ergo ci troviamo in difficoltà..sfiga vuole che Outlook Email Saver sia proprio in VB6!! Damn!

Prima di procedere e vedere come fare, piccola parentesi:

*****************************************************************************

Se siete sfortunati come me e nel exDec.zip non trovate i file .nms, visto che è difficile trovarli in giro (almeno per Windows 98, visto ke io non li ho trovati neppure usando il symretriever,mentre per WinXp si tovano),e visto che senza quelli non potete usare Sice, almeno per il VB5, per debuggare programmi P-compilati, ecco come fare per farseli usando i pdb =)).

1) Dunque, noi i .nms li vogliamo fare del file Msvbvm50.dll, allora disassembliamo questo con IDA

2) In IDA c'è l'opzione da Edit, Plugins, Load PDB File, e usando questa vedrete apparire tanti bei nomi nel disassemblato =)

3) A questo punto facciamo un file .map usando IDA dal menù File, Produce, Create MAP File..

4) Ora con Msym, che dovreste avere nella sottodir util16 della dir di SoftIce, fate un file .sym digitando nel prompt di Dos, "Msym file.map"

5) Ultimo step, caricate il file con il Symbol Loader e fate li partire, chiudete il Symbol Loader e, come per magia, vi apparirà nella dir del file .sym che avete caricato, il file Msvbvm50.nms, yeeee!

*****************************************************************************

Per quanto riguarda i cenni sul p-code li possiamo concludere qua, di come siano fatte le call, che nel p.code si chiamano Proc e non terminano con un RET ma con un ExitProc che può pure non esserci, e magari di qualche istruzione delle più comuni, ne parleremo quando ne troveremo, e le troveremo siatene sicuri =)
Bhè,via con la seconda parte, il reversing e il cracking di Outlook Email Saver. =)

RISCALDATI? BENE, DIAMOCI DA FARE ORA

Allora, apriamo exDec e facciamogli disassemblare il file archiver.exe, al primo impatto, wo..istruzioni mai viste, uhm, cerchiamo di andare un po' a intuito allora, dopotutto siamo sempre in dead listing quindi cerchiamo qualche stringa sospetta, magari proprio quella che ci compare nella msg box che Outlook Email Saver ci sbatte in faccia quando inseriamo il serial errato =)
Come? Bhè,usando Find Text =)
Troviamo una cosa alquanto sospetto qua:

4207FC: 27 LitVar_Missing         
4207FF: 27 LitVar_Missing         
420802: 3a LitVarStr:              ( local_00A0 ) Invalid Key Code
420807: 4e FStVarCopyObj           local_00C4
42080A: 04 FLdRfVar                local_00C4
42080D: f5 LitI4:                  0x0  0  (....)
420812: 1b LitStr:                 Invalid Unlock Code, please try again. If you have not ...
420815: 1b LitStr:                  
420818: 2a ConcatStr              
420819: 23 FStStrNoPop             local_008C
42081C: 1b LitStr:                  
42081F: 2a ConcatStr              
420820: 23 FStStrNoPop             local_0090
420823: 1b LitStr:                 (click the link at the bottom of the yellow form). 
420826: 2a ConcatStr              
420827: 46 CVarStr                 local_00B4
42082A: 0a ImpAdCallFPR4:          
Bhè, questa sembra essere la nostra message box, quindi la call che si trova all'interno della macchina virtuale e che viene chiamata dall'istruzione ImpAdCallFPR4 sarà rtcMsgBox, e ovviamente prima di arrivare a questa call andranno pushati vari parametri, eccoli spiegati:

LitVar_Missing, il cui opcode è 27, equivale a un push 00, il cui opcode è 6A00, quindi non si sarebbe visto di certo un push 00 in un disassemblato fatto con un altro disassembler =)

ed è logico che ce ne siano due, visto che la sintassi di una message box in VB è MsgBox([Text][, buttons][, title][, helpfile, context]), un totale di 5 parametri di cui 3 li definiamo, quindi il:

"LitVarStr( local_00A0 ) Invalid Key Code," equivale a un push dell'offest contenente la stringa "Invalid Key Code", ovvero il titolo della nostra mesagebox.

"LitI4: 0x0 0 (....)", equivale al push di un numero di 4 bytes che corrisponde allo stile della MsgBox, in questo caso corrisponde a VbInformation che mostra un'icona di informazione e un pulsante "OK".

I due "LitVar" serviranno per pushare il testo della message box e il codice fra loro per specificare che le due stringhe "Invalid Unlock Code .." e "(click the link..." vanno scritte separate di uan riga, vedi i due LitStr: seguiti nella riga dal nulla =).

Le altre operazioni non sono rilevanti e cmq da dead listing è un po' difficile capire che cosa facciano =).

Vediamo che prima di arrivare a questa msg box c'è dell'altro codice interessante:

4207E7: 1a FFree1Ad                local_0088
4207EA: 1e Branch:                 420865
4207ED: 00 LargeBos               
4207EF: 6c ILdRf                   local_00A4
4207F2: 1b LitStr:                 Incorrect 
4207F5: Lead0/30 EqStr            
4207F7: 1c BranchF:                420849
Vediamo che c'è un BranchF che salta oltre la Beggar Off di errore, e ancora prima c'è un Branch che va ancora più lontano.
"Salta? Hai detto salta?" eh si ho detto salta =) il Bracnh equivale a un JMP in assembler, quindi a un salto incondizionato, il BranchF invece è Branch if False, quindi corrisponde a un JNE/JNZ, mentre il al JE/JZ corrisponde BranchT, Branch if True.
E infatti sopra il salto condizionale c'è una istruzione che equivale a un cmp/test, ovvero EqStr o Lead0, si ha però sempre un push della stringa "Incorrect" prima di questo salto che viene confrontata, in quel Lead0 con una stringa che il programma mette in qualche offset,nn sappiamo dove, ma neppure ci interessa, sarà meglio allora nn arrivarci ma arrivare al Branch all'offset 4207EA, e per arrivarci, sempre andando indietro nel nostro disassemblato, vediamo che qua ci si arriva se non si salta al BranchF all'offset 4207B2, ma si vede che questo salto confronta la stringa "Skip" con un stringa in un offset, e la stringa "Skip" nn ci interessa, ci interessa invece la stringa "Correct" poco sopra e il BranchF che la segue e che sta all'offset 420788, ovvero questa:

420783: 1b LitStr:                 Correct 
420786: Lead0/30 EqStr            
420788: 1c BranchF:                4207A8
Se questo salta si arriva al BranchF seguente la scritta "Skip" e poi da lì evidentemente ad "Incorrect" dato che il BranchF a 4207B2 salterà visto che la stringa confrontata con "Skip" non sarà "Skip", ma se il BranchF che controlla "Correct" nn salta si arriva ad un salto incondizionato che ci manda a 420865 facendoci saltare la msg box d'errore:

42079D: 0d VCallHresult            CVBApplication::Load
4207A2: 1a FFree1Ad                local_0088
4207A5: 1e Branch:                 420865
Mmmmh proviamo allora a modificare questo BranchF all'offset 420788, ricorriamo al nostro fido editor esadecimale e cerchiamo di trovare quale sia l'opcode 1C giusto, bhè, proviamo a cercare questo 1C e i byte che gli stanno vicino, ad esempio "1b301c" o qls di più lungo, una volta trovato modifichiamo l'1C con un 1D, che è l'opcode del BranchT, in questo modo il programma ci darà il messaggio d'errore e ci butterà fuori dal programma un volta scaduti i 7 giorni, solo se inseriremo il seriale giusto. =)
Proviamo a inserirne uno a caso nell'Outlook Email Saver e TADAAA Registrazione avvenuta e ogni limitazione tolta, Good..ma, proviamo a chiudere il prog e a riavviare, D'ho!, non ci ritiene + registrati, ci sarà un controllo prima, e se nn lo abbiamo visto sopra, allora sarà dentro a qualche call precedente come

420763: 0a ImpAdCallFPR4:          4255d4
e sarà questo che dovremmo patchare, e magari se ci va di culo troveremo pure il serial..si, ma ora basta con il dead listing, ora si deve andare un po' più veloci, quindi, via con il debugger.. =)

Installiamo il WktVbDebugger, debugger user mode fatto apposta per i programmi compilati in P-Code che, anche se non è potente come SoftIce o OllyDbg, ci tornerà utile almeno ai fini del Cracking. Una volta avviato il file loader.exe facciamo Open e apriamo archiver.exe e una vota ke il file è stato "loaded succesfully" lo facciamo partite con "Action-Run", il WktVbDebugger ci dirà su che OS lo stiamo eseguendo..e vabbè..poi ci darà un'altra msg box con scritto "P-code section found at.." ..e vabbè..e poi finalmente partirà.
L'uso del debugger è piuttosto intuitivo, soprattutto per chi viene da SoftIce, dato che i comandi di Step Trace, Trace Ret e Trace Over si danno come in SIce con F8, F12 e F10, e per mettere un bpx basta fare doppio click sulla riga su cui si vuole mettere il breakpoint, nel caso questo offset fosse presente nella finestra e quindi non fosse possibile cliccarci sopra neppure scorrendo la finestra, si può premere Ctrl+E o il pulsante "On Execution" per far aprire una finestra in cui basterà mettere l'offset su cui desideriamo brekkare e premere "Add" per piazzare un bp a quell'indirizzo.
Se invece il bpx lo si vuol mettere su un'API o su una istruzione, allora basta cliccare su uno dei due pulsanti "API" o "OpCodes" per avere un elenco di tutte le API e anche di tutti gli opcodes (cosa di cui vi parlavo sopra).
Tornando al prog, cominciamo a steppare con F10 all'interno del debugger e continuiamo a steppare finchè non ci appare la prima finestra di Outlook Email Saver per dirci se vogliamo inserire il codice, continuare a usare il prog per il tempo restante o registrarci online, questa schermata iniziale non apparirà nella versione registrata ergo cerchiamo ora di capire per quale motivo nn si ritiene registrato.
Bene, la schermata incriminata appare dopo il
420763: 0a ImpAdCallFPR4:          4255d4

che è una call, so che questa istruzione si vede leggermente diversa nel debugger, ma se andate a vedere allo stesso offset, 420763, nel listato dell'exdec, trovate la stringa sopra riportata, che sia questa call a decidere se il serial è "Correct" e a non far quindi saltare il nostro BranchF all'indirizzo 420788? Bhè si fa presto a rispondere, andiamo a vedere da debugger =).
Una cosa da notare prima d andare a vedere questa call, è la diversità di quello che vediamo ora da quello che avremmo visto con SoftIce o OllyDbg, nel WktVbDebugger (WVD) c'è una finestra che appare cliccando su Edit, in questa finestra avete a sinistra il listato esadecimale e a destra quello che vedreste in SoftIce, vedete bene che all'indirizzo 420788 (dove in WVD ci da un BranchF) ho una cosa del tutto differente, per non parlare delle altre istruzioni =); questa finestra dell'edit è utile anche per fare un patching temporaneo come si fa con SoftIce, modificando però non l'istruzione ma il suo opcode, vedete bene che se si sostituisce quell'1C all'offset 420786 con un 1D e poi si fa "Patch Now" e si lascia correre il prog, questo si riterrà soddisfatto per la sua registrazione, ma, come abbiamo visto prima, al prossimo avvio ci dirà di nuovo che vuole essere comperato =).
Andiamo avanti con la nostra opera ora e rifacciamo partire il debugger ricordandoci di premere F8 quando siamo all'offset 420763.
Una volta entrati nella call andiamo avanti con F10 e vedeteche chiama delel call che stanno dentro la dll, le ImpAdCallI2, e che a un certo punto pusha la stringa "License" e poi "Settings", sembrerebbe dunque che siamo sulla strada buona, e la conferma la abbiamo quando pusha "Left" e "Settings", continuando a steppare arriviamo ad un BranchF, all'offset 4252CE, salto che viene eseguito e che ci fa apparire la schermata iniziale, sarebbe bello sapere cosa cavoli il programma confronti prima di decidere se far saltare o no questo salto, purtroppo nel WVD non possiamo vedere il contenuto dei registri =(.
Guardate però cosa c'è dopo quel salto, ovvero nel codice che eseguirebbe il prog se il salto non saltasse, c'è tra le altre cose, una "ImpAdCallFPR4 rtcGetPresentDate on adress ..." mmmh..il nome della call in questione ci fa pensare che questa call prende la data attuale e possiamo azzardarci a pensare che il prog la metta come data di installazione da cui poi partire per calcolare la data di scadenza da lì a sette giorni, bhè tagliamo la testa al toro e proviamo a invertire quel BranchF in un BranchT, ovvero andiamo nella finestra d Edit e modifichiamo l'1C all'offset 4252CE con un 1D cliccandoci sopra e sostituendo il valore.
Ora, andando avanti senza preoccuparci di quello su cui passiamo con F10 (ce ne occuperemo in seguito), arriviamo a un nuovo BranchF all'offset 425450, il salto non salta e dopo l'istruzione
 0d VCallHresult            CVBApplication::get_App 
la schermata appare, ma appare informandoci che la scandenza avverrà fra 7 giorni, avevamo pensato giusto, il programma usava la data avuta dalla GetPresentDate per lo scopo che avevamo supposto =).

Ora rifacciamo tutto daccapo, fino ad arrivare alla getPresentDate, quindi rimodificando il BranchF di prima, e vediamo cosa fa il programma prima di arrivare al BranchF che si trova a 425450, continuando a steppare, si vede che dopo la chiamata alla call :
425395: 0b ImpAdCallI2  rtcRightCharBstr on adress ....
otteniamo un numero di 8 cifre che varia a secondo del seriale immesso, e che quindi verosimilmente dipende da questo, che possiamo vedere nella finestra in basso dove comparirà "FStStrNoPop - NumeroOttenuto"
Purtroppo però è un po' difficile sapere da che operazioni fatte sul serial salti fuori questo numero dato che tutte le call che vengon chiamate prima della sua comparsa sono chiamate alla macchina virtuale e quindi non si possono tracciare usando il WVD, sarebbe però possibile vederle dal disassemblato della msvbvm60 o,una volta entrati nella dll da SoftIce, brekkando all'offset in cui il WVD ci dice che quella chiamata è stata eseguita.
Personalmente ritengo la cosa un po' suicida e non utile, anche se interessante, al momento =).
Andando ancora avanti si vede che viene pushata la stringa 4227-8723-5460-6119-1679, non esultate, non è il serial esatto con cui viene confrontanto quello immesso da noi =), però con la verifica del serial centra di sicuro anche se no sappiamo come dato che dopo c'è di nuovo una chiamata alla macchina virtuale =(.
Arrivando quindi al nostro BranchF che non salta, e facendolo saltare, sempre editandolo nel modo che abbiamo visto prima, ecco che appare il porgramam Outlook Email Saver che si ritiene regiatrato e, se con un hexeditor andiamo modificando i due 1C che abbiamo visto con due 1D faremmo si che il prog si ritenga registrato anche ad ogni successivo avvio.

Bene, abbiamo finito, parlato un po' d P-code, visto come usare il debugger (e speriamo che in futuro ci siano sue innovazioni dato che molte cose erano "Under construction") e crakkato un prog di cui, nel caso ce ne fosse bisogno, sapremo pure fare serial fishing =).
Ciao e BUON NATALEEEEEEEE
                     
                                               Pincopall


Note finali

Spero abbiate imparato qualcosa sul P-Code, purtroppo gli strumenti per reversarlo, se il prog usa la msvbvm60, non sono moltie molto efficienti, ma noi reversers si sa, siamo versatili e ce la caviamo sempre + o - bene =). E se non avete niente da fare, provate a fre serial fishing come vi ho detto sopra =)

Un ringraziamento va dunque a quelli che si sono prodigati nel creare questi strumenti, JosephCo per l'exdec e Mr Silver e Mr Snow dei WkT! per il WktVBDebugger.

Un caldo abbraccio e bacio a Maria che ha colorato questo form rendendolo moolto più bello (nel caso Quequero lo abbia riportato ai colori originali, sappiate, cari lettori, che prima questo form era tutto colorato con colori pastello)
Un saluto a Quequero (trattasi di estremo saluto se ha ricolorato il form, appena se ne accorge MAria..ghghgh) e a tutti i membri della da lui fondata UIC =)
Un saluto poi a tutti quelli he han joinato il Marc assieme a me pur qesto dicembre, Ded, Gipoco, Ra1n, Keeper, b3b0s, R3d5, mioCugino, Emilio e gli altri.

E a tutti voi gente
BUON NATALEEEEE

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. 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 ;))))