0% ont trouvé ce document utile (0 vote)
12 vues20 pages

Rétro-Ingénierie des Programmes ELF

Ce document traite de la rétro-ingénierie de programmes compilés, en se concentrant sur le format ELF utilisé sous Linux. Il explique les étapes de compilation, la structure des fichiers ELF, ainsi que les sections et les en-têtes qui contiennent des informations essentielles sur le programme. Des observations pratiques sont fournies pour explorer le contenu binaire et comprendre les concepts de liaison dynamique et statique.

Transféré par

Niass
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
12 vues20 pages

Rétro-Ingénierie des Programmes ELF

Ce document traite de la rétro-ingénierie de programmes compilés, en se concentrant sur le format ELF utilisé sous Linux. Il explique les étapes de compilation, la structure des fichiers ELF, ainsi que les sections et les en-têtes qui contiennent des informations essentielles sur le programme. Des observations pratiques sont fournies pour explorer le contenu binaire et comprendre les concepts de liaison dynamique et statique.

Transféré par

Niass
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Rétro-Ingénierie de Programmes

Rappels de Compilation

1/16
Qu'est-ce qu'un programme compilé ?

Compilation = Code Source → (Binaire) Programme

Observation #1
Codez un programme C "Hello world", compilez le et ouvrez le binaire
avec la commande cat.

1 #include <stdio.h>
2 int main(void)
3{
4 printf(”Hello World !\n”);
5 return 0;
6}

2/16
Qu'est-ce qu'un programme compilé ?

3/16
Qu'est-ce qu'un programme compilé ?

Observation #2
Ouvrez le binaire avec xxd.

4/16
Qu'est-ce qu'un programme compilé ?

Observation #2
Ouvrez le binaire avec xxd.

4/16
Regarder correctement le contenu d'un programme

Observation #3
Ouvrez le programme avec la commande strings.

5/16
Regarder correctement le contenu d'un programme

Observation #3
Ouvrez le programme avec la commande strings.

5/16
Regarder correctement le contenu d'un programme

Observation #4
Ouvrez le programme en utilisant les commandes suivantes :
objdump -d -M intel
objdump -s -M intel.

6/16
Cible de ce cours : les programmes Linux

De nombreux formats de fichiers

Windows : PE macOS : Mach-O Linux : ELF


Java : JAR Android : APK PDF

Documentation ELF
man 5 elf

7/16
Structure globale d'un fichier ELF

En-tête En-tête
ELF ELF

segment en-tête 1 Table des


... en-têtes de
segment en-tête n programme
Fichier
section en-tête 1 Table des
ELF
... en-têtes
section en-tête m de section

code
&
données
8/16
En-tête ELF

Informations importantes
Architecture cible du programme : jeu d'instructions utilisées par le
programme (ARM, x86, …)
Point d'entrée (Entry point) : adresse de la première instruction du
programme
Adresses des tables des en-têtes de programme et de section

9/16
En-tête ELF

Informations importantes
Architecture cible du programme : jeu d'instructions utilisées par le
programme (ARM, x86, …)
Point d'entrée (Entry point) : adresse de la première instruction du
programme
Adresses des tables des en-têtes de programme et de section

Observation #5
Ouvrez le programme précédent en utilisant la commande readelf -h et
récupérez les informations de l'en-tête.

9/16
En-tête ELF

Observation #6
Allez au point d'entrée du programme en utilisant objdump -d.
À quoi correspond _start?

10/16
Tables des en-têtes programme & section

Définition : segment & section


Les en-têtes de programme et de section fournissent des méta-données sur
différentes parties du fichier.

Les segments contiennent les informations nécessaires à l'exécution


du programme.

Les sections contiennent les informations nécessaires pour l'édition de lien et la


relocalisation du programme en mémoire.

Observation #7
Ouvrez le programme précédent en utilisant readelf -l et readelf -S.

11/16
Sections de code et de données

Section de code
Le code est généralement placé dans la section .text.

Sections de données
.rodata: données globales en lecture seule, comme par exemple les chaînes
de caractères.
.data: données globales en lecture/écriture comme par exemple les variables
statiques.
.bss: données globales non-initialisées (lecture/écriture).

12/16
Rappel sur la mémoire d'un processus
0xffffffff
Noyau Linux
0xcfffffff

Pile (stack)

Tas (heap)
Espace mémoire
d'un processus Segment BSS
Segment Data
Segment Text
(code)
0x400000
...
13/16
Section init & fini

Initialization et terminaison du programme


La section .init_array, resp. .fini_array, contient la liste des adresses à appeler
avant, resp. après, l'appel de la fonction main.

Observation #8
Ajoutez dans le programme le code ci-dessous.
Observez le nouveau comportement et le contenu de la section
.init_array.

1 void before(void) __attribute__((constructor));


2 void before(void) {printf(”Before the main!\n”);}

14/16
Section des symboles

Définition : symboles
Un symbole est un nom donné à une adresse du programme (e.g. nom de fonction).
La section .symtab contient les adresses des symboles.
Vous pouvez retrouver son contenu en utilisant readelf -s.

Observation #9
Utilisez la commande strip sur le programme et observez le en utilisant
la commande objdump -d.
Que s'est-il passé ?

15/16
Liens avec les bibliothèques

Définition : liaison dynamique


Les adresses des fonctions se trouvent dans la section .got.

Définition : liaison statique


Le code des fonctions est directement inséré dans le fichier ELF.

16/16
Liens avec les bibliothèques

Définition : liaison dynamique


Les adresses des fonctions se trouvent dans la section .got.

Définition : liaison statique


Le code des fonctions est directement inséré dans le fichier ELF.

Observation #10
Où est la fonction puts ? Comment est-elle appelée ?

Observation #11
Recompilez le programme en utilisant l'option -static et observez le code
généré. 16/16

Vous aimerez peut-être aussi