I file ELF

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.