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

 Delphi Discussion :

Problème avec les API : VirtualProtectEx et ReadProcessMemory ?


Sujet :

Delphi

  1. #1
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut Problème avec les API : VirtualProtectEx et ReadProcessMemory ?
    Bonjour,

    Je suis actuellement en train de développer un plugin pour OllyDbg et je rencontre un problème avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    lpflOldProtect : Pointer;
    hMem : Boolean;
    sCode : PChar;
    bRead : ULONG;
     
    lpflOldProtect := nil;
    VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, PAGE_EXECUTE_READWRITE, lpflOldProtect);
    hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), @sCode, gDebugCodeSize, bRead);
    VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, Cardinal(lpflOldProtect), lpflOldProtect);
    Le code est compilé, mais ma variable sCode reste désespérément vide...

    Peut-être que j'utilise mal les API ?

    Merci,
    ZiP

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut Zip

    Toujours le même piège: PChar ou PAnsiChar ?

    @+

  3. #3
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour Cl@udius,

    Je ne pense pas car cette fois-ci, je n'ai pas des "??[...]" d'affichés mais rien du tout :
    sCode =
    Je viens tout de même d'effectuer les corrections suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sCode : PAnsiChar;
    Le résultat reste identique

    Merci pour votre aide,
    ZiP

  4. #4
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Bonjour,
    Citation Envoyé par [ZiP] Voir le message
    Peut-être que j'utilise mal les API ?
    il semblerait que oui
    Citation Envoyé par msdn
    lpflOldProtect [out]

    A pointer to a variable that receives the previous access protection of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

    Il te faut une variable OldProtect de type DWORD que tu passes par pointeur (@OldProtect, ce qui revient à faire, manuellement, un passage par référence). Pense aussi à vérifier la valeur de retour de la fonction VirtualProtectEx ; cela t'indiquera si ton appel a réussi ou pas.

  5. #5
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour gb_68,

    J'ai modifié mon code comme vous me l'avez expliqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    lpflOldProtect : DWORD;
    hMem : Boolean;
    sCode : PAnsiChar;
    bRead : ULONG;
     
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, PAGE_EXECUTE_READWRITE, @lpflOldProtect);
    if hMem then Log('VirtualProtectEx => OK !');
    hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), Pointer(sCode), gDebugCodeSize, bRead);
    if hMem then Log('ReadProcessMemory => OK !');
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, lpflOldProtect, @lpflOldProtect);
    if hMem then Log('VirtualProtectEx => OK !');
    Les deux appels à VirtualProtectEx fonctionnent, par contre, ReadProcessMemory ne fonctionne pas !

    Merci pour votre aide,
    ZiP

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Il y a un truc qui manque ! non ?
    Comme définir la zone mémoire de réception ! Ou tu l'as fait ailleurs ?!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    GetMem(sCode, gDebugCodeSize);
    hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), Pointer(sCode), gDebugCodeSize, bRead);
    if hMem then Log('ReadProcessMemory => OK !');
    FreeMem(sCode);
    En cas d'erreur, utilise GetLastError, cela te fourni un code d'erreur supplémentaire !
    Puis SysErrorMessage (encapsulation de FormatMessage), te fourniras un message d'erreur normalement compréhensible !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour ShaiLeTroll,

    Effectivement, je n'ai pas définit la zone mémoire de réception !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    lpflOldProtect : DWORD;
    hMem : Boolean;
    sCode : PAnsiChar;
    bRead : Cardinal;
     
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, PAGE_EXECUTE_READWRITE, @lpflOldProtect);
    if hMem then Log('VirtualProtectEx => OK !');
    GetMem(sCode, gDebugCodeSize);
    hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), Pointer(sCode), gDebugCodeSize, bRead);
    if hMem then Log('ReadProcessMemory => OK !');
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, lpflOldProtect, @lpflOldProtect);
    if hMem then Log('VirtualProtectEx => OK !');
    Avec ce code, je récupère des données, il faut que je vérifie si celles-ci sont correctes !

    Merci,
    ZiP

  8. #8
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour,

    J'ai modifié mon code comme ceci :
    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
     
         hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, PAGE_EXECUTE_READWRITE, @lpflOldProtect);
         if hMem then Log('VirtualProtectEx => OK !');
         GetMem(sCode, gDebugCodeSize);
         hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), Pointer(sCode), gDebugCodeSize, bRead);
         if hMem then Log('ReadProcessMemory => OK !');
         hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, lpflOldProtect, @lpflOldProtect);
         if hMem then Log('VirtualProtectEx => OK !');
     
         if Debug then
         begin
              Log('Length(sCode) = ' + IntToStr(Length(sCode)));
              for i:=0 to Length(sCode) do
              begin
                   Log('sCode = 0x' + IntToHex(Ord(sCode[i]), 2));
              end;
         end;
    Il m'affiche ça :
    DEBUG --> gDebugCodeStart = 00401000
    DEBUG --> gDebugCodeSize = 0004F800
    DEBUG --> VirtualProtectEx => OK !
    DEBUG --> ReadProcessMemory => OK !
    DEBUG --> VirtualProtectEx => OK !
    DEBUG --> Length(sCode) = 3
    DEBUG --> sCode = 0x04
    DEBUG --> sCode = 0x10
    DEBUG --> sCode = 0x40
    DEBUG --> sCode = 0x00
    Savez-vous pourquoi il ne récupère que 3 caractères ?

    Merci,
    ZiP

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Pour length de scode ? tu risque encore d'avoir un conflit Ansi\Wide ^
    Length converti ton PAnsiChar en String (ne me demande pas laquelle), je ne sais exactement ce qui se passe, mais ça doit surement appelé implicitement _LStrFromPChar, ce qui alloue une chaine, dès qu'il y a un caractère zéro, c'est considiré comme une fin de chaine !

    utilise directement gDebugCodeSize qui contient 318Ko !
    Tu devrais même utiliser un TByteDynArray au lieu de PAnsiChar ou un PByte !
    Faut arrêter de manipuler des Byte via des Char, c'était une pratique courante avant qui n'est vraiment plus propre aujourd'hui !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    Bonjour ShaiLeTroll,

    Je viens de vérifier le contenu de ma fenêtre de Log avec le code désassemblé et effectivement, il s'arrête au premier '00' !

    J'ai modifié mon code comme ceci :
    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
     
    sCode : PByte;
     
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, PAGE_EXECUTE_READWRITE, @lpflOldProtect);
    if Debug then
    begin
         if hMem then Log('VirtualProtectEx => OK !');
    end;
    GetMem(sCode, gDebugCodeSize);
    //if Debug then Log('Length(sCode) = ' + IntToStr(SizeOf(sCode)));
    hMem := ReadProcessMemory(gDebugHandleProcess, Pointer(gDebugCodeStart), Pointer(sCode), gDebugCodeSize, bRead);
    if Debug then
    begin
         if hMem then Log('ReadProcessMemory => OK !');
    end;
    hMem := VirtualProtectEx(gDebugHandleProcess, Pointer(gDebugCodeStart), gDebugCodeSize, lpflOldProtect, @lpflOldProtect);
    if Debug then
    begin
         if hMem then Log('VirtualProtectEx => OK !');
         //Log('Length(sCode) = ' + IntToStr(SizeOf(sCode)));
         for i:=0 to gDebugCodeSize do
         begin
              Log('sCode = 0x' + IntToHex(Ord(sCode[i]), 2));
         end;
    end;
    Par contre, sais-tu comment récupérer la taille d'un PByte ?

    Ce code fonctionne à merveille, merci beaucoup pour votre aide !

    Merci,
    ZiP

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Récupérer la taille d'un PByte, euh 4 Octets pour un adressage 32 bits
    Non ! C'est pour cela que l'on fourni généralement la taille des Buffers aux API !

    petite correction " - 1 ", sinon tu risque de dépasser, parfois tu pourras lire parfois non !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i:=0 to gDebugCodeSize - 1 do
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  12. #12
    Membre averti
    Homme Profil pro
    Paramétreur de progiciels
    Inscrit en
    Octobre 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Paramétreur de progiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 970
    Points : 381
    Points
    381
    Par défaut
    D'accord, c'est corrigé !

    Merci,
    ZiP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Google API Calendar v3 : problème avec les librairies
    Par StringBuilder dans le forum C#
    Réponses: 9
    Dernier message: 26/12/2014, 17h11
  2. Problème avec les API
    Par Bertr@nd dans le forum Windows Forms
    Réponses: 20
    Dernier message: 14/07/2007, 14h53
  3. Problème avec les apostrophes
    Par misterbillyboy dans le forum Requêtes
    Réponses: 2
    Dernier message: 15/07/2003, 16h39
  4. Problème avec les fichiers .JPG
    Par cprogil dans le forum Langage
    Réponses: 5
    Dernier message: 10/06/2003, 15h44
  5. []Problème avec les formulaires Outlook
    Par davidinfo dans le forum Outlook
    Réponses: 6
    Dernier message: 05/12/2002, 09h59

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