IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Hook TerminateProcess fichier de log


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 38
    Points : 15
    Points
    15
    Par défaut Hook TerminateProcess fichier de log
    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 :
    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.
    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
    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.
    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;
    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 !

    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

  2. #2
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Citation Envoyé par DelphiCode Voir le message
    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é.
    Le problème c'est qu'il n'y a pas que TerminateProcess qui mette fin à un processus sous Windows...
    Le process peut se terminer tout seul, en particulier en cas de crash...

    Il suffit que le point d'entré du dernier thread rende la main (par exemple, suite à une exception non gérée) pour que le process se termine.

    A ta place, je chercherais plutôt sur deux autres pistes :
    - Hooker toutes les exceptions et les logguer (mêmes celles qui sont trappées). Regarde du côté de JCLDebug dans la JCL.
    - Configurer un déboggueur Just-In-Time : Autrement dit, tu configures un processus dans la base de registre qui sera lancer automatiquement en cas de crash d'un process (DrWatson est un exemple, Delphi a le sien, VS aussi). Fait une recherche sur AeDebug dans Google.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Bonsoir le forum,

    Merci Franck pour ton aide.

    J'avais déjà une solution permettant de tracer en fonctionnement normal les exceptions dans un fichier de log mais j'ai suivi tes conseils et mis en place avec succès la solution du JCLDebug (un bon point) !

    En revanche, j'ai réussi à installer le Dr Watson mais il ne se déclenche que sur certaines erreurs sérieuses ! Je vais prendre un exemple illustrant mes propos.

    J'ai conçu un logiciel tout simple avec une fiche et un bouton sur cette fiche qui génère une exception. Cela m'a permis premièrement de tester le JCLDebug ! En revanche lorsque ce petit logiciel est lancé et que j'essaye de le tuer volontairement en réalisant un Ctrl + Alt + Suppr et clic droit > Terminer ce processus il se ferme sans être intercepter par Dr Watson ou autre et justement j'aimerais bien dans ce cas de figure pouvoir enregistrer dans un fichier de log le processus responsable de son extinction (ici pour l'exemple taskmanager je suppose ?).

    Aujourd'hui j'ai réalisé d'autres tests dans ce sens avec MagicApiHook mais sans succès.

    Peut-être aurais-tu une autre piste ?

    Merci d'avance,

    DelhiCode

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    En revanche, j'ai réussi à installer le Dr Watson mais il ne se déclenche que sur certaines erreurs sérieuses !
    Il se déclenche en cas d'exceptions non gérées par l'application. Il ne se déclenchera pas si l'appli est tuée manuellement, ou si elle se ferme d'elle même.

    Cependant quel est ton but exacte ?
    Avoir un log pour justifier les pertes de données
    ou comprendre pourquoi l'appli crashe et disparait ?

    Il n'y a pas 50 000 process qui vont venir tuer ton appli spontanément. Mis à par le gestionnaire des tâches, il faut que l'appli soit écrite spécifiquement pour aller tuer la tienne...

    Est-ce que tu as commencé par regarder le journal d'événement Windows ?

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 38
    Points : 15
    Points
    15
    Par défaut
    Les deux Franck !

    Le logiciel est installé chez un client et je ne sais pas si le logiciel en question est volontairement tué par un opérateur qui se garde bien de le dire ou si c'est réellement un crash qu'il me faut régler et dont je n'ai pas encore réussi à trouver la cause.

    Merci pour la piste Franck car je n'ai pas pensé à regarder le journal d'évènement, je regarderais ça de plus près en début de semaine prochaine.

    J'ai oublié de préciser que le logiciel en question est gourmand en ressource mémoire et j'ai pensé que peut-être un administrateur réseau ai pris des mesures pour tuer ce genre de processus ?

    C'est pour cela que j'essayer absolument de pouvoir intercepter l'extinction pour essayer de déterminer qui est responsable et avoir des preuves à fournir.

    J'ai déjà mis en place grâce à tes conseils les améliorations en production chez le client et peut-être que cela suffira à trouver le problème mais en attendant si ce n'est pas le cas je souhaiterais quand même poursuivre la solution d'interception.

    Je te remercie une fois de plus pour ton aide.

    DelphiCode

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    En fouillant un peu sur le forum tu devrais trouver quelques exemples de code pour interdire de tuer un process avec le gestionnaire des tâches (ni par une autre appli).
    C'est une question de droits d'accès : Tu peux refuser aux autres applications le droit de te tuer ! (mais ça veut aussi dire que tu ne pourrais plus non plus tuer l'appli en cas de besoin).

Discussions similaires

  1. fichier de log
    Par Arkenstone dans le forum Autres Logiciels
    Réponses: 4
    Dernier message: 01/04/2005, 14h42
  2. [tomcat 5] [paramétrage] fichier de log System.out.println
    Par Aldo dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 22/02/2005, 14h41
  3. [Oracle 8i/Fichier de log] - fichier log pour analyse erreur
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 4
    Dernier message: 25/01/2005, 19h06
  4. [Tomcat] Fichier de logs
    Par yolepro dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 22/03/2004, 16h20
  5. Fichiers de Log
    Par Mouse dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 10/05/2003, 18h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo