Mémoire de l’ordinateur

Salut ce forum est dédié à comprendre les entrailles de l'ordinateur au plus bas niveau bienvenue dans le monde du reverse et de l'assembleur

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 114
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Mémoire de l’ordinateur

Post by Hydraxx »

Mémoire de l’ordinateur

Dans ce chapitre, nous allons voir comment la mémoire d’un programme est organisée et comment le processeur accède aux données. L’objectif est surtout de comprendre ce que l’on observe lorsqu’on analyse un programme en assembleur ou dans un débogueur.

1. Introduction à la mémoire

La mémoire peut être vue comme une immense suite d’octets. Chaque octet possède une adresse permettant au processeur de le retrouver.

Cependant, un programme moderne ne travaille généralement pas directement avec les adresses physiques de la RAM. Il utilise des adresses virtuelles.

Chaque processus possède ainsi son propre espace d’adressage virtuel.

Cela permet notamment :
  • d’isoler les processus ;
  • d’empêcher normalement un programme d’accéder directement à la mémoire d’un autre ;
  • de simplifier la gestion de la mémoire ;
  • de donner à chaque processus sa propre vision de la mémoire.
Deux processus peuvent donc utiliser la même adresse virtuelle sans que cette adresse corresponde nécessairement au même emplacement physique en RAM.

2. Memory Mapping

Le processeur doit traduire les adresses virtuelles utilisées par un programme vers des emplacements de mémoire physique.

La mémoire virtuelle est découpée en pages. Sous Windows x86/x64, une taille de page très courante est :

Code: Select all

4096 octets = 4 Ko
Le système et le processeur utilisent notamment des tables de pages pour établir la correspondance entre pages virtuelles et pages physiques.

Schématiquement :

Code: Select all

Adresse virtuelle
       |
       v
Tables de pages
       |
       v
Adresse physique
       |
       v
RAM
Une adresse virtuelle contient notamment une partie permettant de déterminer la page concernée et un déplacement, appelé offset, à l’intérieur de cette page.

Par exemple, avec des pages de 4096 octets :

Code: Select all

4096 = 2^12
Les 12 bits de poids faible peuvent donc représenter l’offset dans une page de 4 Ko.

Le système peut également définir des protections différentes pour les pages : lecture, écriture, exécution, etc.

Lorsqu’un programme tente d’accéder à une page qui n’est pas actuellement accessible de la manière demandée, le processeur déclenche une faute de page. Le système d’exploitation doit alors déterminer la raison de cette faute et la traiter si cela est possible.

Une faute de page n’implique donc pas automatiquement un crash. Certaines font partie du fonctionnement normal de la mémoire virtuelle. En revanche, un accès réellement invalide peut finir par provoquer une exception telle qu’une violation d’accès.

3. Modèle mémoire d’un processus Windows

L’espace mémoire d’un processus contient plusieurs régions ayant des rôles différents.

Une représentation simplifiée est :

Code: Select all

Adresses hautes
+--------------------+
| Heap               |
+--------------------+
| DLLs               |
+--------------------+
| Stack              |
+--------------------+
| .data / .bss       |
+--------------------+
| .text              |
+--------------------+
Adresses basses
Cette représentation est volontairement simplifiée. Dans un véritable processus Windows, l’espace d’adressage contient de nombreuses autres régions et leur emplacement exact peut varier.

Section .text

La section `.text` contient principalement le code machine du programme.

Exemple :

Code: Select all

section .text
global main

main:
    xor eax, eax
    ret
Les instructions assembleur deviennent après assemblage des octets exécutables placés dans cette région.

Section .data

La section `.data` contient les données initialisées.

Exemple :

Code: Select all

section .data

a dd 4
b dd 4.4
c times 10 dd 0
d dw 1, 2
e db 0xFF
f db "hello world", 0
Les valeurs sont déjà présentes dans l’image du programme.

Section .bss

La section `.bss` est utilisée pour réserver de l’espace pour des données non initialisées.

Exemple :

Code: Select all

section .bss

g resd 1
h resd 10
i resb 100
Ici, le programme demande de l’espace mémoire sans avoir besoin de stocker toutes les valeurs initiales dans le fichier exécutable.

4. Stack et Heap

La stack

La stack, ou pile, est notamment utilisée lors des appels de fonctions.

Elle peut contenir :
  • des variables locales ;
  • des adresses de retour ;
  • des registres sauvegardés ;
  • des données temporaires ;
  • certains paramètres selon l’architecture et la convention d’appel.
Exemple :

Code: Select all

push rbp
mov rbp, rsp
sub rsp, 16

xor eax, eax

leave
ret
L’instruction :

Code: Select all

sub rsp, 16
réserve ici 16 octets dans la frame de pile de la fonction.

Le heap

Le heap sert principalement aux allocations dynamiques.

En C/C++ :

Code: Select all

int* buffer = new int[100];
delete[] buffer;
Sous Windows, on peut également rencontrer des API telles que :

Code: Select all

HeapAlloc
HeapFree
VirtualAlloc
VirtualFree
Le heap n’est donc pas simplement une grosse variable : il correspond à une zone dont la gestion permet au programme d’obtenir et de libérer dynamiquement des blocs de mémoire.

Différence générale

Code: Select all

STACK
- fortement liée aux appels de fonctions
- variables locales
- gestion principalement automatique
- durée de vie souvent liée à la portée/appel

HEAP
- allocation dynamique
- taille choisie pendant l'exécution
- durée de vie contrôlée par le programme
- nécessite une gestion correcte des allocations
5. Sections et directives assembleur

En assembleur, plusieurs directives permettent de définir la taille des données.

On rencontre notamment :

Code: Select all

db    ; byte
dw    ; word
dd    ; double word
dq    ; quad word
Soit généralement :

Code: Select all

db = 1 octet
dw = 2 octets
dd = 4 octets
dq = 8 octets
Exemple :

Code: Select all

value8  db  10
value16 dw  1000
value32 dd  123456
value64 dq  123456789
Pour réserver de la mémoire dans `.bss`, NASM propose notamment :

Code: Select all

resb
resw
resd
resq
Exemple :

Code: Select all

buffer resb 100
array  resd 10
`buffer` réserve 100 octets alors que `array` réserve l’espace nécessaire à 10 double words.

La directive `times` permet de répéter une définition :

Code: Select all

values times 10 dd 0
Cela crée dix éléments de 4 octets initialisés à zéro.

6. Exemple pratique en assembleur

Prenons un programme contenant plusieurs variables :

Code: Select all

segment .data

a dd 4
b dd 4.4
c times 10 dd 0
d dw 1, 2
e db 0xFF
f db "hello world", 0

segment .bss

g resd 1
h resd 10
i resb 100

segment .text
global main

main:
    push rbp
    mov rbp, rsp
    sub rsp, 16

    xor eax, eax

    leave
    ret
Après assemblage, les données et les instructions deviennent des octets.

Un listing d’assembleur permet de faire le lien entre :
  • l’adresse ou l’offset ;
  • les octets générés ;
  • l’instruction ou la donnée correspondante.
Par exemple une instruction telle que :

Code: Select all

push rbp
peut être représentée par son opcode machine :

Code: Select all

55
C’est précisément ce que l’on retrouve dans un désassembleur : celui-ci lit les octets du code machine et tente de les traduire en instructions assembleur.

7. Représentation des données en mémoire

Lorsqu’on observe la mémoire dans un débogueur, on ne voit pas directement :

Code: Select all

"variable = 4"
On observe essentiellement des octets.

Par exemple, une valeur 32 bits peut apparaître sous la forme :

Code: Select all

04 00 00 00
Sur une architecture x86/x64, les entiers multi-octets sont généralement stockés en little endian : l’octet de poids faible se trouve à l’adresse la plus basse.

Par exemple :

Code: Select all

Valeur : 0x12345678

Mémoire :
78 56 34 12
Une chaîne C :

Code: Select all

"hello"
est représentée par les codes des caractères suivis du caractère nul :

Code: Select all

68 65 6C 6C 6F 00
Comprendre cette représentation est particulièrement important en reverse engineering.

8. Observer la mémoire avec un débogueur

Le chapitre utilise ebe pour examiner le programme.

Le principe est identique avec d’autres débogueurs modernes comme x64dbg, WinDbg ou GDB.

Une méthode classique consiste à :
  1. charger le programme ;
  2. placer un breakpoint ;
  3. lancer l’exécution ;
  4. attendre que le breakpoint soit atteint ;
  5. ouvrir une vue mémoire ;
  6. examiner l’adresse d’une variable.
Un breakpoint suspend temporairement l’exécution avant de laisser l’utilisateur examiner l’état du processus.

On peut alors observer :
  • les registres ;
  • la stack ;
  • le code désassemblé ;
  • les adresses ;
  • les données en mémoire.
9. Localiser et modifier une variable

Supposons que le programme possède :

Code: Select all

value dd 4
Dans le débogueur, on cherche l’adresse associée à `value`.

À cette adresse, on peut retrouver les quatre octets correspondant à la variable.

Pour la valeur 4 :

Code: Select all

04 00 00 00
Si l’on remplace ces octets par :

Code: Select all

0A 00 00 00
la valeur devient :

Code: Select all

10
On peut ensuite continuer l’exécution et observer comment le programme réagit.

Cette technique permet de comprendre une idée essentielle du reverse engineering :

les variables, structures, chaînes et instructions que l’on manipule dans le code finissent toutes par avoir une représentation concrète en mémoire.

10. Breakpoints et analyse dynamique

Un breakpoint permet d’arrêter le programme à un endroit précis.

Par exemple :

Code: Select all

mov eax, [variable]
En arrêtant l’exécution avant cette instruction, on peut examiner la mémoire pointée par `variable`.

Après l’exécution de l’instruction, on peut vérifier le contenu de `eax`.

Cette approche permet de suivre le trajet d’une donnée :

Code: Select all

Mémoire
   |
   v
Instruction
   |
   v
Registre
   |
   v
Calcul
   |
   v
Nouvelle valeur
C’est une compétence fondamentale lorsqu’on analyse un programme sans disposer de son code source.

11. Ce qu’il faut retenir

Les points essentiels de ce chapitre sont :
  • un processus utilise principalement des adresses virtuelles ;
  • le système et le matériel traduisent ces adresses vers la mémoire physique ;
  • la mémoire virtuelle est organisée en pages ;
  • un processus possède plusieurs régions mémoire ayant des rôles différents ;
  • `.text` contient principalement le code ;
  • `.data` contient des données initialisées ;
  • `.bss` réserve des données non initialisées ;
  • la stack est fortement liée aux appels de fonctions et aux variables locales ;
  • le heap permet les allocations dynamiques ;
  • les données sont finalement représentées par des octets ;
  • x86/x64 utilise le little endian pour les valeurs multi-octets ;
  • un débogueur permet d’observer les registres et la mémoire pendant l’exécution ;
  • les breakpoints permettent d’arrêter le programme pour suivre précisément les données.
Pour le reverse engineering, l’objectif n’est donc pas seulement de savoir lire des instructions comme `mov`, `cmp` ou `call`. Il faut également être capable de comprendre où les données se trouvent, comment elles sont représentées et comment les instructions les manipulent.

12. Exercices

Exercice 1

Quelle quantité de mémoire est réservée ici ?

Code: Select all

buffer resd 20
Exercice 2

Quelle valeur représente cette suite d’octets en little endian ?

Code: Select all

78 56 34 12
Exercice 3

Dans quelle section placerais-tu chacune des données suivantes ?

Code: Select all

message db "Hello", 0
counter dd 10
buffer resb 256
Exercice 4

Place un breakpoint avant une instruction qui charge une variable en registre. Observe la variable en mémoire, exécute une instruction puis vérifie le registre correspondant.

Exercice 5

Crée plusieurs variables avec :

Code: Select all

db
dw
dd
dq
Puis observe leur représentation dans la fenêtre mémoire du débogueur.

Exercice 6

Définis une valeur :

Code: Select all

number dd 0x12345678
Avant d’exécuter le programme, prédis l’ordre exact des quatre octets que tu devrais observer en mémoire, puis vérifie ta réponse dans le débogueur.

Who is online

Users browsing this forum: No registered users and 1 guest