Format ELF
ELF(Executable and Linking Format) est un format de fichier standard dans les os de type unix-like( linux en général) pour les fichiers exécutables, les bibliothèques partagées et les fichiers Objets.
Structure d'un Fichier ELF (à connaitre pour ce cours)
un fichier ELF contient plusieurs sections et segments qui servent à gérer les différentes parties d'un programme en mémoire
-
En-tête ELF(ELF header) :
situé au début du fichier, il contient des informations sur le type du fichier, l'architecture, les adresses d'entrée, et les offsets pour les autres sections du fichier.
Pour afficher l'en-tête d'un ELF on peut utiliser la commande < readelf -h nom_du_binaire>
exemples:
ici nous avons les l'en-tête de la libc dont le type est DYN pour dynamique est un fichier objet partagé
et notre deuxième exécutable est un programme c qui est de type fichier exécutable
Sur ce screenshot, nous pouvons voir différentes informations sur ce binaire, comme son type, le nombre d'en-têtes, le point d'entrée, etc.
Program Header Table : Il contient les informations nécessaires au chargeur du système pour mapper le fichier ELF en mémoire, en indiquant quelles parties du fichier correspondent aux segments de mémoire (stack, heap, section,etc.).
-
Sections : ce sont des parties d'un ELF qui ont un rôle bien défini :
.text : Contient le code exécutable (instructions du programme).
.data : Contient les variables(locales et globales) initialisées du programme .
.bss : Contient les variables(locales et globales) non initialisées.
.rodata : Contient les données en lecture seule, comme les chaînes de caractères constantes. ex: les chaînes que vous écrivez par exemple dans vos fonctions d'affichage de messages sur la sortie standard
.symtab et .dynsym : Tables de symboles utilisées pour identifier les fonctions et les variables dans le programme.
Un symbole est une chaîne de caractères dans un fichier binaire, associée à une adresse mémoire, une variable, ou une fonction.
.rel et .rela : Sections utilisées pour le relogement (relocation) des adresses lors du chargement du programme ou de l'utilisation de bibliothèques partagées.
Vous pouvez le voir dans cet exemple, certaines sections du binaire C, avec la sortie de GDB ci-dessous :
Les types de fichiers ELF (liste non exhaustive )
- Executable : Un fichier ELF pouvant être directement exécuté par le système d’exploitation.
- Shared Object : Une bibliothèque partagée, utilisée à la fois au moment de la liaison dynamique et de l’exécution pour accéder à certaines fonctions qui ne se trouvent pas dans notre programme, comme "printf" en C par exemple. Ce sont généralement des fichiers ayant une extension .so, comme la libc
Chargement et exécution d’un ELF
Lorsqu’un fichier ELF est exécuté :
- Le chargeur du système lit le program header pour charger les segments appropriés en mémoire.
- Il alloue de la mémoire pour la pile (stack) et le tas (heap).
- Il place les segments de code (.text) et de données (.data, .bss) dans les sections de la mémoire correspondantes.
- Enfin, il commence l’exécution en sautant à l’adresse spécifiée dans le point d'entrée du fichier ELF (généralement défini dans le ELF Header).
Mappage d'un ELF en mémoire :
Représentation de la mémoire pour un programme en cours d'exécution :
------------------------------------------
| Espace du noyau (Kernel) |
------------------------------------------
| Stack |
| (variables locales, adresses |
| de retour, pile des appels) |
-------------------------------------------
| Heap |
| (mémoire dynamique, malloc, etc) |
-------------------------------------------
| Uninitialized Data (.bss) |
| (variables non initialisées) |
-------------------------------------------
| Initialized Data (.data) |
| (variables initialisées) |
-------------------------------------------
| Code (.text) |
| (instructions exécutables) |
-------------------------------------------
| Espace réservé au programme |
-------------------------------------------
Espace kernel : gère les ressources, assure la gestion des erreurs, exécute les appels système, etc.
Stack : est une structure de données qui contient les variables locales et les adresses de retour des fonctions. Elle croît vers le bas.
Heap: est une Zone de mémoire utilisée pour les allocations dynamiques (malloc, calloc). Elle croît vers le haut, en partant du bas
ce n'est pas vraiment la structure d'un elf vu qu'il contient d'autres choses donc juste le minimum !
No Comments