<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
* Travaillez-vous dans une **entreprise de cybersécurité**? Voulez-vous voir votre **entreprise annoncée dans HackTricks**? ou voulez-vous avoir accès à la **dernière version du PEASS ou télécharger HackTricks en PDF**? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**dépôt hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**dépôt hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
Le programme précédent a **9 en-têtes de programme**, puis, la **cartographie des segments** indique dans quel en-tête de programme (de 00 à 08) **chaque section est située**.
Chaque en-tête **LOAD** indique une région de **mémoire** (taille, autorisations et alignement) et indique les octets du binaire ELF **à copier dedans**.
Par exemple, le deuxième a une taille de 0x1190, devrait être situé à 0x1fc48 avec des autorisations de lecture et d'écriture et sera rempli avec 0x528 à partir du décalage 0xfc48 (il ne remplit pas tout l'espace réservé). Cette mémoire contiendra les sections `.init_array .fini_array .dynamic .got .data .bss`.
Contient la configuration de la défense de prévention de l'exécution de la pile. Si activé, le binaire ne pourra pas exécuter de code à partir de la pile.
Indique la configuration RELRO (Relocation Read-Only) du binaire. Cette protection marquera comme en lecture seule certaines sections de la mémoire (comme le `GOT` ou les tables `init` et `fini`) après le chargement du programme et avant son exécution.
Notez que RELRO peut être partiel ou complet, la version partielle ne protège pas la section **`.plt.got`**, qui est utilisée pour la **liaison paresseuse** et a besoin que cet espace mémoire ait des **autorisations d'écriture** pour écrire l'adresse des bibliothèques la première fois que leur emplacement est recherché.
* **Table des chaînes**: Elle contient toutes les chaînes nécessaires au fichier ELF (mais pas celles réellement utilisées par le programme). Par exemple, elle contient des noms de sections comme `.text` ou `.data`. Et si `.text` est à l'offset 45 dans la table des chaînes, il utilisera le nombre **45** dans le champ **name**.
* Pour trouver où se trouve la table des chaînes, l'ELF contient un pointeur vers la table des chaînes.
* **Table des symboles**: Elle contient des informations sur les symboles comme le nom (offset dans la table des chaînes), l'adresse, la taille et plus de métadonnées sur le symbole.
* **`.text`**: Les instructions du programme à exécuter.
* **`.data`**: Variables globales avec une valeur définie dans le programme.
* **`.bss`**: Variables globales non initialisées (ou initialisées à zéro). Les variables ici sont automatiquement initialisées à zéro, empêchant ainsi l'ajout de zéros inutiles au binaire.
* **`.rodata`**: Variables globales constantes (section en lecture seule).
* **`.tdata`** et **`.tbss`**: Comme le .data et le .bss lorsque des variables locales au thread sont utilisées (`__thread_local` en C++ ou `__thread` en C).
Les symboles sont des emplacements nommés dans le programme qui peuvent être une fonction, un objet de données global, des variables locales au thread...
* **Attributs de liaison** (faible, local ou global) : Un symbole local ne peut être accédé que par le programme lui-même tandis que les symboles globaux sont partagés en dehors du programme. Un objet faible est par exemple une fonction qui peut être remplacée par une autre.
* **Type** : NOTYPE (type non spécifié), OBJECT (variable de données globale), FUNC (fonction), SECTION (section), FILE (fichier source pour les débogueurs), TLS (variable locale au thread), GNU_IFUNC (fonction indirecte pour la relocalisation)
Le répertoire NEEDED indique que le programme **doit charger la bibliothèque mentionnée** pour continuer. Le répertoire NEEDED est complété une fois que la **bibliothèque partagée est entièrement opérationnelle et prête** à être utilisée.
Le chargeur doit également relocaliser les dépendances après les avoir chargées. Ces réadressages sont indiqués dans la table de réadressage aux formats REL ou RELA et le nombre de réadressages est donné dans les sections dynamiques RELSZ ou RELASZ.
Si le **programme est chargé à un emplacement différent** de l'adresse préférée (généralement 0x400000) car l'adresse est déjà utilisée ou en raison de **ASLR** ou toute autre raison, un réadressage statique **corrige les pointeurs** qui avaient des valeurs s'attendant à ce que le binaire soit chargé à l'adresse préférée.
Le réadressage pourrait également faire référence à un symbole externe (comme une fonction d'une dépendance). Comme la fonction malloc de libC. Ensuite, le chargeur lors du chargement de libC à une adresse vérifiant où la fonction malloc est chargée, écrira cette adresse dans la table GOT (Global Offset Table) (indiquée dans la table de réadressage) où l'adresse de malloc devrait être spécifiée.
La section PLT permet d'effectuer une liaison paresseuse, ce qui signifie que la résolution de l'emplacement d'une fonction sera effectuée la première fois qu'elle est accédée.
Ainsi, lorsque qu'un programme appelle malloc, il appelle en réalité l'emplacement correspondant de `malloc` dans la PLT (`malloc@plt`). La première fois qu'elle est appelée, elle résout l'adresse de `malloc` et la stocke, de sorte que la prochaine fois que `malloc` est appelée, cette adresse est utilisée à la place du code PLT.
Après que le programme a été chargé, il est temps pour lui de s'exécuter. Cependant, le premier code qui est exécuté **n'est pas toujours la fonction `main`**. Cela est dû, par exemple, en C++, si une **variable globale est un objet d'une classe**, cet objet doit être **initialisé****avant** l'exécution de main, comme dans:
Notez que ces variables globales sont situées dans `.data` ou `.bss`, mais dans les listes `__CTOR_LIST__` et `__DTOR_LIST__`, les objets à initialiser et à détruire sont stockés afin de les suivre.
Du point de vue du compilateur, pour exécuter ces actions avant et après l'exécution de la fonction `main`, il est possible de créer une fonction `init` et une fonction `fini` qui seraient référencées dans la section dynamique comme **`INIT`** et **`FIN`** et placées dans les sections `init` et `fini` de l'ELF.
L'autre option, comme mentionné, est de référencer les listes **`__CTOR_LIST__`** et **`__DTOR_LIST__`** dans les entrées **`INIT_ARRAY`** et **`FINI_ARRAY`** de la section dynamique et leur longueur est indiquée par **`INIT_ARRAYSZ`** et **`FINI_ARRAYSZ`**. Chaque entrée est un pointeur de fonction qui sera appelé sans arguments.
De plus, il est également possible d'avoir un **`PREINIT_ARRAY`** avec des **pointeurs** qui seront exécutés **avant** les pointeurs **`INIT_ARRAY`**.
### Ordre d'initialisation
1. Le programme est chargé en mémoire, les variables globales statiques sont initialisées dans **`.data`** et celles non initialisées sont mises à zéro dans **`.bss`**.
Lorsque cela est utilisé, les sections **`.tdata`** et **`.tbss`** sont utilisées dans l'ELF. Ce sont comme `.data` (initialisé) et `.bss` (non initialisé) mais pour TLS.
Chaque variable aura une entrée dans l'en-tête TLS spécifiant la taille et le décalage TLS, qui est le décalage qu'il utilisera dans la zone de données locale du thread.
Le `__TLS_MODULE_BASE` est un symbole utilisé pour faire référence à l'adresse de base du stockage local aux threads et pointe vers la zone en mémoire qui contient toutes les données locales aux threads d'un module.