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 :

Connaitre le processus qui appelle une fonction API [FAQ]


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut Connaitre le processus qui appelle une fonction API
    Bonjour à tous,

    Me revoila avec mon monitoring de la base de registre.

    Rappel des fait : j'ai réussi a trouver la solution pour Hooker n'importe quelle fonction API en la surchargeant. voir ici http://www.developpez.net/forums/sho...d.php?t=144628


    Pour mon projet j'intercepte pour le moment l'appel de la fonction RegOpenKeyEx.


    Bon maintenant il me faut connaitre le processus qui appelle cette fonction. Avez vous une idée? Il me semble dans un passé lointain que j'ai entendu parler environnement de processus ou de fonctions pouvant explorer l'environnement mémoire d'un processus.


    Si vous avez une piste une idée. En fait il me faudrait une fonction qui a placer dans l'API surchargé pour savoir qui vient de faire l'appel. (voir ci dessous)


    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
    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;
     
         // Ici fonction "Quel Processus Appelle"    
     
        Str.Add('-----------------');
        Str.Add(DateTimeToStr(Now) + ' : RegOpenKey called');
        Str.Add(RootKey + lpSubKey);
        Str.Add('-----------------');
        Str.SaveToFile('c:\regkey.txt');
        Str.Free;
    end;

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Voilà, ca devrait faire ton affaire...
    cette fonction retourne le path complet du processus actuelle...

    je sais pas si ca va fonctionner dans ton contexte particulier...

    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
    38
    39
    40
    41
    42
    43
    44
    45
     
    type
      TModuleArray = array[0..1] of HMODULE;
      PHModule = ^TModuleArray;
    function GetModuleFileNameEx(hProcess : THandle; hModule : THandle;
                                 lpFileName : pchar;
                                 nSize : DWORD): DWORD; stdcall;  
    function EnumProcessModules(hProcess : THandle; Modules:PHModule;
                                cb : DWORD; VAR cbNeeded : DWORD): BOOL; stdcall;
     
    implementation
    {$R *.DFM}
     
    //*** External Function from PSAPI.DLL ****
    function GetModuleFileNameEx; external 'psapi.dll' index 13;
    //*** External Function from PSAPI.DLL ****
    function EnumProcessModules; external 'psapi.dll' index 3;
     
    function GetProcessName():string;
    var
        hProcess:DWORD;
        FileNamePath: array[0..512] of Char;
        cbNeeded: DWORD;
        PID:DWORD;
        Modules  :TModuleArray;
        FileStr:string;
    begin
        GetProcessName:='?';
        cbNeeded:=1;
        PID:=GetCurrentProcessId;
        if PID<>0 then
        begin
            hProcess:=OpenProcess( PROCESS_QUERY_INFORMATION OR PROCESS_VM_READ,FALSE,PID);
            if hProcess <>0 then
            begin
                if (EnumProcessModules(hProcess, @Modules, cbNeeded*SizeOf(HMOdule), cbNeeded)) then
                begin
                    if GetModuleFileNameEx(hProcess,Modules[0],FileNamePath,sizeof(FileNamePath))<>0 then
                    begin
                        GetProcessName := StrPas(FileNamePath);
                    end;
                end;
            end;
        end;
    end;
    Je l'ai Testé ici avec Delphi 5 et W2k. Pour xp je sais pas....
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  3. #3
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Eric Boisvert
    je sais pas si ca va fonctionner dans ton contexte particulier...
    Il n'y a pas de handle commun au deux codes.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Il n'y a pas de handle commun au deux codes.
    Tu peux m'expliquer svp?

    si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PID:=GetCurrentProcessId;
    dans une fonction de callback... j'vais avoir quelle process ID?
    celui de mon programme ou selui du processe qui appele la fonction?

    moi j'en sais rien....
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    à moi! Avec OpenProcess... il faut faire un CloseHandle!!!
    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
    function GetProcessName():string;
    var
        hProcess:DWORD;
        FileNamePath: array[0..512] of Char;
        cbNeeded: DWORD;
        PID:DWORD;
        Modules  :TModuleArray;
    begin
        GetProcessName:='?';
        cbNeeded:=1;
        PID:=GetCurrentProcessId;
        if PID<>0 then
        begin
            hProcess:=OpenProcess( PROCESS_QUERY_INFORMATION OR PROCESS_VM_READ,FALSE,PID);
            if hProcess <>0 then
            begin
                try
                    if (EnumProcessModules(hProcess, @Modules, cbNeeded*SizeOf(HMOdule), cbNeeded)) then
                    begin
                        if GetModuleFileNameEx(hProcess,Modules[0],FileNamePath,sizeof(FileNamePath))<>0 then
                        begin
                            GetProcessName := StrPas(FileNamePath);
                        end;
                    end;
                finally
                   CloseHandle(hProcess);
               end;
            end;
        end;
    end;
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse je teste et je vous tien au courant

  7. #7
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Eric Boisvert
    Tu peux m'expliquer svp?
    Le premier code ne dispose pas de Handle de process à corréler avec le second code.
    Citation Envoyé par Eric Boisvert
    si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PID:=GetCurrentProcessId;
    dans une fonction de callback... j'vais avoir quelle process ID?
    Trés bonne question mais je suis au même point que toi concernant la réponse. Mais de poser cette question c'est déjà une avancée.
    RazielReaver as-tu posté sur le forum de Matthias ?

    [edit]
    dixit MSDN
    GetCurrentProcessId

    Retrieves the process identifier of the calling process.

    DWORD WINAPI GetCurrentProcessId(void);

    Parameters
    This function has no parameters.

    Return Values
    The return value is the process identifier of the calling process.

    Remarks
    Until the process terminates, the process identifier uniquely identifies the process throughout the system.

  8. #8
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Bien cela marche impec GetCurrentProcessId renvoi bien le PID du porcess appelant la fonction RegOpenKeyNext juste une modification pas besoin de enumprocess voila le code que j'utilise :

    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
    function GetProcessName(PID:DWORD):string;
     var
        Handle: THandle;
      begin
        Result := '';
        Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
        if Handle <> 0 then
          try
            SetLength(Result, MAX_PATH);
            if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
                SetLength(Result, StrLen(PChar(Result)))
              else
                Result := '';
          finally
            CloseHandle(Handle);
          end;
      end;
    Je passe juste le PID à la fonction et voili

    POur ce que cela interesse le PID est envoyé par ma fonction surchargé via un message windows.

    voila le code complet de ma dll (encore en phase de test)

    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
    38
    39
    40
    library HookRegOpenKey;
    uses dialogs,classes,Sysutils, Windows, madRemote, madCodeHook, madStrings,Messages,registry;
    var RegOpenKeyExNext : function (HandleKey: Dword; lpSubKey: PChar; ulOptions: DWORD; samDesired: DWORD; var phkResult: Dword): Longint; stdcall;
    NumMessage : UINT;// num de notre message
    Type
    TDataInfo =Packed record  //packed pour "compressé"
      StrKey:String[255];
      StrDate:String[255];
      HPID : DWORD;
    end;
    function RegOpenKeyExCallback(HandleKey: Dword; lpSubKey: PChar; ulOptions: DWORD; samDesired: DWORD; var phkResult: Dword) : Longint; stdcall;
    Var
    RootKey : string;
    h:THandle;
    DataSent:TDataInfo;
    CopyDataStruct:TCopyDataStruct;
     begin
        result := RegOpenKeyExNext(HandleKey, lpSubKey, ulOptions, samDesired, phkResult);
        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;
        DataSent.HPID:=GetCurrentProcessId;
        DataSent.StrDate:=DateTimeToStr(Now) + ' : RegOpenKey called';
        DataSent.StrKey:=RootKey + lpSubKey;
        CopyDataStruct.cbData:=SizeOf(DataSent);
        //adresse de nos données à envoyer :
        CopyDataStruct.lpData:=@DataSent;
        h:=FindWindow(nil,'Fenêtre réceptrice de messages');
        //envoie de l'adresse (le @) du TCopuDataStruct +
        //LPARAM est du type longInt d'où le transtypage LongInt()
        SendMessage(h, WM_COPYDATA,0,LongInt(@CopyDataStruct));
    end;
    begin
      NumMessage:=RegisterWindowMessage('Message perso de application');
      HookAPI('advapi32.dll', 'RegOpenKeyExA', @RegOpenKeyExCallback, @RegOpenKeyExNext);
    end.
    ET voila le code de mon projet qui récupère le HOOk de RegOpenKeyNext

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    unit InjectUnit;
    interface
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, madCodeHook,
      StdCtrls,PsAPI, TlHelp32,Registry;
    type
      TForm1 = class(TForm)
        ButtonHook: TButton;
        ButtonUnHook: TButton;
        Memo1: TMemo;
        procedure ButtonHookClick(Sender: TObject);
        procedure ButtonUnHookClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        NumMessage : UINT;// num de notre message
        { Déclarations privées }
      public
        procedure OnWmCopyData(var msg:TMessage); message WM_COPYDATA;
        { Déclarations publiques }
      end;
    type
      TModuleArray = array[0..1] of HMODULE;
      PHModule = ^TModuleArray;
    var
      Form1: TForm1;
    implementation
    {$R *.DFM}
    Type
    //TPDataEnvoyes est un type pointeur (adresse) sur un TDataEnvoyes :
    TPDataSent=^TDataSent;
    TDataSent =Packed record
      StrKey:String[255];
      StrDate:String[255];
      HPID : DWORD;
    end;
    function GetProcessName(PID:DWORD):string;
     var
        Handle: THandle;
      begin
        Result := '';
        Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
        if Handle <> 0 then
          try
            SetLength(Result, MAX_PATH);
            if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
                SetLength(Result, StrLen(PChar(Result)))
              else
                Result := '';
          finally
            CloseHandle(Handle);
          end;
      end;
    procedure TForm1.OnWmCopyData(var msg: TMessage);
    // procedure qui sera déclenchée lorsqu'un message WM_COPYDATA arrivera
    type
      TPCopyDataStruct=^TCopyDataStruct;
      TPDataSent=^TDataSent;
    Var
      DataSent:TDataSent;
      PDataSent:TPDataSent;
      PCopyDataStruct:TPCopyDataStruct;
    begin
      PCopyDataStruct:=TPCopyDataStruct(msg.LParam);
      //PCopyDataStruct^ signifie "ce qui est pointé par le PCopyDataStruct"
      PDataSent:=PCopyDataStruct^.lpData;
      DataSent:=PDataSent^;
      Memo1.Lines.Add(DataSent.StrDate + ' Process : ' + GetProcessName(DataSent.HPID));
      Memo1.Lines.Add(DataSent.StrKey);
    end;
     
    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;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      NumMessage:=RegisterWindowMessage('Message perso de application');
      Form1.Caption:='Fenêtre réceptrice de messages';
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'HookRegOpenKey.dll');
    end;
    end.

  9. #9
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Bravo à Eric Boisvert, de mon coté j'étais partie dans une mauvaise direction avec mes histoires de handle...

    On va ajouter ce code à la FAQ.

  10. #10
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Ok

    De toute je ferai un totu complet sur ce systeme de hook avec les unités de Mathias. Quand je l'aurai fini tu me diras ou le poster.

Discussions similaires

  1. processus qui appel une fonction
    Par gastoncs dans le forum C
    Réponses: 4
    Dernier message: 03/05/2012, 11h06
  2. Connaitre l'object qui apelle une fonction
    Par Nico128 dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 23/10/2008, 23h08
  3. Lien <a href .. qui appelle une fonction php
    Par CristinaB dans le forum Langage
    Réponses: 1
    Dernier message: 30/05/2008, 16h03
  4. [DOM] connaitre l'objet DOM appelant une fonction javascript
    Par HPmeteo dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 02/09/2007, 18h03
  5. Récupérer le nom du fichier qui appelle une fonction
    Par DeezerD dans le forum Langage
    Réponses: 2
    Dernier message: 24/03/2007, 14h37

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