Cours sur le Registre de Windows

Développement système natif en c/c++ avec win32 ...

Moderator: Rick

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

Cours sur le Registre de Windows

Post by Hydraxx »

Salut, :D

aujourd’hui on va voir un composant vraiment central de Windows : le registre.

C’est un sujet incontournable en développement système, parce qu’une très grande partie de la configuration de Windows et des logiciels passe par lui. Services, pilotes, paramètres noyau, shell, associations de fichiers, politiques, configuration applicative, profils utilisateurs, COM, installation de logiciels… le registre est partout.

Le problème, c’est que beaucoup de développeurs s’en servent comme d’une simple “boite à paramètres” sans vraiment comprendre ce que c’est, comment il est structuré, comment les accès sont sécurisés, quelles sont les bonnes API, ou encore pourquoi certaines opérations échouent selon le compte, l’intégrité ou la vue 32/64 bits utilisée.

Pourquoi le registre est un sujet fondamental

Comprendre correctement le registre permet de mieux voir :
  • comment Windows stocke une grande partie de sa configuration
  • comment les logiciels enregistrent leurs paramètres
  • pourquoi certaines clés sont accessibles et d’autres non
  • comment lire, écrire, créer, supprimer et énumérer proprement des clés et valeurs
  • comment fonctionnent les notifications de changement
  • comment le registre interagit avec les tokens, l’UAC et la vue Wow64
  • pourquoi un service, un pilote ou un composant COM dépend souvent directement du registre
Autrement dit, le registre n’est pas juste une API parmi d’autres. C’est l’un des grands mécanismes de configuration de Windows.

Ce qu’est réellement le registre Windows

Le registre Windows est une base de données hiérarchique gérée par le système. Il stocke des paramètres structurés sous forme de clés et de valeurs. Historiquement, il a remplacé ou centralisé beaucoup d’informations qui étaient auparavant dispersées dans des fichiers INI ou autres mécanismes plus simples.

Il contient notamment :
  • des paramètres système
  • des paramètres utilisateur
  • des informations sur les services
  • des informations sur les pilotes
  • des données d’installation logicielle
  • des associations de fichiers
  • des informations COM et shell
  • des politiques et réglages de sécurité
Il faut bien comprendre ce qu’il n’est pas.

Le registre :
  • n’est pas un simple fichier texte
  • n’est pas un XML
  • n’est pas une base SQL exposée directement à l’utilisateur
  • n’est pas fait pour etre “parcouru à la main” par du code sans API dédiée
Tout passe par des API prévues pour cela.

Le registre n’est pas juste “un fichier caché”

Derrière le registre, il existe des fichiers de ruches sur disque, mais il ne faut pas raisonner comme si l’application lisait directement un fichier structuré. Le système charge, maintient, arbitre, sécurise et expose ces données via le Configuration Manager coté noyau et les API user-mode adaptées.

Cela a plusieurs conséquences :
  • les accès sont contrôlés par sécurité
  • les vues peuvent varier selon le contexte 32/64 bits
  • certaines clés sont virtuelles ou redirigées
  • les modifications peuvent etre observées par le système ou d’autres composants
Les grandes ruches du registre

Les racines principales que l’on rencontre en user-mode sont :
  • HKEY_LOCAL_MACHINE, souvent abrégé HKLM
  • HKEY_CURRENT_USER, souvent abrégé HKCU
  • HKEY_CLASSES_ROOT, souvent abrégé HKCR
  • HKEY_USERS, souvent abrégé HKU
  • HKEY_CURRENT_CONFIG, souvent abrégé HKCC
Il faut immédiatement préciser une chose : ces HKEY racines sont des handles spéciaux prédéfinis, pas des chemins texte. On les utilise comme points de départ des API.

Leur rôle général :
  • HKLM contient surtout des paramètres machine
  • HKCU contient surtout les paramètres du profil utilisateur courant
  • HKCR concerne notamment les classes et associations
  • HKU expose les ruches des utilisateurs chargés
  • HKCC donne accès à une vue de la configuration matérielle courante
HKCU, HKLM, HKCR : bien comprendre les différences

Trois racines reviennent particulièrement souvent.

HKCU :
  • contient les paramètres de l’utilisateur courant
  • renvoie en pratique vers la ruche de cet utilisateur sous HKU
  • est souvent le bon endroit pour des réglages applicatifs par utilisateur
HKLM :
  • contient des paramètres machine
  • est souvent utilisé pour des réglages globaux
  • demande fréquemment des droits élevés pour l’écriture
HKCR :
  • est une vue combinée liée aux classes
  • intervient dans les associations de fichiers, COM, ProgID, CLSID, etc.
  • ne doit pas etre abordé naïvement comme une simple ruche indépendante
Clés et valeurs : la structure logique

Le registre est composé de deux grandes notions :
  • les clés
  • les valeurs
Une clé ressemble conceptuellement à un dossier. Elle peut contenir :
  • des sous-clés
  • des valeurs
Une valeur ressemble conceptuellement à une entrée nommée associée à un type et à des données. Une valeur possède donc :
  • un nom
  • un type
  • une donnée brute
Il faut bien comprendre qu’une clé n’est pas une valeur, et qu’une valeur n’est pas elle-meme une sous-clé.

Les types de valeurs importants

Le registre stocke les données avec un type. Parmi les types les plus courants :
  • REG_SZ : chaine Unicode terminée par zéro
  • REG_EXPAND_SZ : chaine contenant des variables d’environnement expansibles
  • REG_MULTI_SZ : liste de chaines Unicode, doublement terminée par zéro
  • REG_DWORD : entier 32 bits
  • REG_QWORD : entier 64 bits
  • REG_BINARY : données binaires brutes
  • REG_NONE : données sans typage particulier exploitable
Il faut absolument vérifier le type lors d’une lecture sérieuse, surtout si on n’est pas certain du contenu réel de la clé.

HKEY : ce que c’est vraiment

Le type HKEY représente une clé de registre ouverte ou une racine prédéfinie. Visuellement, il ressemble à un handle, et conceptuellement c’en est un pour le monde du registre, mais attention : un HKEY ne se ferme pas avec CloseHandle.

Il se ferme avec :
  • RegCloseKey
C’est une erreur classique de croire que parce que “ça ressemble à un handle”, CloseHandle suffit. Non. Le registre a sa propre famille d’API.

Ouvrir une clé existante

Pour ouvrir une clé déjà existante, l’API de base est :
  • RegOpenKeyExW
Exemple :

Code: Select all

HKEY hKey = NULL;

LONG status = RegOpenKeyExW(
    HKEY_CURRENT_USER,
    L"Software\\MyApp",
    0,
    KEY_READ,
    &hKey
);

if (status != ERROR_SUCCESS)
    return 1;
Paramètres importants à comprendre :
  • la racine ou clé parente
  • le chemin relatif de la sous-clé
  • les options réservées
  • le masque d’accès désiré
  • l’adresse recevant le HKEY ouvert
Une fois ouvert, ce HKEY doit etre fermé avec RegCloseKey.

Créer ou ouvrir une clé avec RegCreateKeyExW

Quand on veut créer une clé si elle n’existe pas, ou l’ouvrir si elle existe déjà, l’API classique est :
  • RegCreateKeyExW
Exemple :

Code: Select all

HKEY hKey = NULL;
DWORD disposition = 0;

LONG status = RegCreateKeyExW(
    HKEY_LOCAL_MACHINE,
    L"Software\\MyApp",
    0,
    NULL,
    0,
    KEY_WRITE,
    NULL,
    &hKey,
    &disposition
);

if (status != ERROR_SUCCESS)
    return 1;
Le paramètre disposition est très utile. Il permet de savoir si la clé a été réellement créée ou simplement ouverte. Les valeurs fréquentes sont :
  • REG_CREATED_NEW_KEY
  • REG_OPENED_EXISTING_KEY
Lire une valeur : RegQueryValueExW

L’API classique de lecture est :
  • RegQueryValueExW
Exemple simple pour un DWORD :

Code: Select all

DWORD type = 0;
DWORD size = sizeof(DWORD);
DWORD data = 0;

LONG status = RegQueryValueExW(
    hKey,
    L"Enabled",
    NULL,
    &type,
    (LPBYTE)&data,
    &size
);

if (status != ERROR_SUCCESS)
    return 1;

if (type != REG_DWORD)
    return 1;
Comme pour beaucoup d’API Win32, il faut bien gérer la taille du buffer. Pour des données de taille variable, le modèle propre consiste souvent à faire un premier appel avec buffer NULL pour récupérer la taille, puis un second appel réel.

Exemple de schéma :

Code: Select all

DWORD type = 0;
DWORD size = 0;

LONG status = RegQueryValueExW(
    hKey,
    L"MyString",
    NULL,
    &type,
    NULL,
    &size
);

if (status != ERROR_SUCCESS)
    return 1;

/* allocation du buffer puis second appel */
Lire plus proprement avec RegGetValueW

Il faut aussi connaitre une API souvent plus pratique :
  • RegGetValueW
Elle permet de combiner plus proprement certains scénarios de lecture et de filtrer le type attendu.

Par exemple, on peut demander explicitement une lecture de type REG_DWORD ou REG_SZ. C’est souvent plus propre que RegQueryValueExW quand on veut du code un peu mieux cadré.

Ecrire une valeur : RegSetValueExW

Pour écrire une valeur existante ou nouvelle :
  • RegSetValueExW
Exemple pour un DWORD :

Code: Select all

DWORD data = 1;

LONG status = RegSetValueExW(
    hKey,
    L"Enabled",
    0,
    REG_DWORD,
    (const BYTE*)&data,
    sizeof(data)
);

if (status != ERROR_SUCCESS)
    return 1;
Exemple pour une chaine REG_SZ :

Code: Select all

const wchar_t* text = L"Bonjour";

LONG status = RegSetValueExW(
    hKey,
    L"Message",
    0,
    REG_SZ,
    (const BYTE*)text,
    (DWORD)((wcslen(text) + 1) * sizeof(wchar_t))
);
Il faut bien faire attention à la taille en octets, pas en nombre de caractères.

Supprimer une valeur ou une clé

Pour supprimer une valeur :
  • RegDeleteValueW
Exemple :

Code: Select all

RegDeleteValueW(hKey, L"Enabled");
Pour supprimer une clé, plusieurs API existent selon le contexte :
  • RegDeleteKeyW
  • RegDeleteKeyExW
  • RegDeleteTreeW
RegDeleteKeyW est l’API historique, mais elle a des limites selon le contenu ou la vue. RegDeleteTreeW est souvent très utile pour supprimer une clé et tout son sous-arbre.

Exemple :

Code: Select all

RegDeleteTreeW(HKEY_CURRENT_USER, L"Software\\MyApp");
Il faut etre très prudent avec ces API, surtout sous HKLM ou dans des zones système.

Droits d’accès sur les clés du registre

Le registre est sécurisé comme beaucoup d’autres objets Windows. Les accès sont soumis à des droits.

Masques d’accès importants :
  • KEY_QUERY_VALUE
  • KEY_SET_VALUE
  • KEY_CREATE_SUB_KEY
  • KEY_ENUMERATE_SUB_KEYS
  • KEY_NOTIFY
  • KEY_CREATE_LINK
  • KEY_READ
  • KEY_WRITE
  • KEY_EXECUTE
  • KEY_ALL_ACCESS
Comme toujours, il vaut mieux demander exactement ce dont on a besoin plutôt que KEY_ALL_ACCESS par réflexe.

Registre, tokens, ACL et UAC

Les accès au registre dépendent directement du contexte de sécurité.

Cela implique notamment :
  • le token du processus ou du thread
  • les ACL de la clé
  • le niveau d’intégrité
  • l’UAC
  • la zone du registre visée
Ecrire sous HKLM, par exemple, demande souvent une élévation ou des droits adaptés. Ecrire sous HKCU est généralement plus simple pour le profil courant.

Autrement dit, un échec sur RegCreateKeyExW ou RegSetValueExW ne veut pas dire que l’API est “capricieuse”. Très souvent, la sécurité explique parfaitement l’erreur.

Enumérer les sous-clés et valeurs

Pour explorer le contenu du registre, il faut connaitre les API d’énumération.

Pour les sous-clés :
  • RegEnumKeyExW
Pour les valeurs :
  • RegEnumValueW
Exemple conceptuel de sous-clés :

Code: Select all

DWORD index = 0;
wchar_t name[256];
DWORD nameLen = 256;

while (RegEnumKeyExW(
    hKey,
    index,
    name,
    &nameLen,
    NULL,
    NULL,
    NULL,
    NULL) == ERROR_SUCCESS)
{
    /* traitement */

    index++;
    nameLen = 256;
}
Il faut faire attention à réinitialiser les tailles de buffer entre les appels.

Obtenir des informations générales sur une clé

Une API très utile à connaitre est :
  • RegQueryInfoKeyW
Elle permet d’obtenir des informations globales sur une clé, par exemple :
  • le nombre de sous-clés
  • le nombre de valeurs
  • la longueur maximale des noms
  • la longueur maximale des données
  • le timestamp de dernière écriture
C’est une fonction très utile pour les outils ou pour préparer des buffers d’énumération.

Notifications de changement dans le registre

Le registre peut aussi etre surveillé. L’API centrale ici est :
  • RegNotifyChangeKeyValue
Elle permet d’etre notifié lorsqu’une clé change, par exemple :
  • ajout ou suppression de sous-clé
  • changement de valeur
  • modification d’attributs de sécurité
C’est une API importante pour les outils de supervision, certains agents, ou des programmes qui doivent réagir à des modifications de configuration.

Flusher le registre

Il existe aussi :
  • RegFlushKey
Cette API force l’écriture sur disque de certaines modifications associées à une clé. Elle a un cout non négligeable, donc il ne faut pas l’utiliser par réflexe. Mais il est bon de savoir qu’elle existe.

API avancées utiles à connaitre

Au-delà des fonctions de base, plusieurs API valent la peine d’etre connues de nom au minimum :
  • RegOpenCurrentUser
  • RegOpenUserClassesRoot
  • RegOpenKeyTransactedW
  • RegCreateKeyTransactedW
  • RegDeleteKeyTransactedW
  • RegCopyTreeW
  • RegRenameKey
  • RegLoadKeyW
  • RegUnLoadKeyW
  • RegSaveKeyW
  • RegRestoreKeyW
  • RegReplaceKeyW
  • RegConnectRegistryW
  • RegDisableReflectionKey
  • RegEnableReflectionKey
  • RegQueryReflectionKey
Toutes ne sont pas utilisées dans chaque projet, mais les connaitre permet de mieux lire du code système ou des outils d’admin avancés.

Transactions registre : à connaitre de nom

Windows a aussi proposé des API transacted pour certaines opérations, par exemple :
  • RegOpenKeyTransactedW
  • RegCreateKeyTransactedW
Leur intérêt historique était de s’intégrer au modèle transactionnel du système. Ce n’est pas la voie la plus courante aujourd’hui dans l’applicatif classique, mais il est bon de savoir qu’elles existent.

Le registre distant

Windows permet aussi, dans certains contextes, d’ouvrir une vue du registre sur une machine distante avec :
  • RegConnectRegistryW
C’est surtout utile pour l’administration ou certains outils d’entreprise, mais cela montre bien que le registre n’est pas juste un objet “local simpliste”. Il s’inscrit dans un modèle plus large de gestion système.

Registre et services

Les services Windows dépendent fortement du registre. Une zone fondamentale à connaitre est :

Code: Select all

HKLM\\SYSTEM\\CurrentControlSet\\Services
On y trouve notamment :
  • la configuration des services
  • les chemins binaires
  • les types de démarrage
  • les dépendances
  • les paramètres de pilotes et services
Autrement dit, le SCM ne vit pas “à coté” du registre : il lit et exploite directement une partie importante de sa configuration via lui.

Registre et pilotes

Les pilotes Windows ont eux aussi une relation étroite avec le registre. Leur configuration, leur chargement et certains paramètres d’initialisation s’appuient souvent sur des clés du registre, notamment sous la zone Services. C’est important à garder en tete quand on fait du système plus bas niveau.

Vue 32 bits / 64 bits et Wow64

Un point très important, souvent mal compris, concerne la vue 32 bits / 64 bits du registre sur les systèmes 64 bits.

Selon le contexte du processus et les flags utilisés, un programme peut voir une vue différente du registre, notamment sous certaines branches comme Software.

Flags importants à connaitre :
  • KEY_WOW64_32KEY
  • KEY_WOW64_64KEY
Cela permet de choisir explicitement la vue 32 bits ou 64 bits dans certaines opérations.

Sans comprendre ce point, on peut croire que le registre “ment” ou “ne contient pas la bonne clé”, alors qu’en réalité on regarde simplement une vue différente.

Redirection et réflexion du registre

Historiquement, sur les systèmes Wow64, certaines parties du registre impliquent des mécanismes de redirection, voire de réflexion selon les versions et scénarios. Il faut au moins connaitre ces notions de nom, car elles expliquent beaucoup de comportements surprenants dans les applications 32 bits sur système 64 bits.

API liées :
  • RegDisableReflectionKey
  • RegEnableReflectionKey
  • RegQueryReflectionKey
Sauvegarde, restauration et chargement de ruches

Le registre n’est pas seulement un objet que l’on consulte clé par clé. Certaines API permettent d’intervenir à un niveau plus “hive”.

Parmi les API importantes à connaitre de nom :
  • RegSaveKeyW
  • RegRestoreKeyW
  • RegLoadKeyW
  • RegUnLoadKeyW
  • RegReplaceKeyW
Ces API sont plus sensibles, souvent plus administratives, et parfois liées à des privilèges spécifiques comme SeBackupPrivilege ou SeRestorePrivilege.

Les structures et types utiles autour du registre

Le monde du registre utilise moins de grosses structures que d’autres domaines Win32, mais il faut quand meme connaitre plusieurs types et notions importantes :
  • HKEY
  • FILETIME
  • SECURITY_ATTRIBUTES
  • SECURITY_DESCRIPTOR
  • ACL
  • DWORD
  • LPBYTE
FILETIME est par exemple utilisé par RegQueryInfoKeyW pour retourner la date de dernière écriture.

SECURITY_ATTRIBUTES et SECURITY_DESCRIPTOR interviennent dans des scénarios de sécurité plus avancés sur les clés.

Bonnes pratiques de lecture et écriture

Quand on manipule le registre proprement, quelques règles simples évitent beaucoup d’erreurs :
  • toujours utiliser les versions W des API
  • toujours vérifier le code de retour LONG
  • toujours valider le type retourné avant d’interpréter les données
  • gérer correctement les tailles de buffers
  • fermer chaque HKEY ouvert avec RegCloseKey
  • éviter d’écrire sous HKLM si HKCU suffit
  • ne pas demander KEY_ALL_ACCESS sans raison
  • faire attention à la vue 32/64 bits
API très utiles à connaitre absolument

Pour ouvrir, créer et fermer :
  • RegOpenKeyExW
  • RegCreateKeyExW
  • RegCloseKey
Pour lire et écrire :
  • RegQueryValueExW
  • RegGetValueW
  • RegSetValueExW
Pour supprimer :
  • RegDeleteValueW
  • RegDeleteKeyW
  • RegDeleteKeyExW
  • RegDeleteTreeW
Pour énumérer et interroger :
  • RegEnumKeyExW
  • RegEnumValueW
  • RegQueryInfoKeyW
Pour notifications et maintenance :
  • RegNotifyChangeKeyValue
  • RegFlushKey
  • RegCopyTreeW
  • RegRenameKey
Pour les vues et scénarios spéciaux :
  • KEY_WOW64_32KEY
  • KEY_WOW64_64KEY
  • RegConnectRegistryW
  • RegOpenCurrentUser
Erreurs classiques

Comme souvent en Win32, les erreurs les plus gênantes viennent d’une mauvaise compréhension des bases.

Parmi les fautes fréquentes :
  • oublier RegCloseKey
  • utiliser CloseHandle au lieu de RegCloseKey
  • écrire dans HKLM sans comprendre les droits nécessaires
  • ignorer le type réel d’une valeur
  • mal gérer la taille des buffers
  • utiliser ANSI au lieu des API W
  • croire qu’une clé “n’existe pas” alors qu’on regarde la mauvaise vue 32/64 bits
  • modifier des zones système sans comprendre leurs effets
  • supposer que HKCR est une ruche simple et autonome
Ce qu’il faut retenir

Le registre Windows est une base de données hiérarchique de configuration gérée par le système. Il organise ses données en clés et valeurs, exposées via des API dédiées. Chaque clé ouverte est représentée par un HKEY, qui doit etre fermé proprement avec RegCloseKey.

Les idées essentielles à garder sont les suivantes :
  • le registre n’est pas un fichier texte
  • HKLM, HKCU, HKCR, HKU et HKCC sont les grandes racines à connaitre
  • une clé contient des sous-clés et des valeurs
  • chaque valeur possède un type et une donnée
  • les accès sont protégés par sécurité, tokens et ACL
  • les services, pilotes et beaucoup de composants Windows dépendent directement du registre
  • la vue 32/64 bits peut changer ce qu’un processus voit
  • les notifications de changement et l’énumération font partie du modèle réel
Conclusion

Comprendre le registre, c’est comprendre comment Windows stocke une très grande partie de sa configuration et de celle des logiciels. C’est aussi comprendre que ce n’est pas une simple arborescence de noms, mais un mécanisme système avec sécurité, vues, types de données, hiérarchie, notifications et rôle central dans l’architecture du système.

Si tu maitrises déjà correctement :
  • RegOpenKeyExW
  • RegCreateKeyExW
  • RegQueryValueExW
  • RegGetValueW
  • RegSetValueExW
  • RegDeleteValueW
  • RegDeleteTreeW
  • RegEnumKeyExW
  • RegEnumValueW
  • RegQueryInfoKeyW
  • RegNotifyChangeKeyValue
  • RegCloseKey
alors tu possèdes déjà une base sérieuse sur le registre Windows.

Et surtout, tu commences à voir que le registre n’est pas juste “l’endroit où l’on met une option”, mais un vrai pilier de configuration du système Windows.

A bientot pour le prochain cours :D

Who is online

Users browsing this forum: No registered users and 0 guests