I file ELF #
ELF sta per Executable and Linkable Format, ed è un formato di file che viene usato per salvare i file oggetto.
Descrive come il programma deve essere caricato (program/segment headers) e contiene metadati che descrivono i componenti del programma (section headers).
Vi sono tre tipi di file oggetto:
- file relocatable, contenente codice e dati, può essere linkato con altri file oggetto per creare un eseguibile o un file shared object.
- file eseguibili, contengono un file adatto ad essere eseguito.
- file shared object, possono essere sia linkati con altri file shared object per ottenere un altro object file, oppure usati da un linker dinamico insieme ad altri file eseguibili e file oggetto per creare un’immagine processo (process image).
Come è fatto un file ELF? #
All’interno di un ELF vi sono due sezioni principali: i program headers e i section headers.
I program headers specificano informazioni necessarie a preparare il programma all’esecuzione. Le entry più importanti sono:
- INTERP, definiscono la libreria che verrà usata per caricare l’ELF in memoria.
- LOAD, definisce una parte del file che deve essere caricato in memoria.
I section headers sono una parte dell’ELF che contiene informazioni utili al debug e all’introspection.
Sezioni importanti che ricordiamo:
- .text: il codice eseguibile del tuo programma
- .plt e .got: sono usati per risolvere le chiamate a libreria (ad esempio le chiamate alla libreria standard C (libc) tipo printf())
- .data: sezione usata per dati globali pre-inizializzati, tipo array globali già inizializzati. Questa sezione è scrivibile.
- .rodata: usata per dati globali read-only, tipo le stringhe costanti.
- .bss: usata per dati globali non inizializzati, come array globali senza inizializzazione.
Analisi delle sezioni di un ELF #
Prendiamo ad esempio il file main che abbiamo generato prima.
Per elencare tutti i program headers possiamo usare il comando
readelf --program-headers main.
Per elencare tutti i section headers possiamo usare il comando
readelf --section-headers main.
Anche objdump può essere usato per elencare gli header di un ELF,
usando il comando objdump -x main.
Per elencare tutti i simboli all’interno del binario possiamo usare
nm main. Invece per rimuovere i simboli e altre informazioni utili
possiamo usare il comando strip.