B.Allouer la mémoire en RW et changer en RX avant l'exécution

Introduction :

On repart du code de la partie A cependant avant toute implémentation il est nécessaire de comprendre la mémoire et les termes RW et RX

Théorie :

1. Les Permissions Mémoire (RWX)

La mémoire vive (RAM) n'est pas juste un long ruban de données. Elle est divisée en pages (souvent de 4 Ko). Le processeur, aidé par le système d'exploitation, applique des règles strictes sur ce que l'on peut faire avec chaque page. C'est ce qu'on appelle la protection de mémoire.

  • R (Read - Lecture) : Autorise le processeur à lire le contenu de la page. Si vous essayez de lire une page sans ce droit, le programme plante (Access Violation).

  • W (Write - Écriture) : Autorise le programme à modifier ou écrire des données dans la page.

  • X (Execute - Exécution) : C'est le droit le plus "puissant". Il autorise le processeur à traiter les données de la page comme des instructions machine. Sans ce droit, même si vous avez du code binaire parfait, le processeur refusera de le lire et déclenchera une erreur de sécurité (appelée DEP pour Data Execution Prevention).

Règle d'or de la sécurité : Pour éviter les attaques, les systèmes modernes essaient d'appliquer le principe W^X (Write XOR Execute). Une page peut être soit écrivable (RW), soit exécutable (RX), mais idéalement jamais les deux en même temps (RWX).


2. L'Organisation de la Mémoire d'un Processus

Lorsqu'un programme (comme .exe) est lancé, Windows crée un "espace d'adressage virtuel". Voici comment il est découpé de haut en bas :

A. La Section Code (.text)

C'est ici que se trouve votre programme compilé.

  • Permission : RX (On lit et on exécute, mais on ne modifie pas son propre code pendant qu'il tourne).

B. La Section Données (.data / .rdata)

Contient les variables globales et les constantes (comme les chaînes de caractères).

  • Permission : RW ou R.

C. Le Heap (Le Tas)

C'est une grande zone de stockage "en vrac". Le programme y demande de la place quand il en a besoin (ex: malloc en C).

  • Permission : RW.

D. La Stack (La Pile)

C'est la zone la plus ordonnée et la plus rapide. Elle sert à gérer la "vie" des fonctions.


3. La Stack (La Pile) en détail

La Stack suit le principe LIFO (Last In, First Out). Imaginez une pile d'assiettes : vous ne pouvez ajouter ou retirer une assiette que par le haut.

Chaque fois que vous appelez une fonction, Windows crée un Stack Frame (un cadre de pile) pour cette fonction. Ce cadre contient :

  1. Les arguments passés à la fonction.

  2. L'adresse de retour : L'endroit où le processeur doit retourner une fois la fonction terminée.

  3. Les variables locales : Celles que vous déclarez à l'intérieur de { ... }.


4. Les Registres : Les mains du Processeur

Le processeur (CPU) possède ses propres zones de stockage ultra-rapides appelées Registres. En 64 bits, ils font 8 octets chacun.

Les registres de contrôle (Les plus critiques) :

  • RIP (Instruction Pointer) : C'est le "curseur". Il contient l'adresse de la prochaine instruction que le processeur va exécuter. Si vous arrivez à changer la valeur de RIP, vous contrôlez ce que l'ordinateur fait.

  • RSP (Stack Pointer) : Il pointe toujours sur le sommet de la pile (l'assiette tout en haut). Il descend quand on ajoute des données (PUSH) et remonte quand on en retire (POP).

  • RBP (Base Pointer) : Il sert d'ancre pour la fonction actuelle. Il pointe sur le début du Stack Frame pour retrouver facilement les variables locales.

Les registres de données :

  • RAX : Souvent utilisé pour stocker le résultat d'une fonction (si une fonction renvoie 1, RAX contiendra 1).

  • RCX, RDX, R8, R9 : Utilisés pour passer les 4 premiers arguments à une fonction sous Windows (Convention d'appel x64).


Résumé du fonctionnement :

  1. Le RIP pointe sur une instruction dans la section Code (RX).

  2. Le processeur exécute l'instruction.

  3. Si l'instruction a besoin d'une variable locale, il va la chercher dans la Stack en utilisant le RSP ou le RBP.

  4. Si vous appelez une fonction, l'adresse actuelle est sauvegardée sur la Stack, et le RIP saute à la nouvelle adresse de la fonction.

5. Pourquoi avoir une zone RW puis RX ?

Dans un système Windows moderne, il est extrêmement rare qu'un programme légitime ait besoin d'une page mémoire qui soit à la fois modifiable (Write) et exécutable (Execute).

  • Logiciels légitimes : Ils séparent strictement les données (RW) du code (RX).

  • Exception : Seuls les moteurs JIT (Just-In-Time) comme ceux des navigateurs web (Chrome, Firefox) pour le JavaScript utilisent du RWX.

Conséquence OPSEC : Les antivirus et les EDR (Endpoint Detection and Response) surveillent spécifiquement l'appel système VirtualAlloc avec l'argument PAGE_EXECUTE_READWRITE. Si ton programme demande du RWX, il déclenche immédiatement une alerte de "comportement suspect".

6. Code :

Last updated