Debugging & Corruption de mémoire

De Wiki - kr[HACK]en
Sauter à la navigation Sauter à la recherche


Introduction

Le jeudi 5 octobre 2017 s’est déroulé le premier Workshop de l’année, intitulé « Introduction au debugging et corruptions dem émoire ». Animé par Cyril BRESCH, cette première séance sur un total de quatre avait pour but d’initier les élèves de tous niveaux au debugging et de les familiariser avec l’utilisation de GDB1. Seul le debug de programmes écrits en langage C a été abordé.

Thèmes abordés pendant la séance :

    • Le format ELF
    • Les commandes basiques de débogage de GDB
    • Reverse sur un code source en C

Le Format ELF

Le format ELF (Executable and Linking Format) est un format d’exécutables utilisé sous les systèmes d’exploitation Linux. Ce format regroupe de nombreuses informations comme l’espace alloué pour les données, le code source, ainsi que des informations concernant les différentes libraires et le debug. C’est le format de fichiers utilisé lors de la compilation d’un programme C par exemple et le format qui a été utilisé lors de cette séance.

Les Commandes Basiques de GDB

Pour lancer le débogage d’un programme nommé « hello » avec GDB, il faut utiliser la commande suivante :

gdb -q hello

L’option -h permet de ne pas afficher les informations au démarrage de GDB et ainsi d’avoir un terminal plus « propre » au démarrage.

REMARQUE: Il est possible, au sein même de gdb, de lancer des commandes shell. Ceci se fait avec la commande :

shell <commande_shell>

Pour lancer son programme au sein de gdb, il faudra utiliser la commande:

 run

et pour un fonctionnement « pas à pas », on privilégiera la commande:

step

Il est parfois, voir même souvent, utile de pouvoir visionner le code assembleur de son programme afin de voir pourquoi il n’a pas le comportement attendu. Pour voir le code assembleur d’une fonction, il faut utiliser la commande suivante :

disas <nom_de_la_fonction>

Pour visionner, par exemple, le code assembleur de tout son programme C, on peut indiquer comme nom de fonction « main » et le code assembleur de tout le programme sera affiché.

Lors d’une session de debug, il est parfois nécessaire d’instaurer des « breakpoints ». Ces derniers permettent de figer le fonctionnement de son programme en un point donné, et ainsi de pouvoir visionner son fonctionnement pas à pas par la suite. Pour créer un breakpoint, on utilise :

b <point_d’arret>

On peut aussi renseigner à la place du point d’arrêt une adresse spécifique. Par exemple:

b *main+9

va créer un breakpoint à l’instruction se trouvant à l’adresse de début de la fonction main + 9 octets.

Enfin, si l’on souhaite afficher tous les breakpoints crées lors d’une session de debugging, la commande suivante peut être utile:

i b

Reverse sur un code source en C

Maintenant que vous maîtrisez les bases de gdb, il est temps de s’exercer un petit peu ! Les fichiers sont disponibles au téléchargement ici !

Exercice 1 : Prise en main de gdb <\br>

  • Compilez le fichier hello.c
  • Entraînez-vous à utiliser les différentes commandes listées ci-dessus

et à comprendre leurs utilités.

Exercice 2 : Sur le fichier crack_me (Afin de réussir toutes les questions de cet exercice, un petit cours sur les différents registres du processeur ainsi que son fonctionnement peut-être nécessaire, vous pourrez en trouver un ici : http://rmdiscala.developpez.com/cours/LesChapitres.html/Cours1/Chap1.5.html )

  • Comprendre le fonctionnement du programme
  • Trouver le point d'entrée du programme
  • Lister les sections du programme
  • Trouver l'adresse de retour de la fonction main
  • Trouver la valeur du Stack Pointer avant que main retourne
  • Essayer de faire jumper le programme dans la fonction cachée grâce au débug
  • Lister les registres dans la fonction cachée.

Exercice 3 : Pour les plus motivés

Ecrire un petit code en assembleur permettant d'afficher hello world.

Article rédigé par Corentin Liaud.

Voici ci-joint la présentation en format pdf: Présentation