2009-02-16 17 views
13

Je voudrais appeler une méthode d'une DLL, mais je n'ai pas la source ni le fichier d'en-tête. J'ai essayé d'utiliser le dumpbin/exports pour voir le nom de la méthode, mais je peux trouver la signature des méthodes?Fonction d'appel dans C++ dll sans en-tête

Est-il possible d'appeler cette méthode?

Merci,

+0

Quel est le nom exact de la méthode affichée par dumpbin/exports? – ChrisW

Répondre

3

Il est possible de trouver une signature de fonction C en analysant le début de son désassemblage. Les arguments de la fonction seront sur la pile et la fonction fera des "pops" pour les lire dans l'ordre inverse. Vous ne trouverez pas les noms des arguments, mais vous devriez être capable de trouver leur nombre et les types. Les choses peuvent devenir plus difficiles avec la valeur de retour - il peut s'agir d'un registre 'eax' ou d'un pointeur spécial passé à la fonction en tant que dernier pseudo-argument (en haut de la pile).

10

Si la fonction est un C++, vous pouvez être en mesure de déduire la signature de la fonction du nom mutilée. Dependency Walker est un outil qui fera cela pour vous. Cependant, si la DLL a été créée avec C linkage (Dependency Walker vous le dira), alors vous n'avez pas de chance.

6

Le langage C++ ne connaît rien aux dll.

Est-ce que c'est sous Windows? Une façon serait de:

  • ouvrir la dll en depends.exe livré avec (Visual Studio)
  • vérifier la signature de la fonction que vous souhaitez appeler
  • utilisation LoadLibrary() pour obtenir charger cette dll (attention sur le chemin)
  • utilisation GetProcAddress() pour obtenir un pointeur vers la fonction que vous voulez appeler
  • utiliser ce pointeur à la fonction pour faire un appel avec des arguments valables
  • d'utilisation FreeLibrary() pour libérer la poignée

BTW: Cette méthode est aussi communément appelé liaison dynamique d'exécution par rapport à la compilation liaison dynamique où vous compilez vos sources avec le fichier lib associé.

Il existe un mécanisme similaire pour * nix avec dlopen, mais ma mémoire commence à échouer après. Quelque chose appelé objdump ou nm devrait vous aider à inspecter la (les) fonction (s).

1

Si vous connaissez ou suspectez fortement la fonction, vous pouvez charger dynamiquement la DLL avec loadLibrary et obtenir un pointeur sur la fonction avec getProcAddress. Voir MSDN

Notez qu'il s'agit d'une manière manuelle et dynamique de charger la bibliothèque; vous devrez toujours connaître la bonne signature de fonction pour mapper le pointeur de fonction afin de l'utiliser. AFAIK il n'y a aucun moyen d'utiliser la DLL dans une capacité de chargement et d'utiliser les fonctions sans un fichier d'en-tête.

6

Comme vous l'avez constaté, la liste des exportations dans une DLL ne stocke que les noms, pas les signatures. Si votre DLL exporte des fonctions C, vous devrez probablement désassembler et désosser les fonctions pour déterminer les signatures de méthode. Toutefois, C++ code la signature de méthode dans le nom d'exportation. Ce processus de combinaison du nom et de la signature de la méthode est appelé "name mangling". This Stackoverflow question a une référence pour déterminer la signature de méthode à partir du nom d'exportation tronqué.

Essayez l'utilitaire gratuit "Dependency Walker" (a.k.a. "depends"). L'option "Undecorate C++ Functions" doit déterminer la signature d'une méthode C++.

1

L'appel de fonctions non externes est une excellente façon de faire en sorte que votre programme soit interrompu chaque fois que la DLL tierce est mise à jour.

Cela dit, l'utilitaire undname peut également être utile.