Annonce

Réduire
Aucune annonce.

Manipulation de la base de registre de Microsoft Windows

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Tutoriel Manipulation de la base de registre de Microsoft Windows

    Ce tutoriel présente les principales fonctions mises à disposition par Microsoft pour manipuler la base de registre dans les programmes en C. Nous verrons comment ajouter, lire, et modifier des clés dans la base de registre Windows.

    Cet article s’adresse majoritairement aux débutants ; quelques bases de C suffisent, notamment sur les pointeurs. Des notions en ce qui concerne la gestion des fichiers (files descriptors) et les handles sont facultatives mais permettront de mieux comprendre les concepts de base.

    Sommaire

    Pour commencer
    Les handles
    Vocabulaire du registre
    Ouverture d'une clé
    Modification d'une valeur

    Remarque :

    Je ne vais expliquer que quelques fonctions parmis les nombreuses mises à disposition. En fait, c’est toujours le même principe. Je vous conseille d’approfondir cet article en recherchant des informations complémentaires dans la documentation officielle [1]. Cette documentation est très complète et est en anglais, mais cela ne doit pas vous arrêter !

    1. Pour commencer

    1.1. Principe de base : les handles

    Je vais faire un rappel sur une notion récurrente en C : les handles. La traduction de ce terme en anglais est « poignée ». Les handles sont utilisés énormément en C, et vous devez d’ailleurs en connaître certains aspects : les files descriptors.

    Un handle porte bien son nom: il vous servira à « transporter » ou « utiliser » quelque chose. Et ce quelque chose, ce peut être n’importe quelle structure de données. J’entends ici le mot «structure» au sens large, et non pas au sens des structures en C définies par « struct ». En réalité, la conception des handles est liée à Unix, système sur lequel tout est fichier.

    Pour les fichiers le type d'un handle, ou d'unfile descriptor, est un simple int. Vous connaissez probablement leur utilisation avec int fd; . Mais pour la plupart des autres structures de données, c’est un autre type, spécifique à la structure (FILE, pour les fichiers, par exemple) . Vous pouvez vous imaginer les handles comme des sortes de pointeurs vers des structures de données. Mais ne confondez pas les handles avec des vrais pointeurs...

    Pour ouvrir la structure de donnée en question, on déclare le handle et on l’initialise. C’est le rôle, par exemple, du int fd = open(…);» pour les fichiers. Quand on a fini de l’utiliser, on doit le fermer avec la fonction close(fd); .

    Quel est le lien avec le registre? En fait, les clés du registre se manipulent avec des handles. Le type de ce handle est "HKEY" . En déclarant un handle vers une clé de registre, on ouvre cette clé. On peut alors modifier ses valeurs. Quand on a fini, on la ferme. C’est aussi simple que cela.

    1.2. Vocabulaire du registre

    Afin d’éviter la confusion, il est préférable de rappeler la définition de certains termes concernant le registre.

    Dans l’éditeur du registre (regedit) , tout ce que vous voyez à gauche, ce sont des clés, ou «keys». A droite, ce sont des valeurs, ou «values». Ces valeurs peuvent être de certains types, comme REG_SZ, DWORD, binaire, chaîne, etc. Enfin, les valeurs contiennent des données ( «data»).

    Nous verrons ensuite le concept de sous-clé («sub-keys»). En fait, vous pouvez considérer une sous-clé comme une clé qui se situe dans l’arborescence d’une autre.

    Par exemple, si l’on compare avec les fichiers, on peut assimiler une clé à un répertoire. On peut donc assimiler C:\Windows à une clé, C:\Windows\system32 à une sous-clé de la précédente, systray.exe comme une valeur et le contenu de systray.exe comme les données de cette valeur. Bien sûr, ce n’est qu’une représentation.

    2. Ouverture d’une clé

    Une fois ces rappels en tête, nous allons aborder la programmation proprement dite. J’en profite pour le dire ici, mais pour la gestion du registre en C, il vous faudra inclure «windows.h» au début de votre source.

    Pour ouvrir une clé, nous allons utiliser la fonction RegOpenKeyEx(). Sa syntaxe (référez-vous à MSDN [1]) est la suivante:

    RegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);

    Pour fermer une clé, on utilise RegCloseKey()et non pas close() :

    LONG RegCloseKey (HKEY hKey);

    La fonction RegOpenKeyEx, comme beaucoup d’autres, retourne un code d’erreur. Ce
    code dépend de l’exécution de la fonction et de son succès. Pour vérifier si la fonction a réussi, on compare le code d’erreur qu’elle renvoie et la valeur de la constante «ERROR_SUCCESS». Si les deux sont égaux, la fonction a réussi, on peut manipuler la clé par le biais du handle.

    Pour ce qui est des arguments de la fonction RegOpenKeyEx, MSDN les décrit en détail. Mais attention aux risques de confusion ; voici leur description.

    1) Le premier argument, le handle hKey, n’est PAS celui dans lequel nous allons stocker le handle vers la clé ouverte ! C’est un paramètre d’entrée, et non de sortie, comme l’indique «[in]» dans MSDN. Il correspond en fait au nom de la clé principale, ici ce sera HKEY_LOCAL_MACHINE.

    2) Le deuxième, lpSubKey, est un pointeur vers une chaîne ASCIZ (terminée par un zéro) et qui désigne la sous-clé à ouvrir.

    3) ulOptions doit être à zéro, c’est une variable réservée (c’est ce qu’indique encore une fois MSDN).

    4) samDesired désigne une constante qui définit les droits d’ouverture. C’est un peu comme les flags d’ouverture d’un fichier (O_WRONLY, etc.) . Ici, nous utiliserons KEY_ALL_ACCESS pour l’ouvrir avec tous les droits. Notez que les droits sont définis la page [2].

    5) Enfin, pHkey désigne un pointeur vers le handle de sortie ( «[out]» ). C’est celui la qui nous permettra de manipuler la clé!

    Le seul argument de la fonction RegCloseKey est le handle qui correspond à la clé ouverte. Ici, vous aurez compris que ce sera hKey. C’est aussi le 5ème argument de RegOpenKeyEx.

    Concrètement, voilà comment cela se passe:

    Code:
    #include <windows.h>
    int main()
    { // Déclaration du handle
      HKEY hKey;
      //On ouvre la clé HKLM\Software\Microsoft\Windows\CurrentVersion\Run
      if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Run", 
          0,KEY_ALL_ACCESS,&hKey ) == ERROR_SUCCESS )
      {
        printf("Ouverture reussie !");
        /* 
        Si l'ouverture a réussi, on peut manipuler la clé, mais nous verrons cela plus tard.
        Pour le moment, le but est seulement de voir l'ouverture et la fermeture, 
        nous allons donc fermer la clé. 
        */
        RegCloseKey( hKey ); }
      getch(); //Pour éviter que le programme ne quitte sans qu’on ait lu ce qui se passe.
    }
    Examinons en détail le code. Il permet d’ouvrir la clé qui contient tous les programmes qui démarrent au lancement de Windows (du moins par le registre).

    Nous commençons par déclarer le handle hKey. Puis nous effectuons un appel à RegOpenKeyEx pour ouvrir la clé HKEY_LOCAL_MACHINE et la sous-clé Software\Microsoft\Windows\CurrentVersion\Run. On ouvre cette clé avec tous les droits (KEY_ALL_ACCESS) et nous initialisons hKey. Vous pouvez noter que la plupart des arguments de sortie d’une fonction sont des pointeurs, car ils permettent de modifier l’argument; ici on a bien mis &hKey et non hKey. Pour vérifier que l’ouverture a fonctionné, nous utilisons un if() sur la valeur de retour de la fonction . Enfin, si la clé a bien été ouverte, nous la refermons. Je précise qu’il est inutile de fermer le handle si son initialisation a échoué, car vous risquez de vous retrouver avec une belle erreur.

    3. Modification d’une valeur

    Vous avez compris le principe, on accélère... La modification d’une valeur du registre suppose que l’on a au préalable ouvert la clé dans laquelle elle se trouve (par le biais de RegOpenKeyEx) . Pour modifier une valeur, on utilise la fonction RegSetValueEx():

    LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName,
    DWORD Reserved, DWORD dwType,
    const BYTE* lpData, DWORD cbData);

    1) hKey désigne le handle d’entrée, donc le handle que nous avons défini au préalable avec RegOpenKeyEx(). Attention, la clé doit avoir été ouverte avec des droits en écriture !

    2) lpValueName est un pointeur vers une chaîne ASCIZ qui est le nom de la nouvelle valeur que nous voulons créer.

    3) Reserved doit être à zéro.

    4) dwType est une constante désignant le type de la valeur à créer. Ici, ce sera REG_SZ. Consultez la liste de tous les types de valeurs [3] , elle vous sera utile.

    5) lpData est un pointeur vers un buffer contenant les données que l’on va insérer dans la valeur. On prendra ici une chaîne de caractères.

    6) cbData est la taille du buffer précédent. Nous la fixerons à 32.

    Voici un exemple de code qui ajoute une valeur au registre afin de faire démarrer un programme au démarrage de Windows:

    Code:
    #include <windows.h>
    int main()
    { // Déclaration du handle
      HKEY hKey;
      //On ouvre la clé HKLMSoftwareMicrosoftWindowsCurrentVersionRun
      if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\Run",
      0,KEY_ALL_ACCESS,&hKey ) == ERROR_SUCCESS )
      { // Si l'ouverture a réussi, on cree la nouvelle valeur
        if( RegSetValueEx(hKey,"Nouvelle clé",0,REG_SZ,"C:\mon_prog.exe",32) == ERROR_SUCCESS )
        //C'est gagné, on ferme la clé ouverte au départ
        RegCloseKey( hKey ); } }
    Je pense que le code est suffisamment bien commenté pour que vous le compreniez en intégralité. Pour vérifier qu’il a marché, ouvrez l’éditeur du registrer et allez à la clé en question, vous constaterez l’apparition d’une nouvelle valeur «Nouvelle valeur» qui contient «C:\mon_prog.exe» .

    The end…

    Nous arrivons à la fin de cet article. Nous avons vu comment ouvrir une clé et comment en créer une nouvelle. Il existe, comme je l’ai dit, une multitude de fonctions pour faire des tas de choses, comme par exemple lire le registre. RegQuerryValueEx() permet d’obtenir le type et les données d’une certaine valeur, RegEnumKeyEx() liste toutes les sous-clés d’une clé donnée… Et enfin une fonction qui me semble assez intéressante: RegConnectRegistry() qui permet de se connecter au registre d’un autre PC du réseau en spécifiant dans l’ordre son nom (du type «\\ordinateur» ) , la clé à ouvrir et le handle de sortie. Inutile de préciser que cette fonction ne marchera que si vous avez les droits suffisants sur la machine cible.

    Voilà, je pense avoir fait le tour. Je ne pense pas nécessaire la rédaction d’un article traitant de toutes les fonctions du registre, étant donné la présence d’une documentation détaillée à ce sujet (ce qui est relativement rare chez Microsoft).

    Bon coding !

    cred:trance
    sigpic

    Cyprium Download Link

    Plus j'étudie plus j'me rends compte que je n'sais rien.

    †|

  • #2
    Suberbe tuto !
    J'invite les gens qui souhaite récuperer des infos dans le registre à lire cet article (en anglais) :
    http://www.forensicfocus.com/Content/pid=73/
    Vous y trouverez les principales clés qui sont à regarder

    Commentaire

    Chargement...
    X