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

MFC Discussion :

pile d'appel


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut pile d'appel
    J'ai 2 dlls qui ataquent une troisième dll.
    Comment savoir dans le code de la 3ème dll(au sein d'une méthode appellé par une des 2 premieres) quelle est la dll qui appelle la méthode?
    Merci

  2. #2
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut
    Merci de m'aider les gars, j'ai vraiment besoin de cette infos pour mes developpements

  3. #3
    Membre expérimenté Avatar de BertrandA
    Inscrit en
    Août 2003
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 170
    Par défaut
    Je ne comprends pas pourquoi tu as besoin de cette information dans ta DLL.
    Néanmoins, est-ce que c'est difficile de passer un paramètre à la fameuse méthode qui doit connaître l'appelant : un enum ou un identifiant quelconque, même un handle... ?

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut
    justement c'est pour ne pas rompre l'interface.

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    pourquoi pas une variable d'environnement alors ,réglée avant l'appel et lue dans la dll pour savoir qui appel.

  6. #6
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut
    le probleme est que je ne peux pas changer le code des 2 dlls ni de l'interface.
    Je dois tout connaitre depuis la 3 ème dll.
    Est-ce possible???

  7. #7
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    ben alors je ne pense pas que ça soit possible ...

  8. #8
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut
    comment le debugger fait il alors?

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    et bien il est deja en debug donc il genere les informations necessaires pour debugger ....


  10. #10
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Par défaut
    Quand tu débugges, tu as bien la pile des appels non?

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 4
    Par défaut
    En dernier recours essaie de mettre la main sur vtune d'intel.

  12. #12
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 101
    Par défaut
    En fait mon code doit savoir quelle dll est l'objet d'un appel de methode.
    Ex. : Si je suis dans la fonction MyFunction de dll3, je veux savoir quell dll a appellé MyFunction, sachant que Mynfunction peut etre appellée par plusieurs clients.

    MyFunction
    {

    Who had called me?? dll1 or dll2??
    }
    Je ne peux rien changer aux interfaces, sinon j'aurais transmis un paramètre.

    C'est quoi le vtune d'intel??

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 4
    Par défaut
    c'est un debugger capable de cartographier sous forme de graphe l'exécution d'un binaire et de ses dll. normalement on utilise ca pour detecter quelles fonctions dans un prog consomme le plus de ressources pour trouver des optimisations. Moi jmen sers essentiellement pour comprendre comment fonctionne un soft.

    Soft commercial par contre..

    Ce que tu cherches a faire j'ai cherché la meme chose ces dernier temps, et pas trouvé.. dsl.

  14. #14
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    C'est techniquement possible bien qu'un peu compliqué...

    Lors d'un appel à une fonction l'adresse de retour est mise sur la pile (stack), ainsi lors de la sortie de cette fonction le programme sait où retourner (donc vers la fonction appelante).

    l'initialisation d'une fonction se fait quasiment toujours par (en Asm) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    PUSH EBP // pousse le pointeur de base (EBP)
    MOV EBP,ESP // met le pointeur de pile (ESP : stack pointer) dans le pointeur de base
    Ainsi quand vous entrez dans la fonction vous pouvez retrouver quelle est l'adresse de la fonction appelante en 'fouinant' sur la pile. Cela requiert un peu d'asm inline, a mettre impérativement au debut de la fonction dans la DLL n°3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DWORD lpAdresseRetour ;
    __asm{
    mov eax, dword ptr [ebp+4]
    mov lpAdresseRetour,eax
    }
    lpAddressRetour contient à ce moment là l'adresse de retour de la fonction appelante.

    Maintenant, comment savoir quel est la DLL ?

    Lorsqu'un processus se crée, les DLL sont 'mappées' (c'est le terme technique) dans son espace d'adresse. La plupart du temps (95%) un exécutable se loge en 0x400000 en mémoire. Les DLL linkées statiquement ou apelée dynamiquement se loge plus loin dans l'espace d'adressage du processus.

    L'adresse de base d'une DLL (le début de son mapping donc) s'obtient aisément avec l'API win32 GetmoduleHandle, en passant comme argument le nom de la DLL.

    Une petite vue de l'espace d'adressage d'un processus (toutes les adresses sont des exemples) :

    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
     
    0x400000 Monexécutable.exe
    - PE header
    - section code
    - import
    - section données
    - ressources
    [etc.]
    0x450000 fin de l'exe (exemple)
     
    ...
     
    0x10000000 DLL n°1
    - PE header
    - section code
    - import
    - export
    - section données
    - ressources
    [etc.]
    0x1050000 fin de DLL 1 (exemple)
     
    ...
     
    0x1200000 DLL n°2
    - PE header
    - section code
    - section données
    -import
    -export
    - ressources
    [etc.]
    0x12500000 fin de DLL n°2 (exemple)
     
    0x13000000 DLL n°3
    - PE header
    - section code
    - import
    - export
    - section données
    - ressources
    [etc.]
    0x13000000 fin de DLL n°3 (exemple)
     
    ...
    En résumer pour trouver la DLL de la fonction appelante :

    1) Obtenez l'adresse lpAdresseRetour
    2) Faites un GetModuleHandle sur vos trois DLL
    3) comparez l'adresse de lpAdressRetour avec les adresse de base de mapping obtenu avec 2)

    Exemple :

    lpAdresseRetour = 0x12300000
    DLL 1 : 0x10000000
    DLL 2 : 0x12000000
    DLL 3 : 0x13000000

    lpAdressRetour est plus haut que DLL1 mais aussi plus haut que DLL2 (ca n'est donc pas DLL 1). C'est donc DLL2 qui apelle DLL3

    Notez que les DLL ne se mappent pas forcément dans l'ordre 1 puis 2 puis 3, c'est pourquoi il faut récupérer les bases des 3 DLLs et faire toutes les comparaisons nécessaires

    Notez finalement que ceci fonctionne pour les procédures d'appel standard type __stdcall (pour la DLL n°3), cela devient plus difficle avec d'autres convention d'appel (nécessite un débugage de la fonction...).

    J'espère n'avoir pas été trop ennuyeux avec ces explications...

  15. #15
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    On pourrait pousser le vice plus loin en listant les modules du process via EnumProcessModules et en déduire celui qui appelle la fonction, mais bon je m'interroge quand même sur un tel besoin. Techniquement c'est sympa, mais c'est très bancal malgré tout. Au moindre changement de nom dans une autre dll / utilisation depuis une 4° dll tout se casse la gueule.
    Sous VC++ >= 7, attention au cookie qui est pushé en plus avec l'option /GS. Cela dit je ne crois pas que cela affecte (la brillante) explication de Neitsa.

  16. #16
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Effectivement la solution par EnumProcessModules est envisageable aussi.

    Comme le souligne Aurélien, cette solution reste très tirée par les cheveux puisque l'on touche plus au Reverse Engineering qu'à la programmation en tant que telle dès qu'on ne peut passer un argument supplémentaire à la fonction... Donc toute modification du nombre de DLL, ou des paramètres de fonction entrainera un gros plantage de l'appli

    J'oublais de souligner (c'est le cookie de sécurité dont Aurélien parlait qui m'y fait penser...) que le +4 dans l'asm inline ne vaut que pour un seul parmamètre passé en argument à la fonction. Il faudra ajouter 4 à chaque parmamètre passé en sus.

    en admettant que la fonction de la DLL n°3 prenne 5 paramètres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DWORD lpAdresseRetour ;
    __asm{
    mov eax, dword ptr [ebp+4*5]
    mov lpAdresseRetour,eax
    }
    En effet la pile se comporte ainsi lors de son init. :

    - params de fonctions
    - adresse de retour <= ce qu'on cherche
    - pointeur de frame
    - cookie de sécu.
    - handler d'exception
    - etc...

    Donc plus il y a de paramètres plus il faudra aller chercher loin...
    (le cookie étant situé après il est donc négligeable dans la recherche de l'adresse de retour)

Discussions similaires

  1. [debug] comment récupérer la pile d'appel lors d'un crash ?
    Par mamelouk dans le forum Autres éditeurs
    Réponses: 13
    Dernier message: 10/11/2006, 17h22
  2. tracer pile d'appels
    Par Estats dans le forum Delphi
    Réponses: 1
    Dernier message: 05/09/2006, 21h30
  3. Affichage de la pile d'appel lors d'une exception
    Par damien.yep dans le forum Langage
    Réponses: 1
    Dernier message: 14/09/2005, 16h42
  4. []Augmenter la taille de la pile des appels ?
    Par oncle ervil dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 10/05/2005, 09h29
  5. [Exception]Connaitre la pile d'appel de classes/méthodes
    Par salome dans le forum Général Java
    Réponses: 2
    Dernier message: 19/03/2005, 20h21

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