1. #1
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut L'inverse de GetProcAddress

    Connaissant l'Adresse d'une Fonction dans une DLL, comment récupérer son nom (ou son ordinal) et le nom de la DLL à laquelle elle appartient?

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 897
    Points : 7 831
    Points
    7 831

    Par défaut

    Bonjour,
    On peut trouver les ordinaux et noms des fonctions dans la table d'export de la dll (voir ici). Dans la table d'import du programme (voir même lien), on a les noms des dll et adresses des fonctions.
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2007
    Messages
    2 361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2007
    Messages : 2 361
    Points : 2 165
    Points
    2 165

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut

    Merci pour vos réponses.
    Pourrais-je avoir un exemple (j’utilise Delphi7) de l’utilisation de la fonction SymFromAddr dans Dbghelp.dll.
    J'ai toujours une erreur :ERROR_ACCESS_DENIED.

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 897
    Points : 7 831
    Points
    7 831

    Par défaut

    Bonjour,
    As-tu encadré ton appel à SymFromAddr par un SymInitialize et un SymCleanup ?
    Si l'erreur persiste malgré l'initialisation, c'est pê un problème de droits, à explorer.
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut

    Bonjour,
    Je n'avais pas encadré avec un SymInitialize et un SymCleanup.
    Maintenant ça marche un peu mieux.
    Mais SymFromAddr me renvoie l'erreur 126:ERROR_MOD_NOT_FOUND

    Dans SymInitialize que je mette le chemin de l'application ou de la DLL ou rien c'est pareil.
    Pourtant la dll est bien là, et la fonction existe , j' extrait son adresse avec GetProcAdress.
    J'ai encore du oublié quelque chose...

  7. #7
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 897
    Points : 7 831
    Points
    7 831

    Par défaut

    moi aussi ! avec le code suivant, j'obtiens une erreur 87 : paramètre incorrect...
    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
    const
      DbgHelpDll = 'C:\windows\system32\dbghelp.dll';
      SYMFLAG_FUNCTION = $00000800; // 2048
     
    type
      TSYMBOL_INFO = packed record
        SizeOfStruct: DWORD; // 10 DWORD 5 uint64 256 AnsiChar => 336
        TypeIndex: DWORD;
        Reserved_1, Reserved_2: uint64;
        Index: DWORD;
        Size: DWORD;
        ModBase: uint64;
        Flags: DWORD; // SYMFLAG_FUNCTION
        Value: uint64;
        Address: uint64;
        Registre: DWORD;
        Scope: DWORD;
        Tag: DWORD;
        NameLen: DWORD;
        MaxNameLen: DWORD; // 256
        Name: array[0..255] of AnsiChar;
      end;
     
    function SymInitialize(aHandle: HMODULE; aUserSearchPath: PAnsiChar;
                            aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll;
     
    function SymFromAddr(aHandle: HMODULE; aAdress: uint64;
                          var aDisplacement: uint64; var aSymbolInfo: TSYMBOL_INFO): Boolean; stdcall; external DbgHelpDll;
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Hmod: HMODULE;
      P: Pointer;
      i, Deplacement: uint64;
      SymbolInfo: TSYMBOL_INFO;
      Result: AnsiString;
    begin
      Hmod:=LoadLibrary(DbgHelpDll);
      if Hmod=0 then
      begin
        ShowMessage('librairie pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      P:=nil;
      P:=GetProcAddress(Hmod, 'SymFromName'); // pour charger la 1ère fonction
      if not Assigned(P) then
      begin
        ShowMessage('fonction pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      if not SymInitialize(Hmod, nil, False) then
      begin
        ShowMessage('symboles pas initialisés');
        FreeLibrary(Hmod);
        Exit;
      end;
      i:=SizeOf(TSymbol_Info);
      FillChar(SymbolInfo, i, 0);
      SymbolInfo.SizeOfStruct:=i; // 336 si packed   
      SymbolInfo.MaxNameLen:=256;
      Deplacement:=0;
      if SymFromAddr(Hmod, UInt64(P), Deplacement, SymbolInfo) then
      begin
        if SymbolInfo.Flags and SYMFLAG_FUNCTION <> SYMFLAG_FUNCTION then
        begin
          ShowMessage('le symbole retourné n''est pas une fonction');
          FreeLibrary(Hmod);
          Exit;
        end;
        SetLength(Result, SymbolInfo.NameLen);
        for i:=1 to SymbolInfo.NameLen
        do Result[i]:=SymbolInfo.Name[i];
        ShowMessage(Result);
      end
      else begin
        i:=GetLastError;
        ShowMessage('infos pas retournées ; erreur '+IntToStr(i));
      end;
      if not SymCleanup(Hmod) then
        ShowMessage('symboles pas nettoyés');
      FreeLibrary(Hmod);
    end;
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut

    Comme ceci ça marche

    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
    90
    91
    92
    93
    94
    95
    96
     const
      DbgHelpDll = 'C:\windows\system32\dbghelp.dll';
      SYMFLAG_FUNCTION = $00000800 or $200; // fonction ou export table
     
    type
      TSYMBOL_INFO =  record
        SizeOfStruct: DWORD; // 10 DWORD 5 uint64 256 AnsiChar => 336
        TypeIndex: DWORD;
        Reserved_1, Reserved_2: uint64;
        Index: DWORD;
        Size: DWORD;
        ModBase: int64;
        Flags: DWORD; // SYMFLAG_FUNCTION
        Value: Int64;
        Address: int64;
        Registre: DWORD;
        Scope: DWORD;
        Tag: DWORD;
        NameLen: DWORD;
        MaxNameLen: DWORD; //256
        Name: array[0..255] of AnsiChar;
      end;
     
    function SymInitialize(aHandle: HMODULE; aUserSearchPath: PAnsiChar;
                            aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll;
     
    function SymFromAddr(aHandle: HMODULE; aAdress:int64;
                          aDisplacement:DWORD;
                          aSymbolInfo: pointer): Boolean; stdcall; external DbgHelpDll;
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
     var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Hmod,Hprocessus: HMODULE;
      P: Pointer;
      i:cardinal;
      Deplacement:dword;
      SymbolInfo: TSYMBOL_INFO;
      Result: string;
    begin
      Hprocessus:=getcurrentprocess;
      Hmod:=LoadLibrary('kernel32.dll'); //une dll quelconque
      if Hmod=0 then
      begin
        ShowMessage('librairie pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      P:=nil;
      P:=GetProcAddress(Hmod, 'AddAtomA');//une fonction quelconque,l'adresse peut être supérieur jusqu'à la prochaine fonction
     
      if not Assigned(P) then
      begin
        ShowMessage('fonction pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      if not SymInitialize(Hprocessus, nil, true) then
      begin
        ShowMessage('symboles pas initialisés');
        FreeLibrary(Hmod);
        Exit;
      end;
      i:=SizeOf(TSymbol_Info);
      zeromemory(@SymbolInfo,i);
      SymbolInfo.SizeOfStruct:=i; // 336 si packed
      SymbolInfo.MaxNameLen:=255;
      Deplacement:=0;
      if SymFromAddr(Hprocessus, int64(p), Deplacement, @SymbolInfo) then  // mettre le handle du processus
      begin
        if (SymbolInfo.Flags and SYMFLAG_FUNCTION) = 0 then
        begin
          ShowMessage('le symbole retourné n''est pas une fonction');
          FreeLibrary(Hmod);
          Exit;
        end;
        SetLength(Result, SymbolInfo.NameLen);
        for i:=0 to SymbolInfo.NameLen
        do Result:=SymbolInfo.Name;
        ShowMessage(Result);
      end
      else begin
        i:=GetLastError;
        ShowMessage('infos pas retournées ; erreur '+IntToStr(i));
      end;
      if not SymCleanup(Hprocessus) then
        ShowMessage('symboles pas nettoyés');
      FreeLibrary(Hmod);
    end;

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 897
    Points : 7 831
    Points
    7 831

    Par défaut

    Mince ! Je pensais qu'en passant le paramètre record en var on passait son adresse, soit l'équivalent d'un pointeur en C... Mauvaise traduction...
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  10. #10
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : mai 2002
    Messages : 2 423
    Points : 3 805
    Points
    3 805

    Par défaut

    c'est surtout que tu ne prenez pas le bon handle de process aussi
    tu passe le handle du loadlibrary alors qu'il faut le handle du processus courant (application)
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  11. #11
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2007
    Messages
    2 361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2007
    Messages : 2 361
    Points : 2 165
    Points
    2 165

    Par défaut

    Ce serait bien d'ajouter le résultat final à FAQ.

    Sergio ? ton avis ?

  12. #12
    Membre averti Avatar de Cirec
    Profil pro
    Inscrit en
    octobre 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2010
    Messages : 183
    Points : 389
    Points
    389

    Par défaut

    Bonjour,

    comme le code m’intéresse aussi, je l'ai testé (le dernier posté par "angel_f") et j'ai toujours "infos pas retournées ; erreur 87" !!!
    une idée du problème ?
    testé sous D2009 & Win7

    Cordialement,
    @+

  13. #13
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2007
    Messages
    2 361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2007
    Messages : 2 361
    Points : 2 165
    Points
    2 165

    Par défaut

    là, j'ai pas trop le temps mais je ferai un essai ce soir

    Déjà, si le code a été testé correct sous Delphi 7, vu que tu utilises Delphi 2009 unicode, il y a peut-être à voir de ce côté là.

  14. #14
    Membre averti Avatar de Cirec
    Profil pro
    Inscrit en
    octobre 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2010
    Messages : 183
    Points : 389
    Points
    389

    Par défaut

    Citation Envoyé par Papy214 Voir le message
    là, j'ai pas trop le temps mais je ferai un essai ce soir

    Déjà, si le code a été testé correct sous Delphi 7, vu que tu utilises Delphi 2009 unicode, il y a peut-être à voir de ce côté là.
    j'y ai pensé à l'UNICODE mais ça ne change rien
    déjà de base les fonctions appelées sont en Ansi et le record aussi donc ça devrait passer mais non

    j'ai changé pour appeler les fonctions UNICODE "W" et modifié le record en conséquence ... toujours erreur 87

    du coup j'ai testé le code original tel quel avec D7 et j'ai le même problème ... erreur 87
    j'ai également testé en mode Administrateur au cas ou ... idem

    du coup je ne pense pas que ce soit lié à la version de Delphi (UNICODE ou non)

    Mais il y a peut être un truc qui m'échappe

    Cordialement,
    @+

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut

    Erreur localisée :
    Dans mon projet j’utilise la version 5.1 de dbghelp.dll.
    Sous win 7 c’est la version 6.1 qui entraîne une erreur.
    2 solutions :
    - Mettre la version 5.1 dans le projet, marche sous win7
    - Trouver la différence entre 5.1 et 6.1 que je ne connais pas

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    décembre 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : décembre 2016
    Messages : 6
    Points : 6
    Points
    6

    Par défaut

    Problème résolu :
    Pour Dbghelp.dll version 6.1
    Dans SYMBOL_INFO. SizeOfStruct mettre la valeur $58 ne pas tenir compte de la longueur du nom.

  17. #17
    Membre averti Avatar de Cirec
    Profil pro
    Inscrit en
    octobre 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2010
    Messages : 183
    Points : 389
    Points
    389

    Par défaut

    Citation Envoyé par angel_f Voir le message
    Problème résolu :
    Pour Dbghelp.dll version 6.1
    Dans SYMBOL_INFO. SizeOfStruct mettre la valeur $58 ne pas tenir compte de la longueur du nom.
    Effectivement ça fonctionne parfaitement
    Merci.

    Fixer ainsi arbitrairement la taille du record ne me plait pas trop.
    Pour donner une certaine cohérence au code (quand on essaye le lire) je propose de l'écrire comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      SymbolInfo.MaxNameLen := 256;
      SymbolInfo.SizeOfStruct := I - SymbolInfo.MaxNameLen; // 88
    ce qui me semble plus claire et surtout explique la taille de 88 ($58)

    EDIT:
    Après avoir testé la version UNICODE et
    dans un souci de compatibilité entre les deux je propose une dernière modification du code comme ceci:
    Il fonctionne aussi bien sous D7(ansi) que sous D2009 (UNICODE) sans changer une virgule
    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    unit Unit5;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm5 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    const
      DbgHelpDll   = 'C:\windows\system32\dbghelp.dll';
      SYMFLAG_FUNCTION = $00000800 or $200; // fonction ou export table
     
    type
      TSYMBOL_INFO = record
        SizeOfStruct: DWORD; // 10 DWORD 5 uint64 256 AnsiChar => 336
        TypeIndex: DWORD;
        Reserved_1, Reserved_2: uint64;
        Index: DWORD;
        Size: DWORD;
        ModBase: int64;
        Flags: DWORD; // SYMFLAG_FUNCTION
        Value: Int64;
        Address: int64;
        Registre: DWORD;
        Scope: DWORD;
        Tag: DWORD;
        NameLen: DWORD;
        MaxNameLen: DWORD; //256
        Name: array[0..255] of Char;   // AnsiChar
      end;
     
    function SymInitialize(aHandle: HMODULE; aUserSearchPath: PChar;
      aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymInitializeW'
    {$ELSE}
      name 'SymInitialize'
    {$ENDIF};
     
    function SymFromAddr(aHandle: HMODULE;
      aAdress: int64;
      aDisplacement: DWORD;
      aSymbolInfo: Pointer): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymFromAddrW'
    {$ELSE}
      name 'SymFromAddr'
    {$ENDIF};
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
    var
      Form5        : TForm5;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm5.Button1Click(Sender: TObject);
    var
      Hmod, Hprocessus: HMODULE;
      P            : Pointer;
      i            : cardinal;
      Deplacement  : dword;
      SymbolInfo   : TSYMBOL_INFO;
      Result       : string;
    begin
      Hprocessus := getcurrentprocess;
      Hmod := LoadLibrary('kernel32.dll'); //une dll quelconque
      if Hmod = 0 then
      begin
        ShowMessage('librairie pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      //P := nil;
      P := GetProcAddress(Hmod, 'AddAtomA');
        //une fonction quelconque,l'adresse peut être supérieur jusqu'à la prochaine fonction
     
      if not Assigned(P) then
      begin
        ShowMessage('fonction pas chargée');
        FreeLibrary(Hmod);
        Exit;
      end;
      if not SymInitialize(Hprocessus, nil, true) then
      begin
        ShowMessage('symboles pas initialisés');
        FreeLibrary(Hmod);
        Exit;
      end;
      i := SizeOf(TSymbol_Info);
      zeromemory(@SymbolInfo, i);
      SymbolInfo.MaxNameLen := 256;
      SymbolInfo.SizeOfStruct :=  I - Length(SymbolInfo.Name) * SizeOf(SymbolInfo.Name[0]); // 88
      Deplacement := 0;
      if SymFromAddr(Hprocessus, int64(p), Deplacement, @SymbolInfo) then
        // mettre le handle du processus
      begin
        if (SymbolInfo.Flags and SYMFLAG_FUNCTION) = 0 then
        begin
          ShowMessage('le symbole retourné n''est pas une fonction');
          FreeLibrary(Hmod);
          Exit;
        end;
        {SetLength(Result, SymbolInfo.NameLen);
        for i := 0 to SymbolInfo.NameLen do} Result := SymbolInfo.Name;
        ShowMessage(Result);
      end
      else begin
        i := GetLastError;
        ShowMessage('infos pas retournées ; erreur ' + IntToStr(i));
      end;
      if not SymCleanup(Hprocessus) then
        ShowMessage('symboles pas nettoyés');
      FreeLibrary(Hmod);
    end;
    end.
    je pense que cette fois c'est la dernière

    qu'en pensez-vous ?
    Cordialement,
    @+

  18. #18
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2007
    Messages
    2 361
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2007
    Messages : 2 361
    Points : 2 165
    Points
    2 165

    Par défaut

    qu'en pensez-vous ?
    Je testerai ce w-e, pas le temps aujourd'hui.

    Mais j'en pense qu'il faudrait juste extraire ça dans une unité séparée réutilisable et l'ajouter (je me répète, désolé) à la FAQ

  19. #19
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 897
    Points : 7 831
    Points
    7 831

    Par défaut

    Bonjour,
    Je voulais revisiter le code de Cirec sous forme d'une fonction autonome, mais je ne parviens pas à inclure les déclarations de fonctions externes dedans : le compilateur n'y reconnaît pas la directive external.

    Du coup, je propose ceci, qui n'est pas self-contained, que je n'ai testé qu'avec Berlin 10.1 sous Win7, et dans lequel j'ai ôté tout le code de gestion d'erreurs, surtout utile lors du débogage :
    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
    const
      DbgHelpDll = 'C:\windows\system32\dbghelp.dll';
     
    function SymInitialize(aHandle: HMODULE;
     aUserSearchPath: PChar;
     aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymInitializeW'
    {$ELSE}
      name 'SymInitialize'
    {$ENDIF};
     
    function SymFromAddr(aHandle: HMODULE;
     aAdress: uint64;
     var aDisplacement: Cardinal;
     aSymbolInfo: Pointer): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymFromAddrW'
    {$ELSE}
      name 'SymFromAddr'
    {$ENDIF};
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
    // retourne le nom d'une fonction d'une bibliothèque à partir de son adresse.
    function GetDllFunctionNameFromAddress(aAddress: Pointer): String;
    const
      SYMFLAG_FUNCTION = $00000800 or $00000200; // fonction ou export table
      MaxSymbolNameLen = 256;
     
    type
      TSYMBOL_INFO = record
        SizeOfStruct: Cardinal;
        TypeIndex: Cardinal;
        Reserved_1, Reserved_2: uint64;
        Index: Cardinal;
        Size: Cardinal;
        ModBase: uint64;
        Flags: Cardinal; // SYMFLAG_FUNCTION
        Value: uint64;
        Address: uint64;
        Registre: Cardinal;
        Scope: Cardinal;
        Tag: Cardinal;
        NameLen: Cardinal;
        MaxNameLen: Cardinal; // MaxSymbolNameLen (modifiable)
        Name: array[0..MaxSymbolNameLen-1] of Char; // pas à inclure dans TSYMBOL_INFO.SizeOfStruct
      end;
     
    var
      ProcessHandle: HMODULE;
      i, Deplacement: Cardinal;
      SymbolInfo: TSYMBOL_INFO;
     
    begin
      Result := EmptyStr;
      ProcessHandle := GetCurrentProcess;
      // initialisation de la table des symboles
      if not SymInitialize(ProcessHandle, nil, True) then Exit;
      // initialisation de la structure pour le retour des infos
      i := SizeOf(TSymbol_Info);
      ZeroMemory(@SymbolInfo, i);
      SymbolInfo.MaxNameLen := MaxSymbolNameLen;
      SymbolInfo.SizeOfStruct :=  i - Length(SymbolInfo.Name) * SizeOf(SymbolInfo.Name[0]);
      Deplacement := 0;
      // informations sur l'adresse demandée
      if SymFromAddr(ProcessHandle, int64(aAddress), Deplacement, @SymbolInfo) then
      begin
        if (SymbolInfo.Flags or SYMFLAG_FUNCTION) = SYMFLAG_FUNCTION  // filtre les fonctions
        then Result := SymbolInfo.Name;
      end;
      // libération de la table des symboles
      SymCleanup(ProcessHandle);
    end;
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  20. #20
    Membre averti Avatar de Cirec
    Profil pro
    Inscrit en
    octobre 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2010
    Messages : 183
    Points : 389
    Points
    389

    Par défaut

    Citation Envoyé par tourlourou Voir le message
    Bonjour,
    Je voulais revisiter le code de Cirec sous forme d'une fonction autonome, mais je ne parviens pas à inclure les déclarations de fonctions externes dedans : le compilateur n'y reconnaît pas la directive external.

    Du coup, je propose ceci, qui n'est pas self-contained, que je n'ai testé qu'avec Berlin 10.1 sous Win7, et dans lequel j'ai ôté tout le code de gestion d'erreurs, surtout utile lors du débogage :
    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
    const
      DbgHelpDll = 'C:\windows\system32\dbghelp.dll';
     
    function SymInitialize(aHandle: HMODULE;
     aUserSearchPath: PChar;
     aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymInitializeW'
    {$ELSE}
      name 'SymInitialize'
    {$ENDIF};
     
    function SymFromAddr(aHandle: HMODULE;
     aAdress: uint64;
     var aDisplacement: Cardinal;
     aSymbolInfo: Pointer): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymFromAddrW'
    {$ELSE}
      name 'SymFromAddr'
    {$ENDIF};
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
    // retourne le nom d'une fonction d'une bibliothèque à partir de son adresse.
    function GetDllFunctionNameFromAddress(aAddress: Pointer): String;
    const
      SYMFLAG_FUNCTION = $00000800 or $00000200; // fonction ou export table
      MaxSymbolNameLen = 256;
     
    type
      TSYMBOL_INFO = record
        SizeOfStruct: Cardinal;
        TypeIndex: Cardinal;
        Reserved_1, Reserved_2: uint64;
        Index: Cardinal;
        Size: Cardinal;
        ModBase: uint64;
        Flags: Cardinal; // SYMFLAG_FUNCTION
        Value: uint64;
        Address: uint64;
        Registre: Cardinal;
        Scope: Cardinal;
        Tag: Cardinal;
        NameLen: Cardinal;
        MaxNameLen: Cardinal; // MaxSymbolNameLen (modifiable)
        Name: array[0..MaxSymbolNameLen-1] of Char; // pas à inclure dans TSYMBOL_INFO.SizeOfStruct
      end;
     
    var
      ProcessHandle: HMODULE;
      i, Deplacement: Cardinal;
      SymbolInfo: TSYMBOL_INFO;
     
    begin
      Result := EmptyStr;
      ProcessHandle := GetCurrentProcess;
      // initialisation de la table des symboles
      if not SymInitialize(ProcessHandle, nil, True) then Exit;
      // initialisation de la structure pour le retour des infos
      i := SizeOf(TSymbol_Info);
      ZeroMemory(@SymbolInfo, i);
      SymbolInfo.MaxNameLen := MaxSymbolNameLen;
      SymbolInfo.SizeOfStruct :=  i - Length(SymbolInfo.Name) * SizeOf(SymbolInfo.Name[0]);
      Deplacement := 0;
      // informations sur l'adresse demandée
      if SymFromAddr(ProcessHandle, int64(aAddress), Deplacement, @SymbolInfo) then
      begin
        if (SymbolInfo.Flags or SYMFLAG_FUNCTION) = SYMFLAG_FUNCTION  // filtre les fonctions
        then Result := SymbolInfo.Name;
      end;
      // libération de la table des symboles
      SymCleanup(ProcessHandle);
    end;
    je ne comprends pas bien où se situe ton problème ?

    j'ai repris ton code tel quel et je l'ai mis dans une unité et voilà:
    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
    unit UGetProcName;
     
    interface
    function GetDllFunctionNameFromAddress(aAddress: Pointer): String;
     
    implementation
    uses Windows, SysUtils;
    const
      DbgHelpDll = 'dbghelp.dll';
     
    function SymInitialize(aHandle: HMODULE;
     aUserSearchPath: PChar;
     aInvadeProcess: Boolean): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymInitializeW'
    {$ELSE}
      name 'SymInitialize'
    {$ENDIF};
     
    function SymFromAddr(aHandle: HMODULE;
     aAdress: uint64;
     var aDisplacement: Cardinal;
     aSymbolInfo: Pointer): Boolean; stdcall; external DbgHelpDll
    {$IFDEF UNICODE}
      name 'SymFromAddrW'
    {$ELSE}
      name 'SymFromAddr'
    {$ENDIF};
     
    function SymCleanup(aHandle: HMODULE): Boolean; stdcall; external DbgHelpDll;
     
    // retourne le nom d'une fonction d'une bibliothèque à partir de son adresse.
    function GetDllFunctionNameFromAddress(aAddress: Pointer): String;
    const
      SYMFLAG_FUNCTION = $00000800 or $00000200; // fonction ou export table
      MaxSymbolNameLen = 256;
     
    type
      TSYMBOL_INFO = record
        SizeOfStruct: Cardinal;
        TypeIndex: Cardinal;
        Reserved_1, Reserved_2: uint64;
        Index: Cardinal;
        Size: Cardinal;
        ModBase: uint64;
        Flags: Cardinal; // SYMFLAG_FUNCTION
        Value: uint64;
        Address: uint64;
        Registre: Cardinal;
        Scope: Cardinal;
        Tag: Cardinal;
        NameLen: Cardinal;
        MaxNameLen: Cardinal; // MaxSymbolNameLen (modifiable)
        Name: array[0..MaxSymbolNameLen-1] of Char; // pas à inclure dans TSYMBOL_INFO.SizeOfStruct
      end;
     
    var
      ProcessHandle: HMODULE;
      i, Deplacement: Cardinal;
      SymbolInfo: TSYMBOL_INFO;
     
    begin
      Result := EmptyStr;
      ProcessHandle := GetCurrentProcess;
      // initialisation de la table des symboles
      if not SymInitialize(ProcessHandle, nil, True) then Exit;
      // initialisation de la structure pour le retour des infos
      i := SizeOf(TSymbol_Info);
      ZeroMemory(@SymbolInfo, i);
      SymbolInfo.MaxNameLen := MaxSymbolNameLen;
      SymbolInfo.SizeOfStruct :=  i - Length(SymbolInfo.Name) * SizeOf(SymbolInfo.Name[0]);
      Deplacement := 0;
      // informations sur l'adresse demandée
      if SymFromAddr(ProcessHandle, int64(aAddress), Deplacement, @SymbolInfo) then
      begin
        if (SymbolInfo.Flags or SYMFLAG_FUNCTION) = SYMFLAG_FUNCTION  // filtre les fonctions
        then Result := SymbolInfo.Name;
      end;
      // libération de la table des symboles
      SymCleanup(ProcessHandle);
    end;
    end.
    et ça fonctionne

    Cordialement,
    @+

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. inverser l'écran
    Par relax_06 dans le forum C++Builder
    Réponses: 2
    Dernier message: 13/03/2004, 12h20
  2. inverser la lecture d'une requète
    Par nilaco dans le forum Requêtes
    Réponses: 5
    Dernier message: 10/08/2003, 12h16
  3. [VB6] [Graphisme] Inversion dans picturebox
    Par tomnie dans le forum VB 6 et antérieur
    Réponses: 23
    Dernier message: 16/04/2003, 15h05
  4. Inverser une chaîne de caractères
    Par DBBB dans le forum Assembleur
    Réponses: 2
    Dernier message: 30/03/2003, 11h09
  5. [VB6]fonction inverse de Hex (nombres hexadécimaux)
    Par Guigui_ dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 08/10/2002, 19h31

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