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

C++ Discussion :

Branchement à chaud d'une dll ( iat patching ? )


Sujet :

C++

  1. #1
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut Branchement à chaud d'une dll ( iat patching ? )
    Bonjour,

    J'ai un besoin simple ( lié à une situation de debug ) : j'ai un executable lourd à démarrer qui link à une bibliothèque dynamique trés légère ( et donc rapide à compiler ). Je veux débugger la dll en question.

    J'aimerai donc pouvoir sans redémarrer l'éxécutable recharger la dll, pour changer les comportements de tout les appels fait depuis l'éxécutable vers la dll.

    Je précise que je n'ai pas besoin d'être portable, une solution qui fonctionnerait sous windows me suffirait amplement. Je précise aussi bien entendu que l'api de la dll ne changera pas.

    Bien entendu je pourrais utiliser GetProcAdress, mais j'ai potentiellement un grand nombre de symbol à recharger (qui ne seront pas forcément des fonctions) et surtout j'aimerais utiliser une méthode générique qui n'oblige pas la dll et l'éxécutable à être réécrit ( au free/loadlibrary prêt du coté de l'éxécutable ).

    J'ai essayé cette procédure (qui ne fonctionne pas):
    * appel ex -> dll : comportement 0
    * freelibrary
    * changement de la dll sur le système de fichier ( avec la dll qui à le comportement 1 )
    * load library
    * appel ex -> dll : toujours le comportement 0 :'(

    Existe t il une solution simple ? J'ai entendu parler de l'iat patching mais ça me semble un peu lourd à implémenter.

  2. #2
    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
    Bonjour.

    Personnellement je n'utilise que des dll COM. Tu peux les charger/décharger à la volée. Pas de souci, si tu ne modifies pas les noms de fonctions ou les paramètres d'appel qu'utilise l'exécutable. Si tu modifies les méthodes et les paramètres, c'est encore possible, mais c'est un peu plus de travail de développement.

    PS: par contre je suis étonné qu'après un FreeLibrary, ce soit le premier exemplaire de la dll qui soit rechargé. Peut-être une optimisation de windows qui recharge l'exemplaire en mémoire (comportement 0) et non l'exemplaire sur le disque (comportement 1)...

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Citation Envoyé par MatRem Voir le message
    J'ai un besoin simple ( lié à une situation de debug ) : j'ai un executable lourd à démarrer qui link à une bibliothèque dynamique trés légère ( et donc rapide à compiler ). Je veux débugger la dll en question.
    * Soit tu veux débugger la bibliothèque et alors tu utilises une application de test dédiée à la place de ton exécutable lourd à démarrer. Cette application de test sollicite les interfaces de ta dll dans différents scénarii couvrant le design de ta bibliothèque
    * Soit tu veux debugger ton exécutable et alors c'est ta bibliothèque que tu dois bouchonner pour vérifier que les appels sont cohérents.
    * Soit tu fais du test système, mais cela suppose que ta bibliothèque n'a pas besoin d'être debuggée...

    Citation Envoyé par MatRem Voir le message
    Bien entendu je pourrais utiliser GetProcAdress, mais j'ai potentiellement un grand nombre de symbol à recharger (qui ne seront pas forcément des fonctions) et surtout j'aimerais utiliser une méthode générique qui n'oblige pas la dll et l'éxécutable à être réécrit ( au free/loadlibrary prêt du coté de l'éxécutable ).
    Je ne comprends pas. Soit tu utilises LoadLibrary/GetProcAddress/FreeLibrary, soit tu n'utilises pas GetProcAdress et LoadLibrary/FreeLibrary ne te servent à rien (peut être même que LoadLibrary échoue). C'est à priori comme ça que j'expliquerais ton code (simple hypothèse) : pas de changement car en réalité le lien a été fait avec la bibliothèque 1 depuis longtemps, que celle-ci a été chargée en mémoire au démarrage de VeryBigFatHeavyApplication et que LoadLibrary n'a servi à rien.

    Citation Envoyé par MatRem Voir le message
    Existe t il une solution simple ? J'ai entendu parler de l'iat patching mais ça me semble un peu lourd à implémenter.
    => IAT patching : c'est effectivement un gros marteau
    => Je connais pas bien mais peut être que les delay-loaded DLL peuvent t'arranger. D'autant, qu'elles on peut les décharger explicitement.
    => Une DLL intermédiaire : tu mets une DLL de swap entre ton exécutable et ta vrai DLL : elle offre un linkage implicite à l'exécutable et s'occupe du linkage explicite vers la DLL à debugger. Bref, c'est elle qui fait les LoadLibray/GetProcAdress/FreeLibrary et ton exécutable ne change pas (comme dirait l'autre, All problems in computer science can be solved by another level of indirection. )

  4. #4
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Merci beaucoup ça fonctionne.

    Il faut donc :
    - activer le mode delay ( /delay:unload et /delayload:mylibrary.dll sur le projet de l'executable )
    - FreeLibrary(GetModuleHandle("MyLibrary")) => les appels vont effectivement echouer
    - LoadLibrary("MyLibrary") => ils échouent toujours mais cet appel charge effectivement la nouvelle version en mémoire
    - __HrLoadAllImportsForDll(""MyLibrary".dll") => recharge l'iat et les appels vont passer par la nouvelle version

Discussions similaires

  1. Extraire les icônes d'une DLL
    Par Globus dans le forum MFC
    Réponses: 6
    Dernier message: 13/09/2002, 13h44
  2. pb de récup de handle à partir d'une dll
    Par yokito dans le forum Langage
    Réponses: 2
    Dernier message: 20/08/2002, 12h29
  3. Utilisation d'une dll écrite en delphi 5 dans VB6
    Par Jean-Louis dans le forum Langage
    Réponses: 4
    Dernier message: 05/08/2002, 09h19
  4. Declarer une dll Delphi ?
    Par DelphiCool dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/07/2002, 10h07
  5. Equivalent à ExeName pour une DLL
    Par Smortex dans le forum Langage
    Réponses: 7
    Dernier message: 16/07/2002, 21h07

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