OllyDbg 1.09d
Tutorial

Data

by bender0

 

18/02/2004

UIC's Home Page

Published by Quequero


I don't care if Monday's blue
Tuesday's grey and Wednesday too

Grazie bender, ci voleva proprio un tute su Olly!

Thursday I don't care about you
It's Friday I'm in love

....

E-mail: [email protected]

....

tutti dicono che non si trovano tutorial sull'olly...ergo...eccovene uno! uff... 60k di tute!
scritto per i newbies che hanno poca esperienza (POCA VUOL DIRE CHE UN MINIMO DI ASSEMBLY LO DOVETE SAPERE...) o per chi vive a pane e softice e vuole conoscere questo prog.

x que: mi sono permesso di editare un pò il form, ti dispiace?
probabilmente rivedrò il tute per renderlo più leggibile e completo, e aggiungerò una sezione "hands-on" seria... per ora è tutto.


OllyDbg 1.09d
Tutorial
written by bender0

Introduzione

OllyDbg (anche grazie ai numerosi problemi di installazione di softice nei nuovi os) sta spopolando. E' un debugger che lavora in user mode, ovvero non può fare più degli altri programmi di win avendo gli stessi privilegi, il che è un difetto rispetto a s-ice. Ma per il "reversing di tutti i giorni" è comunque un ottima scelta, anche perchè è più potente di quanto sembri...

Tools usati

OllyDbg
Beh, se non lo volete solo contemplare questo tute penso che vi servirà! io ho la 1.09d (step 4)

URL o FTP del programma

Alla fine del tute c'è anche una sezione "hands-on": il nostro bersaglio sarà il crackme69 di Eimiar, molto semplice per cominciare. lo trovi alla uic... beh se stai leggendo queste righe dovresti esserci già dentro... ad ogni modo vedi quel grosso link rosso in cima alla pagina che recita "UIC's home page"? seguilo e vai alla sezione crackme.

Notizie sul programma

La protezione (nome\serial) del crackme è davvero basilare, ma lo scopo di questo tute è di isegnarvi a steppare con ollydbg... inoltre l'ho scelto perchè c'è una vulnerabilità interessante ;-) nel controllo del serial.

Essay

eccoci qua. direi di cominciare descrivendo la funzione di tutti i menu del prog.
NOTA: per chi non lo sapesse, un context menu è un menù popup il cui contenuto varia a seconda di dove si è clickato per farlo comparire, e che di solito è associato al tasto destro del mouse...


OLLYDBG - I MENU

->prima di File
c'è un icona che indica con una lettera la finestra attualmente maximizzata all'interno dell'olly. per navigare tra le finestre aperte o cliccate su questa icona e scegliete "successivo" o usate lo shortcut CTRL+F6. lo shortcut permette di attivare la finestra successiva in ogni momento (non è necessario che le finestre siano maximizzate). vedi la sezione "ollydbg - le finestre".

->File
Open (F3):
carica un eseguibile (*.exe) in ollydbg. anche tutte le librerie linkate staticamente all'eseguibile sono caricate ora, mentre quelle linkate dinamicamente sono caricate solo quando il programma lo richiede.
Attach:
apre una finestra con una tabella che permette di selezionare il processo IN ESECUZIONE a cui ollydbg si deve "attaccare"; praticamente puoi caricare in olly un programma "on the fly".
la tabella in ordine specifica:
id del processo - nome del processo - nome della finestra principale del processo - percorso del modulo associato al processo.
seleziona il processo che ti interessa e premi "attach" oppure esci con "cancel". cliccando col destro sulla tabella si apre un context menu che contiene utili opzioni per copiare tutta la tabella o parte di essa, oltre a delle opzioni per personalizzare la visualizzazione della tabella.
Exit (Alt+X):
esce da OLLYDBG, non dal processo che si sta debuggando. chiude (o almeno ci prova) anche il processo che si sta debuggando.
Recent files list:
sotto a Exit c'è una lista degli ultimi file caricati in ollydbg. per caricare l'ultimo aperto basta premere Ctrl+F2.

->View
Finestre:
vari comandi e relativi shortcut relativi all'apertura delle finestre di ollydbg. vedi la sezione "ollydbg - le finestre".
File:
praticamente un mini hex-editor all'interno di ollydbg. col context menu (click dx) permette di fare modifiche e salvarle nel file, creare backup, etc. se si carica un file PE e si sceglie special->PE header ollydbg isola il l'header PE e ne riconosce le varie parti "traducendole" nella colonna a destra. molto utile per avere informazioni sulle sezioni, etc.
Text file:
apre la finestra source caricando il file sorgente scelto. visualizza il numero della linea sulla sinistra.

->Debug
premessa: cercate di ficcarvi in testa gli shortcut di questi comandi se volete usare ollydbg!

Run (F9): esecuzione libera
il comando cede in controllo al programma debuggato che può eseguirsi liberamente. quando si carica un modulo in ollydbg di default lui si ferma sull'entry point in modalità PAUSED. con questo comando si "fa partire" il programma. se durante l'esecuzione dei breakpoints vengono attivati il controllo ritorna all'olly che si mette in modalità PAUSED. per ripristinare l'esecuzione del programma usare questo comando.
Pause (F12): pausa (ma va?)
ollydbg ferma l'esecuzione del programma debuggato e si prende il controllo. quando il programma è in modalità PAUSED si può steppare, modificare i registri, e fare molte cose che ci piacciono tanto!
Restart (Ctrl+F2): ricomincia da capo
ricarica il programma dall'entry point in modalità PAUSED proprio come se l'aveste appena aperto. utile quando si è fatto qualche casino irreversibile o se si deve semplicemente ricominciare tutto da capo!
Close (Alt+F2): chiudi
chiude il programma debuggato.

Step into (F7): passo e entra
questo comando, che può essere utilizzato solo in modalità PAUSED, fa avanzare l'esecuzione del prog di UNA istruzione. se l'istruzione da eseguire è una chiamata a funzione (call) vi ritroverete dentro la funzione.
Step over (F8): passa sopra
questo comando, che può essere utilizzato solo in modalità PAUSED, fa avanzare l'esecuzione del prog di UNA istruzione. se l'istruzione da eseguire è una chiamata a funzione (call) tale funzione viene eseguita e vi ritroverete all'istruzione che seguiva la chiamata.
Animate into (Ctrl+F7):
simula una serie di "step into", come se si tenesse premuto il tasto F7. il programma viene eseguito passo-passo finchè non si preme esc o un comando di controllo (F7,F8,F9,F12...). l'animate può fermarsi anche se si incontrano breakpoint o se si verifica un eccezione.
Animate over (Ctrl+F8):
simula una serie di "step over", come se si tenesse premuto il tasto F8. il programma viene eseguito passo-passo finchè non si preme esc o un comando di controllo (F7,F8,F9,F12...). l'animate può fermarsi anche se si incontrano breakpoint o se si verifica un eccezione.
Execute till return (Ctrl+F9): esegui fino al return
il programma viene eseguito finchè non si incontra un'istruzione di ritorno da chiamata (come ret). se entrate per errore in una funzione sulla quale invece volevate "passare sopra" è il modo più rapido per uscirne.
Execute till user code (Alt+F9):
comando molto utile. se (ad esempio per un breakpoint) l'esecuzione si ferma in una dll di sistema, questo comando esegue il programma finchè non incontra un istruzione non di sistema.
-ESEMPIO-
avete messo un breakpoint on execution su una API X che risiede in una dll. dopo averne ripristinato l'esecuzione con F9, il programma che state debuggando chiama una API Y, la quale chiama un'altra funzione in un'altra dll, la quale chiama la API X sulla quale avete messo il breakpoint. l'esecuzione si ferma e vi trovate persi e non riuscite a steppare fuori da queste dll. premendo Alt+F9 vi ritrovate all'interno del codice del programma subito dopo la chiamata alla API Y.
-FINE ESEMPIO-

Open or clear run trace:
serve per iniziare una sessione di run trace (vedi sotto) oppure a svuotare il buffer di run trace per ricominciare.
Trace into (Ctrl+F11):
l'esecuzione in run trace è per certi versi simile all'animate, olly esegue il programma step by step (entrando nelle funzioni con trace into e saltandole con trace over). ci sono però due differenze fondamentali:
1) il run trace si ferma anche se si incontrano certe condizioni settate dall'utente (vedi set condition).
2) durante il run trace olly salva in un buffer i contenuti dei registri e tutto quello che serve per consentire lo "step all'indietro".
si, avete sentito bene, all'indietro... ovviamente non si riavvolge l'esecuzione del programma ma si può vedere cosa ha fatto durante il run trace. una volta fatto partire il run trace, fermatelo (con F12 ad esempio) e premete il tasto - (meno): olly ci mostra cosa succedeva al comando precedente, e così via. ovviamente tasto + per tornare avanti. notate che la sezione registri e la zona sotto il disassemblato si scuriscono? serve ad indicare che il cursore non è all'attuale punto di esecuzione del programma, ma più indietro (mi viene da dire "nel passato"!).
per capire le potenzialità aggiunte del run trace, vedi set condition.
Trace over (Ctrl+F12):
vedi trace into.
Set Condition (Ctrl+T):
bene, Ctrl+T e si apre una finestrella. vi sono vari tipi di "condizioni" che si possono settare per stoppare il run trace. vediamole:
EIP is in range -> stop se l'istruzione da eseguire si trova nel range specificato.
EIP is outside the range -> stop se l'istruzione da eseguire si trova fuori dal range specificato.
Condition is TRUE -> stop se si verifica la condizione specificata. per la sintassi delle condizione vedere "Evaluation of expressions" nell'help di ollydbg. un esempio? 'eax = 1' oppure 'al = cl' o ancora 'eax == "Seriale esatto!"' (in quest'ultimo caso eax è considerato un pointer a stringa).
Command is suspicious or possibly invalid -> stop se l'istruzione da eseguire è da considerarsi non valida. per settare che istruzioni devono essere considerate non valide nelle debugging options (Alt+O) scegliere il tab analysis 3.
Command is one of -> stop se l'istruzione da eseguire è del tipo specificato. la sintassi è semplice, farò alcuni esempi:
xor r8,r8 -> uno xor tra due registri a 8 bit qualsiasi (al,bl,cl...)
add r32,r32 -> un add tra due registri a 32 bit (per es. add ecx,edx)
cmp r32,CONST -> confronto tra un registro a 32 bit e una costante numerica (per es. cmp eax,1)
jcc OFFSET -> salto condizionale a un offset qualsiasi
ce ne sono altri, li potete trovare nella guida dell'olly sotto "assembler" dove dice "imprecise commands".
Close run trace:
svuota il buffer del run trace.

Hardware breakpoints:
con ollydbg si possono settare 4 breakpoint "hardware". con questi si può breakkare nel prog senza sostituire un int3 all'istruzione. non si possono settare da qui, ma con il context menu sulla cpu window (vedi "ollydbg - le finestre"). da qui puoi cercarli nel disassemblato o eliminarli.
Inspect:
bene, l'inspector serve a visualizzare il contenuto di un array mono- o bi-dimensionale in una tabella di cui potete specificare le dimensioni. non capisco come usarlo per un'array 2d, ma se ad esempio specificate "[eax+4*%A]" con un range per %A di ad es. 10 e 1 per %B vedrete la dword puntata da eax e i 9 valori successivi. pratico per visualizzare strutture.
Arguments:
permette di specificare gli argomenti passati al prog debuggato quando viene lanciato. se l'avete già lanciato dovete riavviarlo per vedere gli effetti (ovviamente!). provate a specificare il percorso di un file *.txt e lanciare il buon vecchio notepad e... MAGIA!... notepad si apre proprio con quel file!
Select import libraries:
serve a caricare dei file *.lib che olly userà per sostituire i nomi delle funzioni esportate dalle dll caricate ai rispettivi ordinali.
Select path for symbols:
specifica la cartella da dove olly andrà a leggere i file con le informazioni simboliche di debug.


->Plugins
visualizza dei menù relativi ai plugin caricati all'avvio da ollydbg. quelli distribuiti assieme al prog sono 2:
Command line
utilissimo plug-in che permette di inserire comandi in command-line come su s-ice. si apre con Alt+F1.
i comandi che ci interessano di più (breakpoints!):
bp [nome api\indirizzo] -> per settare breakpoint on execution (come il bpx in softice). attenzione: al contrario di softice olly è molto fiscale riguardo ai nomi della API qui specificati, in termini di maiuscole\minuscole.
bpx [...] -> strano comando. qualsiasi cosa si scriva dopo bpx si apre una finestra che contiene tutte le chiamate a API che partono dal modulo che si sta debuggando... o il mio pc è andato a puttane...
bc [nome api\indirizzo] -> per rimuovere il break sulla API o all'indirizzo specificato.
mr [start addr] [end addr] -> setta un memory breakpoint sull'accesso a un certo range in memoria, specificato da start e end.
mw [start addr] [end addr] -> setta un memory breakpoint sulla scrittura in un certo range in memoria, specificato da start e end.
md -> rimuove il memory breakpoint attivo (settato con mr o mw)
hr [indirizzo] -> setta un breakpoint hardware che scatta quando si accede alla memoria all'indirizzo specificato.
hw [indirizzo] -> setta un breakpoint hardware che scatta quando si scrive sulla memoria all'indirizzo specificato.
he [indirizzo] -> setta un breakpoint hardware che scatta quando si esegue l'istruzione all'indirizzo specificato.
hd [indirizzo] -> elimina il breakpoint hardware all'indirizzo specificato.
Bookmarks
semplice sistema di bookmarks (segnalibri) ovvero parti del codice dove vogliamo tornare spesso senza ricordarci l'indirizzo a memoria... per aggiungere un bookmark cliccare col destro nella code window e scegliere bookmark->insert bookmark X.

->Options
Appearance
apre una finestra che contiene NUMEROSE opzioni di visualizzazione che per la maggior parte si spiegano da sole.
la sezione code highlighting permette di personalizzare il modo in cui ollydbg visualizza i vari opcode nel disassemblato. è un opzione molto utile ma... a me non funziona e non so perchè... se qualcuno lo sa mi scriva!
Debugging options (Alt+O)
apre una finestra che contiene tutte le opzioni di debug di ollydbg (sono TANTISSIME). vediamo i menù più importanti:
-Exceptions: consente di specificare quali eccezioni ignorare (ovvero passare al programma) tra quelle note, e anche di specificare un range di eccezioni da ignorare (io le ignoro TUTTE, cioè 00000000 .. FFFFFFFF per non avere problemi).
-Events: si può scegliere dove si deve pausare il programma quando viene caricato, prima che il sistema chiami il nostro programma, all'entry point (lo consiglio) o alla winmain. si può anche dire all'olly di fermarsi se vengono caricate\rilasciate dll, se vengono avviati\terminati thread, o se il programma chiama OutputDebugString per farci sapere qualcosa. da modificare a seconda della situazione, perchè puo diventare molto fastidioso - provate a reversare winamp 5 con le opzioni delle dll e dei thread attivate e capirete cosa intendo.
-Disasm: opzioni relative all'output disassemblato nella finestra CPU. giocateci un pò e vedete con quali vi trovate meglio.
-Cpu: consiglio di mettere la v su "show direction of jumps" e su "show jump path", che rendono più facile seguire visualmente il flow del programma.
le altre opzioni sono buone di default (imho), ma ciò non vi impedisce di smanettare...
Just-in-time debugging
configura ollydbg per essere\non essere il debugger just-in-time, ovvero il debugger che windows lancia se un programma crasha. c'è anche l'opzione per "attaccarsi" al programma crashato senza chiedere conferma.
Add to explorer
aggiunge\toglie l'opzione "Open with ollydbg" al context menù che si apre con un click destro su un file .exe in explorer.

->Window
contiene le solite opzioni per organizzare le finestre aperte (tile,cascade...) e la lista di quelle aperte per saltare da una all'altra.

->Help
About
che dire della about box? carina. mi piace l'icona dell'olly...c'è ADDIRITTURA un link al sito! ;-)
Contents
apre l'help file di ollydbg.
Select API help file
permette di selezionare la tua guida delle API preferita che in seguito può essere aperta con il successivo menù.
Open API help file
apre la guida selezionata col menù precedente.


OLLYDBG - LE FINESTRE
ecco le finestre nell'ordine in cui sono listate nel menu view:

->Log
un semplice log, con informazioni sui plug-in caricati, moduli caricati e scaricati ecc ecc.
->Executable Modules
i moduli attualmente caricati nell'olly. contiene anche path del modulo, versione, nome ms-dos...
interessante l'opzione del context menu "view all resources" che crea un'elenco delle risorse del modulo, che si possono dumpare su disco con il context menu di questa finestra.
->Memory
mappatura di tutta la memoria assegnata all'eseguibile debuggato. olly riconosce a che modulo appartiene ciascuna sezione di memoria. per dumpare una sezione di memoria: con right click->dump si apre una dump window, da cui right click->backup->save data to file e il gioco è fatto! se ad esempio dumpate tutte le sezioni di un modulo e le rimettete assieme con un hex editor, se il programma non fa scherzi a run-time otterrete un dump funzionante!
->Heap
non funziona su nt, e non l'ho mai provato. la guida di ollydbg dice che questo comando mostra una lista dei blocchi di memoria allocati dal programma in uno dei suoi heap.
->Threads
lista di tutti i threads relativi al processo attivo in ollydbg, e alcune informazioni extra come l'ultimo errore avvenuto nel thread, il suo stato e la sua priorità. usando la stessa procedura che ho descritto a proposito della memory window, si può dumpare un thread!
->Windows
lista delle finestre aperte dall'applicazione con id, stili, classe di appartenenza... per chi non lo sapesse, anche i control (bottoni, edit ecc...) sono finestre. se ad esempio tra i parametri di una chiamata alla GetDlgItemTextA vedete che pusha come id del control "3E8" qui potete vedere che tipo di finestra è, il testo associato (titolo) e quant'altro.
la vera potenzialità di questa finestra sta nella possibilità di settare breakpoints (anche condizionali) sulla classproc della finestra, e già così potreste intercettare un messaggio di WM_GETTEXT con due click sul context menù... per facilitarvi ulteriormente la vita, c'è addirittura una funzione di break sui messaggi (sempre nel context menù) che offre anche una lista dei messaggi di windows per fare prima.
quindi potete tranquillamente trovare il punto d'attacco di quei crackme che pensano di fotterci usando SendMessage con WM_GETTEXT invece che GetWindowText o simili.
->Handles
lista di tutte le handle aperte dal programma debuggato, che contiene files e directory aperte, chiavi del registro...
->CPU
uff eccoci qua, al CORE di olly. la CPU window è la finestra più complessa, più potente e più utile di ollydbg, e per ogni opera di reversing (che pomposo!) l'avrete SEMPRE aperta. è quello che fa la differenza tra olly e softice: olly fonde un eccellente debugger con un buon disassembler. anzi, il disassemblato di olly è migliore di quello del wdasm della ursoft e viene prodotto in brevissimo tempo. olly individua provenienza e destinazione di salti e call, routines, loops, switches e altre cose notevoli automaticamente e le evidenzia graficamente rendendoci più facile lo stepping. olly decodifica i parametri pushati alle funzioni del c e alle API, convertendo i numeri nelle costanti simboliche corrispondenti. olly a runtime tiene d'occhio la memoria puntata dai registri e dagli offset e vi segnala se c'è qualcosa di interessante (come una stringa). l'analisi del codice può essere fatta in qualsiasi momento, quindi se vi trovate un prog che si decrypta a runtime, steppatevi il loader fino all'OEP (original entry point) e rianalizzate il codice, e in mezzo secondo vedrete il disassemblato delle istruzioni decryptate come su softice. per questi motivi, e data la centralità dell'argomento, vedrò di dare adeguato spazio e di spiegare tutto il mecessario per permettervi di ammaestrare l'olly.

prima di cominciare, rapido riassunto degli shorcuts di debug essenziali (vedi "ollydbg - i menu" sotto "debug"):
F3 - open file
F9 - run
F12 - pause
Ctrl+F2 - restart
Alt+F2 - close
F7 - step into
F8 - step over
F2 - set breakpoint at selected address

vediamo le 4 parti della CPU window:
in alto a sx: disassembler window -> disassemblato del file e "centro di comando"
in alto a dx: registers window -> visualizza il contenuto dei registri
in basso a sx: dump window -> visualizza il contenuto della memoria
in basso a dx: stack window -> visualizza lo stack


Disassembler
la finestra più importante. dopo qualche secondo dal caricamento (F3) di un prog, olly metterà qui il disassemblato della sezione che contiene l'entry point, avvisandovi se si trova fuori dalla sezione code. sull'entry point (se non avete specificato diversamente nelle opzioni) verrà posizionato il cursore dell'istruzione corrente, cioè vedrete a sx l'indirizzo dell'istruzione a colori invertiti (lo sfondo nel colore del testo e viceversa). il vostro cursore invece è quella fascia di disassemblato più scura (a meno di color schemes psichedelici) con la quale potete selezionare una o più linee di codice per i vostri scopi.

analizziamo la finestra: dovreste vedere quattro colonne più uno spazio in basso.
1.la colonna più a sx contiene gli indirizzi in memoria. tutto il resto si basa su questi indirizzi. l'indirizzo dell'istruzione corrente è evidenziato.
2.la seconda colonna contiene informazioni sul codice a livello grafico. le grandi "parentesi" nere rappresentano le routine. le freccine rappresentano la direzione su\giu del jump a quella riga o la destinazione di altri jump. le "parentesi" in rosso più sottili indicano il percorso di un jump, e si vedono se si seleziona un'istruzione jump o la destinazione di un jump. se non vedete qualcuna di queste cose, andate nella sezione "ollydbg - i menù" e cercate il menù opzioni->CPU, lì spiego come attivarle.
3.nella terza colonna c'è il disassemblato.
4.la quarta colonna serve a olly per scriverci ogni cosa notevole. se un registro mentre steppate contiene un puntatore a stringa, vedrete la stringa. se il prog sta pushando i parametri per una call ad una funzione nota, vedrete una "parentesi" nera che contiene i parametri pushati (nome del parametro in grigio e valore in nero) e la call, ovvero il nome della funzione in rosso. se l'istruzione è sospetta (per impostare quali istruzioni sono da ritenersi sospette,nelle debugging options (Alt+O) scegliere il tab analysis 3), viene scritto. e altre cose che non mi vengono in mente...
5.lo spazio in basso ha una funzione simile a quella della quarta colonna, ma lavora più in dettaglio. mostra informazioni relative all'istruzione corrente: contenuti dei registri coinvolti, se un salto condizionale verrà eseguito o no, destinazione dei salti, indirizzi da cui si salta all'istruzione corrente, etc etc etc...

vediamo il context menù:

|
|----
|-backup:
| ^ salva tutta la sezione di memoria nella disassembler window in un backup
| ^ che si può ripristinare in seguito. inoltre può salvare tutto in un file.
|-copy:
| ^ il solito: copia la selezione negli appunti (Ctrl+C) o in un file.
| ^ ci sono anche opzioni per la selezione rapida.
|-binary:
| ^ edita la selezione in hex, riempie di 00 o di NOPs, copia\incolla gli opcode selezionati.
|-assemble (space):
| ^ apre una finestra dove inserire un'istruzione in asm che sovrascriverà la corrente in memoria. utilissimo quando si cracka!
| ^ conviene usare "fill with NOPs" per non generare istruzioni non valide con i byte
| ^ rimanenti dopo le modifiche... così saranno sostituiti con degli innocui nop.
|-label (:):
| ^ da un nome (etichetta) all'indirizzo specificato. olly sostituisce tutte le referenze a questo indirizzo con l'etichetta.
|-comment (;):
| ^ serve a commentare il codice. i commenti compariranno nella quarta colonna.
|-breakpoint:
| ^ comandi relativi ai breakpoint dei quali ho già parlato, più run to selection (F4),
| ^ che esegue il programma fino all'istruzione selezionata.
|-hit trace:
| ^ permette di aggiungere alle zone di hit trace la selezione, la procedura selezionata, tutte le procedure...
| ^ le zone di hit trace vengono segnate con un quadratino grigio a fianco che diventa rosso se vengono eseguite.
|-run trace:
| ^ ho parlato diffusamente del run trace su "ollydbg - i menù" debug->run trace.
|----
|-new origin here:
| ^ assegna a EIP l'indirizzo dell'istruzione selezionata. spesso il prog crasha dopo di questo...
|-go to:
| ^ permette di saltare a vari punti del disassemblato, tra cui l'origin (cioè eip),
| ^ il valore di un espressione che verrà valutata, la prossima routine e la precedente (Ctrl++ e Ctrl+-).
| ^ con + e - si può navigare tra le ultime istruzioni eseguite, ma è consigliabile il run trace per questo scopo.
|-follow in dump:
| ^ a seconda di che tipo di istruzione state selezionando e della validità dei valori in gioco potrete visualizzare
| ^ nella dump window l'istruzione corrente, o la memoria puntata da costanti o registri.
|-view call tree (Ctrl+K):
| ^ visualizza l'albero delle chiamate, ovvero l'elenco gerarchico delle routine che hanno chiamato la corrente.
|----
|-search for:
| ^ permette di cercare nel disassemblato molte cose... ma facili da capire, basta leggere i comandi nel context menù.
|-find references to:
| ^ permette di cercare delle referenze all'istruzione selezionata (Ctrl+R), alle varie costanti o variabili usate dall'istruzione,
| ^ alla destinazione del salto e così via...
|-view:
| ^ per vedere il profilo (numero di esecuzioni per ogni istruzione) al posto dei commenti a destra,
| ^ per vedere il file eseguibile originale e per cambiare (a sx) tra indirizzi assoluti e relativi a quello selezionato.
|-copy to executable:
| ^ copia la selezione o tutte le modifiche fatte al programma in memoria e le trasporta nel file originale.
| ^ se fate una patch in memoria e vedete che funziona, così potete "salvarla".
|-analysis:
| ^ ri-analizza o rimuove l'analisi dal codice (utili per crypters e smc), e passa al setaccio i file *.obj e *lib
| ^ in cerca di nomi simbolici da usare nel disassemblato. "assume arguments" costringe l'olly a considerare
| ^ l'indirizzo selezionato come entry point di una funzione con certi argomenti, selezionabili da una lista.
|-help on symbolic name (F1):
| ^ olly apre la guida API selezionata nel menù help (vedi "ollydbg - i menù") e cerca il nome simbolico selezionato all'interno della guida.
|-bookmark:
| ^ vedi "ollydbg - i menù" sotto plugins->bookmarks.
|----
|-appearance:
| ^ solite opzioni di visualizzazione.
|----


Registers
in ogni momento qui vedrete il contenuto dei registri. cliccando sulla barra in alto si cambia tra i registri FPU, MMX e 3dNow!, ma in ogni caso il set standard di registri e flag (che poi sono quelli che ci interessano) viene sempre visualizzato. se un registro punta a una stringa tale stringa comparirà vicino al registro. lo stesso vale per le locazioni del codice: olly vi mostrerà dove punta il registro (a che modulo e l'indirizzo) e se è l'indirizzo di una funzione nota, lo sostituirà con il nome di tale funzione. ora vediamo come interagire con i registri.
clickate col tasto dx su un registro standard e comparirà un context menù che conterrà (al massimo) queste opzioni:

|
|----
|-increment (+):
| ^ aumenta di 1 il valore del registro
|-decrement (-):
| ^ diminuisce di 1 il valore del registro
|-set to 1:
| ^ assegna il valore 1 al registro
|-modify (enter):
| ^ apre una finestra nella quale inserire il nuovo valore per il registro
|-copy to clipboard:
| ^ copia il contenuto del registro negli appunti
|----
|-follow in disassembler:
| ^ cerca nel disassemblato l'istruzione puntata dal registro e ci posiziona il cursore.
| ^ disponibile solo se il puntatore punta a del codice.
|-follow in dump:
| ^ cerca nella memoria del prog debuggato l'area puntata dal registro e la carica nella dump window.
| ^ disponibile solo se il puntatore punta a una valida zona di memoria nell'address space del programma.
|-follow in stack:
| ^ cerca nello stack l'indirizzo puntata dal registro e posiziona la stack window a quell'indirizzo.
| ^ disponibile solo se il puntatore punta allo stack.
|----
|-view (FPU,MMX,3dNow!,debug) registers:
| ^ specifica i registri non standard da visualizzare.
|----
|-appearance:
| ^ solite opzioni di visualizzazione.
|----

nota: per i registri non standard ci sono funzioni specifiche, e alcuni registri, come eip e i registri di debug, non si possono modificare. almeno non così... ad esempio eip si può modificare dalla finestra del disassemblato.

Dump
questa finestra serve a visualizzare aree di memoria in vari formati, che si possono scegliere nel context menù. potete vederla come hex bytes con l'ascii a fianco (cosa che farete molto spesso) oppure come solo testo o ancora come numeri in vari formati (short, long, float). potete vederla anche come disassemblato, quindi olly può disassemblare QUALSIASI area della memoria, che sia una sezione .text, .data, .rsrc o qualcos'altro. inoltre c'è l'opzione PE header - se c'è un valido header da qualche parte nell'area di memoria visualizzata, olly lo decodificherà nelle sue varie parti (dos signature, pe, con le descrizioni delle varie sezioni etc etc).
sempre con il context menù, potete operare sulla memoria:
backup -> per creare un backup dell'area di memoria selezionata, che si può facilmete ripristinare. anche per dumparla in un file.
copy -> copia l'area selezionata negli appunti o in un file, o seleziona tutto.
binary -> per editare la memoria in hex, riempire di 00 o di FF, e copiare\incollare zone di memoria.
search for -> consente la ricerca di stringhe o labels nella memoria caricata nella dump window
le altre opzioni le abbiamo già viste per la CPU window e comunque servono a poco qui.

Stack
la finestra stack visualizza... lo stack! o meglio, lo stack del thread corrente. ovviamente olly vi segnala ogni pointer a stringa o a sezioni di codice nello stack, quindi se viene pushato l'indirizzo di una stringa vedrete alla prima riga l'indirizzo E la stringa. vediamo il context:

|
|----
|-address:
| ^ cambia il modo di visualizzazione degli indirizzi dello stack (la colonna più a sx).
| ^ absolute li mostra come indirizzi in memoria, relative to ESP\EBP come ad es. "ebp+4",
| ^ relative to selection come per ESP\EBP ma usa l'indirizzo selezionato come riferimento.
|-show ASCII dump:
| ^ aggiunge una colonna con la "traduzione" in ascii dei valori dello stack.
| ^ è un comando potenzialmente inutile.
|-show UNICODE dump:
| ^ vedi sopra...
|-lock\unlock stack:
| ^ lo stack normalmente si auto-posiziona sempre allo stack top, così si disabilita questa feature.
|----
|-copy to clipboard (Ctrl+C):
| ^ copia indirizzi e valori selezionati negli appunti.
|-modify:
| ^ semplice finestrella per editare i dati all'indirizzo selezionato.
|-edit:
| ^ sempre per editare (anche più righe), ma più completa, con ascii\unicode\hex.
|-search for address:
| ^ trova nello stack il valore specificato.
|-search for binary string (Ctrl+B):
| ^ permette di specificare una search pattern e ne trova la prima ricorrenza.
| ^ specificando "56 ?? FF ?A" si può trovare ad es. "56 45 FF 4A".
|----
|-go to esp (*):
| ^ porta all'indirizzo dello stack puntato da esp.
|-go to ebp:
| ^ porta all'indirizzo dello stack puntato da ebp.
|-go to espression:
| ^ calcola il valore dell'espressione specificata e si posiziona su quell'indirizzo.
| ^ "ebp-eax" porterà all'indirizzo puntato da ebp meno eax bytes.
|----


->Patches
lista delle patch (attive e non), ovvero le modifiche apportate dall'utente nel codice del programma debuggato. le istruzioni per patchare sono nella sezione CPU window. con la space bar (oltre al classico context menu) attivate\disattivate una patch. con del la potete rimuovere, ma vi consiglio di disattivarle e basta perchè possono sempre tornare utili. con enter il cursore della CPU window si posiziona sul primo byte della patch.
->Call stack
permette di visualizzare il call stack (ma daveeeeero?), ovvero l'indirizzo a cui deve ritornare la procedura corrente finita la sua esecuzione più tutti gli altri delle routine che hanno chiamato la corrente. ovviamente in puro stile stack gli indirizzi di ritorno più "vicini" li vedrete apparire all'inizio della lista. se steppate un pò un prog (con step into (F7) mi raccomando altrimenti è inutile) vedrete i nuovi return addresses che si aggiungono in cima alla lista e li vedrete sparire a fine call.
->Breakpoints
la lista dei breakpoint (attivi e non) che avete settato sul codice del programma. da qui potete individuarli nella cpu window (enter), modificare la loro condizione di break, abilitarli\disabilitarli (space bar) e cancellarli (del) usando il context menu o con gli shortcuts.
->Watches
apre la finestra degli watch. un watch è semplicemente un espressione che viene valutata continuamente mentre il programma debuggato è in esecuzione. per esempio, se scriviamo "eax" olly ci dirà il contenuto del registro eax; se scriviamo "[eax]" ci dirà a che valore punta eax e così via.
->References
finestra che si apre quando si cercano referenze a un comando o a un indirizzo e che le lista tutte. vedi CPU window.
->Run Trace
dopo aver eseguito un run trace (vedi il menu "debug") in questa finestra si vedono tutte le istruzioni che il programma ha eseguito prima di essere fermato; ovviamente entro i limiti di buffer che si settano nelle debuggin options (Alt+O) nel tab "trace". oltre alle istruzioni ci sono gli indrizzi a cui si trovano, i moduli a cui appartengono, i thread che le hanno eseguite e (importante) i registri che hanno modificato, con il valore modificato. c'è un opzione carina nel context menù che permette di evidenziare un registro per seguire meglio i suoi cambiamenti.
->Source
mmmh... non ho mai provato a debuggare con il sorgente (siamo reverser, in fondo). ad ogni modo questa finestra dovrebbe solo far vedere il codice sorgente (quando disponibile). inoltre - stando alla guida - se il programma debuggato ha le informazioni di debug in formato borland permette di trovare il punto esatto nei sorgenti che corrisponde all istruzione corrente nella cpu window.
->Source files
mostra i file contenenti i sorgenti e i moduli corrispondenti (sono un poeta!). ripeto, non ho mai usato queste features quindi non vi posso assicurare niente...


OLLYDBG - HANDS ON: CM69 by Eimiar

darò una spiegazione ESAUSTIVA del processo di keygenning di questo crackme.

->Analisi iniziale
prima di tutto lanciate l'eseguibile per studiarlo... prova2.exe? che nome è? ok apparte questo, nome\serial, la about box ci dice solo che dobbiamo fare un keygen, la finestra è in tipico stile dialog il che ci orienta verso GetDlgItemText per breakkare.
se avete PEditor o qualsiasi altro programma veloce che visualizza gli imports e le sezioni, usatelo ora. con un'occhiata alle sezioni o alle funzioni importate si può individuare in un attimo se il prog è packato\cryptato (non andrebbe molto lontano importando solo LoadLibrary e GetProcAddress, no?). in questo caso vediamo DialogBoxParamA e GedDlgItemTextA e molte altre, inoltre le sezioni sono perfettamente normali quindi... si procede con il debugger! fine analisi...

->Reversing della routine
lanciate ollydbg e caricate il file (F3). finita l'analisi del codice (olly è molto veloce) il cursore si ferma all'entry point (anche il programma :-). date le modeste dimensioni del crackme potreste trovare il punto d'attacco solo scorrendo il codice nella CPU window ma... facciamo le cose per bene. ricordate gli imports? Alt+F1 e nella command-line scrivete "bp GetDlgItemTextA" (occhio alle maiuscole!) per settare un breakpoint on execution su tale API. potete amministrare i breakpoint nella apposita finestra (Alt+B). ora eseguite il programma (F9) e scrivete "bender0"... ERR... il vostro nick nel campo nome e il vostro codice fiscale o numero di telefono o quel c***o che volete nel campo serial. premete Try it! e incrociate le dita... boom! l'olly prende il controllo.

vi ritrovate in user32.dll. ora dovete uscirne, quindi o usate execute till return (Ctrl+F9) e poi steppate sul return per ritrovarvi dopo la chiamata alla API, oppure più semplicemente usate execute till user code (Alt+F9) che fa da solo. vi trovate all'indirizzo 4010DE: nelle 5 righe precedenti vedete i parametri da passare a GetDlgItemTextA e la call. vedete come olly vi risolve i parametri? e non è tutto... vedete che pusha esi come "buffer"? durante la chiamata esi non viene modificato, quindi guardate a destra i registri: esi contiene l'indirizzo in memoria del buffer che contiene il vostro nome, e l'olly è così carino da scrivercelo a fianco! segue un'altra chiamata a GetDlgItemTextA per il serial, vedete che il "buffer" è in ebp. disabilitate il breakpoint su GetDlgItemTextA usando la breakpoint window (Alt+B) (non viene visualizzato il nome della API ma l'indirizzo, ad ogni modo sotto "module" c'è scritto user32 quindi...). abbiamo tolto il break perchè adesso andiamo a steppare over (F8) l'altra chiamata a GetDlgItemTextA e al posto di passarci sopra come vogliamo olly avrebbe breakkato proprio sulla API. steppata la call, vedete a destra su ebp l'indirizzo del buffer e il vostro serial.

ora vedrete questo (i commenti li ho aggiunti io, per commentare il codice premete ';' col cursore sulla linea desiderata):

004010E9 MOV EDI,ESI ; sposta in edi l'indirizzo del nome
004010EB OR ECX,FFFFFFFF ; ecx = -1
004010EE XOR EAX,EAX ; eax = 0
004010F0 MOV EBX,DWORD PTR DS:[<&USER32.MessageBoxA>]
004010F6 REPNE SCAS BYTE PTR ES:[EDI] ; scorre la stringa finchè non incontra uno 0, e ogni volta diminuisce di 1 ecx
004010F8 NOT ECX ; ecx viene negato (ribaltato nei positivi)
004010FA DEC ECX ; e diminuito di 1, ora contiene la lunghezza del nostro nome
004010FB CMP ECX,3 ; confronta la lunghezza con 3
004010FE JNB SHORT prova2.0040110F ; se la lunghezza del nome NON è MINORE di 3, salta la messagebox di errore e prosegue

capito? controlla la lunghezza del nome che deve essere almeno 3 caratteri (ho riportato il codice perchè ne vedrete parecchi di questi controlli). steppate queste righe e (se non avete un nick da 2 caratteri :-) salterete la chiamata a messageboxa e potrete proseguire. notare che, messagebox o meno, il controllo del codice continua, non vi butta fuori. vi sarete accorti che segue un controllo uguale per la lunghezza del serial... steppatelo allegramente e salterete anche la parte che vi butta fuori! così se non si scrive niente o quasi in entrambi i campi, escono DUE messagebox scassac***o E POI vi butta fuori. non è carino.

ora vi trovate all'indirizzo 40113E. e indovinate? ora il prog RICONTROLLA la lunghezza di nome e codice... che bello! steppate pure. dopo questi altri 2 check a 401162 c'è una routine quasi uguale (oh nooooooo)... la differenza e quel je alla fine, praticamente qui controlla che il nome non sia di zero caratteri (ma non ne sei ancora convinto?!?).

eccoci a 401170. alla prima riga viene caricato in ebp l'indirizzo di una particolare stringa, "0123456789:;<=>?@ABCDEFGHIJKL", che chiameremo keystring. notare che poche linee fa ebx è stato azzerato, perchè ora farà da counter.

00401170 LEA EBP,DWORD PTR SS:[ESP+14] ; keystring caricata in ebp
00401174 MOV EDX,ESI ; indirizzo del nome in edx
00401176 SUB EBP,ESI ; ebp = indirizzo keystring MENO indirizzo nome
; INIZIO LOOP
00401178 MOV AL,BYTE PTR DS:[EDX+EBP] ; prende un char da keystring e lo mette in al
0040117B MOV CL,BYTE PTR DS:[EDX] ; prende un char dal nome e lo mette in cl
0040117D XOR CL,AL ; vengono xorati questi due valori
0040117F INC EBX ; ebx fa da counter, viene incrementato
00401180 MOV BYTE PTR DS:[EDX],CL ; il valore xorato sostituisce in memoria le lettere del nome
00401182 MOV EDI,ESI ; # (le istruzioni con # servono a calcolare a ogni ciclo la lunghezza del nome)
00401184 OR ECX,FFFFFFFF ; #
00401187 XOR EAX,EAX ; #
00401189 INC EDX ; passa al prossimo char
0040118A REPNE SCAS BYTE PTR ES:[EDI] ; #
0040118C NOT ECX ; #
0040118E DEC ECX ; #
0040118F CMP EBX,ECX ; è l'ultimo carattere del nome?
00401191 JB SHORT prova2.00401178 ; se si prosegui se no passa al prossimo char
; FINE LOOP

bene, avrete capito che questo loop non fa altro che xorare ogni carattere del vostro nome con quello allo stesso posto nella keystring...

fate bene attenzione al prossimo pezzetto di codice... hee hee hee...

00401193 MOV EBP,DWORD PTR SS:[ESP+10] ; carica il serial in ebp
00401197 MOV EDI,ESI ; carica il nome xorato con keystring in edi
00401199 OR ECX,FFFFFFFF ; # (stessa storia di prima...)
0040119C XOR EAX,EAX ; #
0040119E XOR EBX,EBX ; ebx = 0
004011A0 REPNE SCAS BYTE PTR ES:[EDI] ; #
004011A2 NOT ECX ; #
004011A4 DEC ECX ; #
004011A5 JE SHORT prova2.004011C8 ; controlla che il nome xorato con keystring non sia una stringa di zero caratteri

all'apparenza questo sembra un normale controllo sulla stringa che il programma ha creato nel loop precedente per evitare che contenga solo uno zero... ma provate a immaginare che succede se il primo carattere è zero... ecx conterrà zero e quindi il jump si farà, MA GUARDATE DOVE FINISCE IL JUMP! alla messagebox di congratulazioni! studiamo la vulnerabilità (parlo come un professore...sigh): il primo carattere di questa stringa, ovvero il nostro nome xorato con la keystring deve dare 0, la keystring comincia con '0' (30 in hex) quindi "x xor 30 = 0". ovviamente x deve valere 30: qualsiasi nome che cominci per '0' salterà quindi il controllo e verrà accettato, provare per credere! (peccato che nel mio nick lo zero sia alla fine!)

dopo questa (intenzionale?) vulnerabilità, abbiamo il check vero e proprio... non riporto neanche il codice perchè si tratta di un loop del tutto simile ai precedenti che ad ogni giro confronta la nuova stringa (nome xorato con keystring) con il nostro serial, carattere per carattere. ovviamente se ne trova 2 diversi ci butta fuori e tanti saluti...

->Creazione di un keygen
bene, ora la protezione dovrebbe esservi chiara... ecco il sorgente in c di un keygen per questo crackme:

--INIZIO CODE--

#include <stdio.h>

int main()
{
// la keystring e il buffer per il vostro nick
char keystring[31] = "0123456789:;<=>?@ABCDEFGHIJKL";
char buffer[31];

// intro e raccolta dati
printf("keygen per il crackme69 by eimiar\n");
printf("il tuo nick in uppercase (max 30 chars!): ");
gets(buffer);

// loop che calcola il serial
for (int c=0;c<=30;c++)
{
if (buffer[c] == 0) break;
buffer[c] = buffer[c]^keystring[c];
}

// se poi non lo stampiamo non serve a niente, no?
printf("il tuo serial : ");
printf(buffer);
getchar();
return 0;
}

--FINE CODE--


ora, anche se il nick lo dovete scrivere voi in uppercase, il serial generato è valido, ma tante volte contiene dei caratteri strani ed è quindi difficile da riportare nel programma.
abbiamo finito! il crackme non era decisamente un osso duro ma almeno avete messo le mani sull'olly e avete intravisto cosà può fare...
droppatemi una mail al mio indirizzo (in cima alla pagina!) per qualsiasi cosa.
"quo usque tandem abutere, bender0, patientia nostra?" ok ok la smetto... al prossimo tute! thx e ciao.


Thx2: (inpo)

Que & la uic (esclusi i lameri che continuano a chiedere crack sul forum)
la blacksun research facility che mi ha insegnato un sacco di cose
phobos che ha mirrorato ringzer0!
Oleh Yuschuk, il tizio che ha scritto ollydbg - senza di lui che tute avrei scritto?!?
sourceforge che mi aiuta nei miei proggies
cure & smashing pumpkins che ho ascoltato scrivendo questo tute
la gente di deviantART che mi vuole bene!
softice che mi blocca l'orologio del win e mi fa arrivare sempre in ritardo!
volevo ringraziare anche la nullsoft per winamp 5 ma NON LO FARO' perchè hanno messo il pro a pagamento...

bender0

Paracul... err... disclaimer

questo coso è necessario anche se reversiamo crackme? mah...

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. "Come?!? NON CI PAGANO?!? AAAAAAGH!!!!"