GDB e Objdump : piccola guida all’uso
Pubblicato da T4n|n0 Ru|3z su 3 Luglio 2008

I tools di sviluppo GNU includono un programma chiamato appunto Objdump che può essere usato per esaminare i dei binari.
Una delle funzioni principali,è quindi quella di essere un disassembler. Per avere una panoramica completa di questa funzione,si può usare il comando:
objdump -Dslx file
dove file è il nostro binario.
Naturalmente un bel
man objdump
ci da tutte le info necessarie,ma vi voglio elencare le principali e forse più usate:
-d : come già detto,disassemblatore
-h : per vedere le intestazioni ELF
–full-contents : per vedere una sezione ELF
-S : ci mostra il source e l’assembly
Facciamo un esempio:
objdump -D a.out |grep main
Ho isolato solo la parte del main,visto che l’output di objdump è davvero lungo. Ho usato un codice di prova di un piccolo client creato da me che iteragiva con un server usando le code di messaggi SysV IPC. L’output è:
08048514 :
8048579: 79 18 jns 8048593
80485be: 74 0b je 80485cb
80485c9: 75 57 jne 8048622
804862b: 74 0b je 8048638
8048636: 75 0c jne 8048644
804864d: 74 0b je 804865a
8048658: 75 70 jne 80486ca
804873f: e9 4f fe ff ff jmp 8048593
ogni byte ha una rappresentazione esadecimale,molto familiare con il nostro linguaggio normale in base 10 ( per chi non lo sapesse,una notazione esadecimale usa 0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F come alfabeto ).
Notiamo che nel nostro codice tutto parte dal punto 0×8048514 che non è altro che l’indirizzo di memoria associato.
Non tutti i codici usano una sintassi intel ma volend,possiamo mostrare l’output Intel usando l’opzione -M:
objdump -M intel -D a.out |grep main
provate se non avete un architettura intel ![]()
Oltre a objdump,abbiamo a disposizione GDB.
GDB viene spesso usato per mostrare lo stato dei registri prima dell’esecuzione del programma:
gdb -q ./a.out
entreremo nel dgb e potremo usare alcuni comandi,ecco un esempio:
(gdb) break main
Breakpoint 1 at 0×8048522
(gdb) run
Starting program: /home/tanino/Scrivania/client
Breakpoint 1, 0x08048522 in main ()
Current language: auto; currently asm
(gdb) info registers
eax 0x1 1
ecx 0xbffecd70 -1073820304
edx 0xbffecd90 -1073820272
ebx 0xb7f03ff4 -1208991756
esp 0xbffecd54 0xbffecd54
ebp 0xbffecd58 0xbffecd58
esi 0xb7f36ce0 -1208783648
edi 0x0 0
eip 0x8048522 0x8048522
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
come vedete ho cercato il breakpoint del main e info sui registi. Per uscire dal gdb basta digitare quit.
Tornando ai registri,possiamo dire che i primi quattro ( EAX, ECX, EDX, EBX ) sono registri general purpose,chiamati rispettivamente Accumulator, Counter, Data, and Base registers.
Invece i seguenti 4 registri rispetto ai precedenti sono ESP, EBP, ESI, EDI e sono rispettivamente chiamati Stack Pointer, Base Pointer, Source Index,e Destination Index. ESP (Extended Stack Pointer) è un registro puntatore che contiene l’indirizzo di memoria corrispondente alla testa dello stack. Il registro EIP è invece il registro Instruction Pointer,che punta alla istruzione corrente che il processore sta leggendo.
Eccovi una lista completa:
- EAX – Accumulator — Manipolazione degli operandi e dei risultati delle operazioni logico-aritmetiche, nonché, in genere, del valore restituito dalle funzioni al codice chiamante.
EBX – Base Addressing — Puntatore ai dati contenuti nel segmento DS (ad esempio, viene usato per contenere l’indirizzo del primo byte di un array o di un tipo di dato complesso, come una struttura o un record).
ECX – Counter — Usato come contatore nei cicli, nelle istruzioni di shifting e rotazione e nelle operazioni di manipolazione di stringhe.
EDX — Data — Puntatore nelle operazioni di I/O nonché come registro ausiliario in alcune istruzioni aritmetiche (moltiplicazione e divisione).
ESI — Source Index — Usato nelle operazioni di manipolazione di stringhe, come puntatore ai dati di partenza. Viene usato anche per contenere l’offset di dati contenuti nel segmento DS (rispetto all’indirizzo di base contenuto in EBX).
EDI — Destination Index — Usato nelle operazioni di manipolazione di stringhe, come puntatore ai dati di destinazione. Viene usato anche per contenere il puntatore ai dati (o all’indirizzo) di destinazione contenuti nel segmento ES o l’offset di dati contenuti nel segmento DS (rispetto all’indirizzo di base contenuto in EBX).
EBP — Base Pointer — Puntatore ai dati sullo stack (ad esempio, i parametri e le variabili locali di procedure e funzioni). Viene usato anche per contenere l’indirizzo dei dati contenuti nel segmento SS.
ESP — Stack Pointer — Puntatore all’ultimo elemento posto sullo stack. Viene anche usato per contenere l’indirizzo di offset di dati contenuti nel segmento SS (rispetto all’indirizzo di base contenuto in EBP).
Il registro EFLAGS invece è un insieme di flags di bit usato per confronti e segmenti di memoria.
E’ tutto per ora..












Mary James detto
tsniiiiiiiiiiiiiiiiiiii
sì u MAST!!!
bacissimi tvtttttttttttttttttb
T4n|n0 Ru|3z detto
x AnarchiX: grazie per aver segnalato l’errore,mi sono distratto :D
AnarchiX detto
quote:
per chi non lo sapesse,una notazione decimale usa 0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F come alfabeto
bè.. non è proprio così… quella è la ESADECIMALE…