Pour faciliter la recherche des utilisateurs du forum je copie colle une partie d'un post en rennomant le sujet.
Le poste original était : Surveiller la base de registre.
De fils en aiguille j'ai découvert un principe très interessant voià un résumé de cette recherche
Voila je vais donc essayer de vous faire une petit topo sur cette méthode. Ce topo ne sera pas complet je compte sur vos compétences pour me reprendre sur quelque points ou pour apporter des précisions à mon propos.
1) Point de départ :
Je cherchais donc comment faire un hook sur la base de registre.
a - première solution imcomplète : RegNotifyChangeKeyValue.
Cette solution est expliquée ici : http://delphi.about.com/od/kbwinshell/l/aa052003a.htm
Le gros défaut de cette solution est qu'elle ne renvoie pas la clé qui a subit une modification. Elle notifie seulement un changement.
b - deuxième solution envisagée : le principe qu'utilise regmon. Là j'ai été un peu perturbécar le procédé utilise des fonctions non documentées de xp et que tout cela me paraissait un peu trop pointu. Pour info je vous donne différent liens dont j'ai cru comprendre qu'ils traitaient plus ou moins du sujet.
http://www.eviloctal.com/forum/htm_d...603/20388.html
et le site de regmon
http://www.sysinternals.com/Utilities/Regmon.html (voir l'explication : "How Regmon Works")
Peut-être aussi un référence bibliogrpahique :
http://www.amazon.com/gp/product/020...lance&n=283155
c - La solution utilisant le principe de Mathias Rauen (je décrirai plus bas cette méthode)
En gros cette méthode permet de hooker n'importe quelle fonction API de windows. Pour le moment j'ai juste fait un hook sur RegOpenKey cela reste donc incomplet, mais le principe est vraiment très prometteur.
2) Description du principe de Mathias Rauen
Alors là je vais tenter une explication, mais je me reserve le droit d'être approximatif![]()
Les API windows sont donc chargées par le système et les programmes à partir des dll natives de windows. Par exemple on sait que TerminateProcess se trouve dans kernel32.dll. Quand un programme ou un utilisateur demande au systeme de terminer un process celui ci fait appel a cette fonction. Imaginons maintenant qu'il soit possible de surcharger cette fonction. C'est à dire d'executer un bout de code personnel au moment de son appel. On pourrait donc par exemple refuser qu'un processus donné soit terminé sans autorisation.
Ceci est possible grâce au procédé développé par Mathias Rauen. Ce principe permet donc d'injecter la fonction surchargée d'une fonction originale (API) en lieu et place de celle-ci dans le système (system wide). D'ailleurs si quelqu'un veut bien m'expliquer ce que recouvre exactement ce terme (system wide) utilisé pas Mathias je suis preneur.
L'ecriture de la fonction surchargée doit se faire dans une dl qui elle sera injecté dans le système.
Pour développé un projet permettant cette injection il faut télécharger la collection de composants ici : http://madshi.net/madCollection.exe. Le composant qui nous interesse plus particulièrement est nommé madCodeHook.
L'install registre une dcu "madCodeHook.dcu" et fournit une dll madCHook.dll nécessaire à l'injection.
Pour résumé :
on crée un dll contenant la fonction API surchargée. Cette dll est injectée dans le system à l'aide des fonctions contenues dans "madCodeHook.dcu" et de la dll "madCHook.dll". A mon avis c'est la dcu qui fait appel à "madCodeHook.dcu" .
3) Passons à la pratique
a - D'abord l'exemple de de l'auteur : http://help.madshi.net/HowToUseMadCodeHook.htm
Cet exemple nous montre comment hooker l'API TerminanteProcess en autorisant ou non l'arrêt d'un processus donné.
b - Maintenant mon exemple :
Je vais en suivant Mathias hooker la fonction RegOpenKey qui est dans advapi32.dll.
Ecriture de la dll surchargeant RegOpenKey :
Remarque importante : La fonction surchargée doit impérativement respecter les conventions d'écriture (paramètres et variables) de l'originale.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 library HookRegOpenKey; uses dialogs,classes,Sysutils, Windows, madRemote, madCodeHook, madStrings; // variable représentant l'api originale "function RegOpenKey(hKey: HKEY; lpSubKey: PChar; var phkResult: HKEY): Longint; stdcall;" var RegOpenKeyNext : function (HandleKey: Dword; lpSubKey: PChar; var phkResult: Dword): Longint; stdcall; // Fonction surchargée function RegOpenKeyCallback(HandleKey: Dword; lpSubKey: PChar; var phkResult: Dword) : Longint; stdcall; Var Str : TStringList; RootKey : string; begin // On renvoie la fonction originale pour que la demande soit bien prise en compte result := RegOpenKeyNext(HandleKey, lpSubKey,phkResult); // surcharge par mon code perso j'ouvre un fichier log ou seront enregistrer les infos Str:=TStringList.Create; If fileExists('c:\regkey.txt') Then Str.LoadFromFile('c:\regkey.txt'); Case HandleKey Of HKEY_CLASSES_ROOT : RootKey := 'HKEY_CLASSES_ROOT\'; HKEY_CURRENT_USER : RootKey := 'HKEY_CURRENT_USER\'; HKEY_LOCAL_MACHINE : RootKey := 'HKEY_LOCAL_MACHINE\'; HKEY_USERS : RootKey := 'HKEY_USERS\'; HKEY_CURRENT_CONFIG : RootKey := 'HKEY_CURRENT_CONFIG\'; End; Str.Add('-----------------'); Str.Add(DateTimeToStr(Now) + ' : RegOpenKey called'); Str.Add(RootKey + lpSubKey); Str.Add('-----------------'); Str.SaveToFile('c:\regkey.txt'); Str.Free; end; begin // HookAPI provient de madCodeHook.dcu et permet de subsituer la fonction surchargée à l'API originale. HookAPI('advapi32.dll', 'RegOpenKeyA', @RegOpenKeyCallback, @RegOpenKeyNext); end.
Maintenant l'ecriture du projet permettant l'injection :
Voila il suffit d'utiliser InjectLibrary pour Hooker et UninjectLibrary pour UnHooker.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 unit InjectUnit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, madCodeHook, StdCtrls; type TForm1 = class(TForm) ButtonHook: TButton; ButtonUnHook: TButton; procedure ButtonHookClick(Sender: TObject); procedure ButtonUnHookClick(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.ButtonHookClick(Sender: TObject); begin InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'HookRegOpenKey.dll'); end; procedure TForm1.ButtonUnHookClick(Sender: TObject); begin UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'HookRegOpenKey.dll'); end; end.
PS : scusez pour les fautes d'orthographe je fait des efforts mais c'est souvent en vain.
Quand j'aurai monté le projet global je vous le ferai parvenir. Car il me reste un autre point a résoudre : connaitre le processus qui vient d'accéder à la base de registre. Il faut aussi que je surcharge les appels aux fonctions d'écriture dans la base.
Raziel
Partager