Zoom Icon

Lezione 2 OllyDbg Tutorial

From UIC Archive

Lezione 2: OllyDbg tutorial

Contents


Lezione 2 OllyDbg Tutorial
Author: UICommunity
Email: Email
Website: Home page
Date: 15/09/2008 (dd/mm/yyyy)
Level: Working brain required
Language: Italian Flag Italian.gif
Comments:



Thanks to:

Bender0, Pn;


Introduction

Scritto per i newbies che hanno poca esperienza (poca significa che un minimo di assembly lo dovete sapere).

OllyDbg (anche grazie ai numerosi problemi di installazione di softice nei nuovi os) sta spopolando. È 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

Beh, se non lo volete solo contemplare questo tute penso che vi servirà OllyDbg! Io ho la versione 1.09d (step 4).
Lezione 2: il crackme che useremo per far un pò di pratica col debugging.


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.
  • 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!

  • 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 qui 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

CPU: Disassembler Window

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, qui 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 nella sezione debug.
|----
|-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 menu help e cerca il nome simbolico selezionato all'interno della guida.
|-bookmark:
| ^ vedi plugins.
|----
|-appearance:
| ^ solite opzioni di visualizzazione.
|----

CPU: Registers Window

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.

CPU: Dump Window

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.

CPU: Stack Window

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...

Il nostro primo debugging

Prima di aprire il crackme allegato alla lezione con olly, lanciamolo per vedere cosa fa: all'inizio appare una finestra, poi c'è una dialog con una textbox e un pulsante: scrivendo qualcosa nella textbox e premendo ok, vedremo che ci appare un'altra finestra che contiene il testo della textbox.
Ora apriamo il file con olly: vedrete che dopo la fase di analisi, ollydbg vi fermerà sull'entrypoint. L'entrypoint è l'indirizzo di memoria della prima istruzione da eseguire del programma, che in questo caso è: 00401286 CALL Pmak.0040298C ; <-- entry point 0040128B JMP Pmak.00401108 .... Il nostro scopo è mettere un breakpoint sulla prima messagebox.
Di solito per far apparire una messagebox si usa l'apile api sono delle funzioni del Sistema Operativo usate nei programmi per vari scopi, ad esempio per far apparire un messaggio o una dialog MessageBox, che ha due versioni: MessageBoxA che utilizza il testo in formato ASCII, e MessageBoxW, dove W sta per wchar, che utilizza il formato UNICODE.
Vi mostro la sintassi di quest'api (per maggiori info visitate il sito msdn http://msdn.microsoft.com/en-us/library/ms645505.aspx): int MessageBox(

   HWND hWnd,
   LPCTSTR lpText, //<-- è il testo del messaggio
   LPCTSTR lpCaption, // <-- è il testo della caption
   UINT uType

); Ora settiamo un breakpoint su MessageBoxA, vi mostro due metodi per farlo:
1)Pulsante destro -> Search for -> All intermodular calls: le intermodular calls sono tutte quelle call che chiamano funzioni presenti al di fuori del codice del programma, come ad esempio funzioni presenti in dll di sistema.
A questo punto dovrebbe apparire la lista delle call del modulo, molte delle quali chiamano le Api di Windows: ordiniamo la lista in base alla destinazione (destro -> sort by -> destination) e poi premiamo M: .... 0040107B | CALL DWORD PTR DS:[<&USER32.MessageBoxA>] | USER32.MessageBoxA 00401054 | CALL DWORD PTR DS:[<&USER32.MessageBoxW>] | USER32.MessageBoxW ... Per settare un break point su quest'indirizzi basta che mettiamo il cursore sulla riga e premiamo F2, oppure destro -> toggle breakpoint; per togliere un breakpoint basta premere di nuovo F2
2)Usiamo il plugin Command line come spiegato poco sopra: digitiamo bp MessageBoxA (attenti alle maiuscole) per settare il breakpoint.
Per vedere se il breakpoint è stato settato correttamente basta premere Alt+B e scorrere la lista dei breakpoint o vedere se nella windows CPU la colonna dell'indirizzo è rossa.

Lez2 img1.jpg



Settiamo un breakpoint su MessageBoxA usando il secondo metodo, poi premiamo F9 per far partire il programma e vedrete che olly ci fermerà qua (l'indirizzo di memoria potrebbe cambiare sul vostro pc): 77D5050B >MOV EDI,EDI ; <-- prima istruzione dell'api MessageBoxA 77D5050D PUSH EBP 77D5050E MOV EBP,ESP 77D50510 CMP DWORD PTR DS:[77D7041C],0 77D50517 JE SHORT USER32.77D5053D 77D50519 MOV EAX,DWORD PTR FS:[18] 77D5051F PUSH 0 77D50521 PUSH DWORD PTR DS:[EAX+24] 77D50524 PUSH USER32.77D70AF4 77D50529 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange 77D5052F TEST EAX,EAX 77D50531 JNZ SHORT USER32.77D5053D 77D50533 MOV DWORD PTR DS:[77D70AF0],1 77D5053D PUSH 0 77D5053F PUSH DWORD PTR SS:[EBP+14] 77D50542 PUSH DWORD PTR SS:[EBP+10] 77D50545 PUSH DWORD PTR SS:[EBP+C] 77D50548 PUSH DWORD PTR SS:[EBP+8] 77D5054B CALL USER32.MessageBoxExA 77D50550 POP EBP 77D50551 RETN 10 Questa funzione è contenuta in una dll di sistema, USER32 da come potete vedete nel titolo della window del disasm, quindi siamo fuori dal codice del nostro eseguibile, per ritornarci, basta stappare con F8 fino al ret e vedrete che torneremo in questo punto: 00401081 XOR EAX,EAX
Settiamo un bp su MessageBoxW, e poi lanciamo il programma con F9.
Come potete vedere v'appare la dialog: scrivete qualcosa nel textbox e poi premete "OK": olly stavolta vi fermerà a: 77D66116 >MOV EDI,EDI; <-- prima istruzione dell'api MessageBoxW 77D66118 PUSH EBP 77D66119 MOV EBP,ESP 77D6611B CMP DWORD PTR DS:[77D7041C],0 77D66122 JE SHORT USER32.77D66148 77D66124 MOV EAX,DWORD PTR FS:[18] 77D6612A PUSH 0 77D6612C PUSH DWORD PTR DS:[EAX+24] 77D6612F PUSH USER32.77D70AF4 77D66134 CALL DWORD PTR DS:[<&KERNEL32.Interlocke>; kernel32.InterlockedCompareExchange 77D6613A TEST EAX,EAX 77D6613C JNZ SHORT USER32.77D66148 77D6613E MOV DWORD PTR DS:[77D70AF0],1 77D66148 PUSH 0 77D6614A PUSH DWORD PTR SS:[EBP+14] 77D6614D PUSH DWORD PTR SS:[EBP+10] 77D66150 PUSH DWORD PTR SS:[EBP+C] 77D66153 PUSH DWORD PTR SS:[EBP+8] 77D66156 CALL USER32.MessageBoxExW 77D6615B POP EBP 77D6615C RETN 10 Guardate la window dello stack 0012FA40 0040105A /CALL to MessageBoxW from Pmak.00401054 <-- ESP 0012FA44 00000000 |hOwner = NULL 0012FA48 0012FA54 |Text = "ciao" 0012FA4C 0040813C |Title = "Caption" 0012FA50 00000000 \Style = MB_OK|MB_APPLMODAL in 12FA40 è salvato il valore dell'indirizzo di memoria in cui torneremo una volta eseguito il ret, mentre tutti gli altri valori, sono quelli usati per far apparire la MessageBox.
Se steppate e contemporaneamente vedete la window dello stack, potete notare che questi valori vengono passati a MessageBoxExW e poi arrivati al ret l'ESP è 0012FA40 0040105A RETURN to Pmak.0040105A from USER32.MessageBoxW che indica l'indirizzo di ritorno.

Utiliziamo il primo metodo sempre per allenamento:
settate un bp su MessageBoxA, e poi premete F9: olly vi fermerà qua: 0040106D PUSH 0  ; /Style = MB_OK|MB_APPLMODAL; 0040106F PUSH Pmak.00408130  ; |Title = "InitDialog" 00401074 PUSH Pmak.0040A000  ; |Text = "breakpointMe" 00401079 PUSH 0  ; |hOwner = NULL 0040107B CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA  ; <-- il bp è qui 00401081 XOR EAX,EAX A questo punto se steppate con F8 vi appirà la messagebox e poi vi fermerete a 401081, mentre se steppate dentro la call con F7, vi verrà mostrato il codice della funzione MessageBoxA.

Compiti per casa

Scrivete un tutorial su come arrivare alla prima MessageBox, settando un breakpoint su DialogBoxParam, e quindi spiegando un pò la DialogProc.
Per info su quest'api potete utilizzare il motore di ricerca di msdn http://msdn.microsoft.com/it-it/library/default.aspx, e seguire le lezioni di Iczelion sulle dialog: http://win32assembly.online.fr/tutorials.html.


Note Finali

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:
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 nel coding
cure e smashing pumpkins che ho ascoltato scrivendo questo tute
tool e meshuggah che ho ascoltato wikizzando 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!


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.