Explication général
Partie 1 : Introduction à l'API Windows
1. Qu'est-ce que l'API Windows ?
L'API Windows (ou Win32 API pour les systèmes 32 bits, bien que le terme soit toujours utilisé pour le 64 bits) est l'ensemble de fonctions, structures, messages et constantes qui permet aux applications de communiquer avec le système d'exploitation Windows (OS).
Lorsque votre code C/C++ appelle une fonction comme CreateThread ou VirtualAlloc, il fait appel à une routine dans le noyau de Windows.
2. Les Bibliothèques Fondamentales (DLLs)
Les fonctions de l'API Windows sont organisées en Bibliothèques de Liens Dynamiques (DLL). Les trois plus importantes pour un loader sont :
DLL
Rôle Principal
Exemple de Fonction
Kernel32.dll
Gestion de la mémoire, des processus, des threads, de la synchronisation et des fichiers.
VirtualAlloc, CreateThread, LoadLibrary
User32.dll
Gestion de l'interface utilisateur (fenêtres, événements souris/clavier).
MessageBox, GetForegroundWindow
Ntdll.dll
Interface directe avec le noyau NT (couche la plus basse). C'est la cible des Syscalls directes.
NtAllocateVirtualMemory, NtProtectVirtualMemory
3. Utilisation dans le Code C
Pour utiliser ces fonctions dans votre code C ou C++, vous avez besoin de deux éléments principaux :
Inclusion : Vous devez inclure le fichier d'en-tête principal :
#include <windows.h>Ce fichier contient les déclarations de toutes les fonctions et les définitions des types Windows (
DWORD,HANDLE,BOOL, etc.).Types de Données : L'API Windows utilise ses propres types de données qui sont des alias (typedefs) pour les types C standards. Par exemple :
HANDLEest souvent unvoid*pour représenter un objet du noyau (thread, fichier, processus).DWORDest un entier 32 bits non signé (unsigned int).
🔎 Partie 2 : Comment Retrouver les Fonctions (Résolution d'Adresses)
Pour qu'un programme puisse appeler une fonction comme VirtualAlloc, il doit connaître son adresse en mémoire. Il existe deux méthodes :
1. Liaison Statique (Méthode Standard et Bruyante)
Lors de la compilation, le linker ajoute une référence à VirtualAlloc dans la Table d'Adresses d'Importation (IAT) de votre exécutable. Lorsque Windows charge votre programme :
Il trouve
VirtualAllocdansKernel32.dll.Il inscrit l'adresse en mémoire dans l'IAT.
Votre programme appelle cette adresse.
2. Liaison Dynamique (Méthode Manuelle et Furtive)
C'est la méthode privilégiée par les loaders pour l'évasion, car elle permet de charger des fonctions qui ne sont pas visibles dans l'IAT du fichier sur le disque (contournant ainsi l'analyse statique).
Deux fonctions sont essentielles dans ce processus :
A. LoadLibrary
Cette fonction est utilisée pour charger manuellement une DLL en mémoire. Elle renvoie un handle (l'adresse de base) de la DLL.
(HMODULE est le type de handle pour une DLL. L'ajout de 'A' indique la version ANSI, basée sur les chaînes de caractères standards).
B. GetProcAddress
Une fois que vous avez le handle de la DLL, cette fonction trouve l'adresse en mémoire d'une fonction spécifique à partir de son nom.
(FARPROC est un type de pointeur générique pour les fonctions d'API).
Le Schéma de Récupération (Fonction Pointer)
Une fois l'adresse obtenue, vous devez la caster dans le type de pointeur de fonction approprié pour pouvoir l'appeler.
typedef LPVOID (WINAPI *pVIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD);
Les Types Entiers Fondamentaux (Basés sur la Taille)
Ces types de données définissent la taille de la variable et sont les plus couramment utilisés dans les paramètres des fonctions WinAPI comme VirtualAlloc.
Type WinAPI
Définition C standard (Typique)
Taille (Bits)
Description
BYTE
unsigned char
8
Un octet. Souvent utilisé pour les tableaux de données brutes ou les octets uniques (comme votre shellcode).
WORD
unsigned short
16
Un « mot » (Word). Entier non signé.
DWORD
unsigned long
32
Double Word (Double mot). C'est le type le plus commun pour les flags, les identifiants et les longueurs.
ULONGLONG
unsigned long long
64
Entier non signé de 64 bits.
INT / UINT
int / unsigned int
32
L'équivalent de l'entier standard.
SIZE_T
size_t
32 ou 64
Entier non signé utilisé pour représenter la taille des objets en mémoire. Il prend la taille d'un pointeur (32 bits sur un OS 32 bits, 64 bits sur un OS 64 bits).
🗂️ Les Types Spéciaux (Pointeurs et Objets)
Ces types ne représentent pas seulement une taille, mais un concept spécifique du système d'exploitation ou de la programmation.
Type WinAPI
Définition C standard (Typique)
Description
HANDLE
void *
Gestionnaire d'objet. C'est l'identifiant opaque d'un objet géré par le noyau (un thread, un processus, un fichier, etc.). Par exemple, CreateThread renvoie un HANDLE.
BOOL
int (32 bits)
Type booléen utilisé par l'API pour les valeurs de retour (VRAI/FAUX). Attention : Dans WinAPI, VRAI est non-zéro (souvent 1), et FAUX est zéro (0).
BOOLEAN
BYTE (8 bits)
Type booléen utilisé principalement dans le code du noyau (NTDLL).
VOID
void
Identique au type void en C.
FARPROC
int (__stdcall *)(...)
Pointeur vers une fonction d'API. Utilisé comme valeur de retour par GetProcAddress.
💬 Les Conventions de Nommage (Préfixes)
L'API Windows utilise des préfixes pour décrire la nature d'un pointeur ou d'une chaîne de caractères. Ces conventions sont essentielles, surtout pour le travail avec l'unicode.
1. Pointeurs (P et LP)
P et LP)PouLP(Long Pointer) : Indique que la variable est un pointeur vers un autre type.Exemple :
LPDWORDest un pointeur vers unDWORD.
2. Chaînes de Caractères (A, W, T)
A, W, T)Les fonctions de l'API Windows existent généralement en deux versions pour gérer les chaînes de caractères :
Suffixe
A(ANSI) : Utilise des chaînes de caractères d'un octet (ASCII/ISO 8859-1).Exemple :
CreateFileA.
Suffixe
W(Wide) : Utilise des chaînes de caractères de deux octets (Unicode/UTF-16).Exemple :
CreateFileW.
Le type TCHAR et les pointeurs associés sont des alias qui se résolvent en char ou en wchar_t en fonction des options de compilation du projet :
TCHAR: Se résout enchar(ANSI) ou enwchar_t(Unicode).LPTSTR: Long Pointer to T-String. Se résout enchar *ouwchar_t *.
En programmation de loader, vous verrez souvent les versions A (ANSI) comme LoadLibraryA ou GetProcAddressA, car elles sont plus simples à utiliser pour coder des chaînes de caractères fixes sans avoir à se soucier de l'encodage Unicode.
Last updated