Architecture x86/amd64

De UnixWiki
Aller à : navigation, rechercher

Les registres

Architecture CISC (complex instruction set).

Les registres sont sur 32 bits en x86 et 64 sur amd64

EIP (extended instruction pointer): pointeur d'instruction, pointe toujours sur la prochaine instruction à exécuter)
EBP (extended base pointer): Pointeur de la base de la pile
ESP (extended stack pointer): Pointeur du sommet de la pile

le SFP, saved frame pointer garde en mémoire la position antérieure (et ultérieure, après le popping) de l'EBP, et le RA, return address, le pointeur vers l'adresse de retour (la prochaine valeur de l'EIP, donc la prochaine instruction après l'appel de la fonction).

L'empilement sur la stack s'éffectue dans le sens décroissant! C'est-à-dire que l'ESB originale est l'adresse la plus grande et que le sommet est 0..0H. De là naît la possibilité d'écraser des données vitales et d'avoir un buffer overflow.

Le but est donc d'écraser EIP avec une adresse différente que nous pourrons utiliser pour accéder à une partie de code qui nous appartient. (par exemple le contenu du buffer)

/!\ En little endian 4F52 sera stocké en mémoire sous la forme 524F 52 à l'adresse 1000 et 4F à 1001

Segmentation mémoire

Lorsque un programme est lancé, une plage mémoire est réservée pour l'éxécution du programme. Cette mémoire du programme est divisée en 5 segment : text, data, bss, heap et stack.

text : ce segment est aussi appellé le segment code. Il sert à stocker les instructions machine du programme. Au démarrage du programme, EIP pointe vers la première instruction de ce segment. Si le même programme est lancé plusieurs fois, le segment text sera partagé entre les programmes car ce qui est dans ce segment est fixe et ne peut être modifié.

data et bss : sont utilisés pour stocker les variables globales et statiques du programme. data variables globales initialisées au lancement du programme, les chaînes de caractères et les constantes globales et bss variables globales et statiques (non-initialisées)

heap : est utilisé pour toutes les autres variables du programme. Cette fois, des variables pouvant être dynamiques, le segment heap ne peut pas être de taille fixe (sa taille s'adapte au long du programme). Le heap grandit vers les adresses mémoire plus grandes.

La pile (stack) : est aussi de taille variable et est utilisée comme un bloc-note temporaire pendant les appels de fonctions. En assembleur on emplie sur la pile avec push et on dépile avec pop. Contrairement au heap, la pile grandit dans le sens des adresses décroissantes