Bonsoir le forum,
Je me casse les dents sur un sujet depuis deux jours, je me décide donc à faire appel à votre aide !
J'ai un exécutable qui se charge de dialoguer avec un automate pour récupérer des données mais qui pour une raison inconnue se crache et il arrive que certaines données soient perdues ! J'ai donc créée un nouveau logiciel qui permet de détecter sa disparition des processus et de le relancer mais cela ne règle pas mon problème de perte de données.
J'ai donc décidé d'essayer de détecter lorsque le logiciel se fait tué afin de créée un fichier de log avec le nom du processus qui l'a tué avant qu'il soit tué. Bien évidemment comme TerminateProcess intervient à bas niveau il n'est pas possible d'intervenir directement. J'ai continué mes recherches et j'ai découvert qu'il fallait hooker le dit processus pour injecter une dll qui pourra réaliser le fichier de log.
J'ai donc trouvé une source en Delphi sur le site suivant intitulé "MagicApiHook" qui contient un exemple de Hook de TerminateProcess et plus exactement "zwTerminateProcess" de l'Api "ntdll.dll" mais le problème c'est que l'exemple permet d'mpêcher un processus de se terminer comme un antivirus par exemple alors que moi je veux juste écrire un fichier de log avant qu'il se termine et non pas l'empêcher de se terminer.
Le code exemple (loader.exe) se comporte de la façon suivante :
- Injection de la dll pour tous les processus actifs
- test via ctrl alt suppr pour terminer le processus loader.exe (ne fonctionne pas c'est le but du code)
- fermeture de façon normale via la croix de la fichie principale de loader.exe
- Libération de la dll pour tous les processus
Voici des extraits du code utile pour illustrer les propos ci-dessus :
Code du logiciel de chargement :
Extraits de code de la dll :
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 program Loader; uses Windows, MagicApiHook; var Dllname:string='ProtectProcess.dll'; F: THandle; PID,Cnt: DWORD; begin if not IsWinNt then begin MessageBox(0,'Sorry...just for WinNT...','Error...',MB_ICONERROR); Exit; end; if not IsFileExist(DllName) then begin MessageBox(0,Pchar('File not found : '+DllName),'Error...',MB_ICONERROR); Exit; end; PID:=GetCurrentProcessID; F:=CreateFileA(Pchar(GetPath(Paramstr(0))+'PID.dat'),GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); if F=INVALID_HANDLE_VALUE then begin MessageBox(0,'Can not Create ProcessID file...','Error...',MB_ICONERROR); Exit; end; WriteFile(F,PID,SizeOf(PID),Cnt,nil); CloseHandle(F); DebugPrivilege(True); InjectAllProc(GetPath(ParamStr(0))+DllName); MessageBox(0,'TerminateProcess Hook Installed...'#13#10+ 'Now Try to Terminate Me !'#13#10#13#10+ 'Press OK to UnInstall Hook...', 'Success... Magic_h2001',MB_ICONINFORMATION); UnInjectAllProc(GetPath(ParamStr(0))+DllName); end.
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 procedure DLLEntryPoint(dwReason:DWORD); begin case dwReason of DLL_PROCESS_ATTACH: begin ApiHook('ntdll.dll','ZwTerminateProcess',nil,@HookZwTerminateProcess,@MainZwTerminateProcess); ApiHook('kernel32.dll','CreateProcessInternalW',nil,@HookCreateProcessInternalW,@MainCreateProcessInternalW); ApiHook('kernel32.dll','OpenProcess',nil,@HookOpenProcess,@MainOpenProcess); ApiHook('advapi32.dll','CreateProcessAsUserA',nil,@HookCreateProcessAsUserA,@MainCreateProcessAsUserA); ApiHook('advapi32.dll','CreateProcessAsUserW',nil,@HookCreateProcessAsUserW,@MainCreateProcessAsUserW); GetModuleFileName(GetModuleHandle(Pchar(DllName)),DllPath,SizeOf(DllPath)); PID:=$FFFFFFFF; F:=CreateFileA(Pchar(GetPath(DllPath)+'PID.dat'),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); if F<>INVALID_HANDLE_VALUE then begin ReadFile(F,PID,SizeOf(PID),Cnt,nil); CloseHandle(F); end; end; DLL_PROCESS_DETACH: begin ApiUnHook('ntdll.dll','ZwTerminateProcess',nil,@HookZwTerminateProcess,@MainZwTerminateProcess); ApiUnHook('kernel32.dll','CreateProcessInternalW',nil,@HookCreateProcessInternalW,@MainCreateProcessInternalW); ApiUnHook('kernel32.dll','OpenProcess',nil,@HookOpenProcess,@MainOpenProcess); ApiUnHook('advapi32.dll','CreateProcessAsUserA',nil,@HookCreateProcessAsUserA,@MainCreateProcessAsUserA); ApiUnHook('advapi32.dll','CreateProcessAsUserW',nil,@HookCreateProcessAsUserW,@MainCreateProcessAsUserW); end; end; end; (******************************************************************************) begin DllProc:=@DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end.Dans la dernière fonciton "HookzwTerminateProcess" j'ai essayé de mettre le code pour générer le fichier de log avant result := False mais cela ne fonctionne pas ! J'ai effectué d'autres tests pas plus concluants qui m'ont valus quelques écrans bleu dûs à la non libération de dll !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function HookZwTerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL; stdcall; begin if PHandleToPID(hProcess)=PID then begin Result:=False; SetLastError(ERROR_ACCESS_DENIED); end else Result:=MainZwTerminateProcess(hProcess,uExitCode); end;
Je me tourne donc vers vous pour savoir si quelqu'un aurait une piste pour m'aider.
Je vous remercie par avance de votre aide,
DelphiCode
Partager