Question

Imaginez que vous souhaitez écrire un programme qui teste les fonctions dans un c ++ fichier dll. Vous devez permettre à l'utilisateur de sélectionner une dll (nous supposons que nous parlons de c ++ dll). Il devrait être en mesure d'obtenir une liste de toutes les fonctions exportées par la dll. Ensuite, l'utilisateur doit être en mesure de sélectionner un nom de fonction dans la liste, une liste saisie manuelle des arguments (les arguments sont tous les types de base, comme int, double, bool ou tableaux de char (par exemple des chaînes de type c)) et tenter de exécuter la fonction sélectionnée avec les arguments spécifiés. Il aimerait savoir si la fonction fonctionne avec les arguments spécifiés, ou font-ils provoquer des plantages (parce qu'ils ne correspondent pas à la signature par exemple).

Le principal problème est que C ++, étant un langage fortement typé, vous devez connaître le nombre et le type des arguments pour un appel de fonction à la compilation time.And dans mon cas, je ne sais vraiment pas ce que ces arguments sont , jusqu'à ce que l'utilisateur les sélectionne à l'exécution.

La seule solution que je suis venu avec, était d'utiliser l'ensemble pour pousser manuellement les arguments sur la pile d'appel.

Cependant, je suis venu à comprendre que si je veux jouer avec l'ensemble, je ferais mieux de faire sacrément sûr que je sais que la convention d'appel sont les fonctions du dll utilisent.

(enfin :) voici ma question: puis-je déduire la convention d'appel programmaticaly? Dépendance Walker ne me aidera pas, et je n'ai aucune idée comment lire manuellement le format PE.

Était-ce utile?

La solution

La réponse est peut-être .

Si les fonctions noms sont C ++ décorées, vous pouvez déterminer le nombre d'arguments et les types de la décoration de nom, c'est votre meilleur scénario, et assez probable si MSVC a été utilisé pour écrire le code en premier lieu.

Si les fonctions exportées sont la convention d'appel stdcall (la valeur par défaut pour Windows api), vous pouvez déterminer le nombre d'octets à être poussé, mais pas les types des arguments.

Les mauvaises nouvelles sont que pour la convention d'appel C, il n'y a aucun moyen de dire en regardant les noms de symboles. Vous auriez besoin d'avoir accès au code source ou les informations de débogage.

http://en.wikipedia.org/wiki/X86_calling_conventions

Le nom qu'une fonction est donnée comme une exportation n'est pas requis pour avoir une relation avec le nom que l'éditeur de liens voit, mais la plupart du temps, le nom exporté et le nom du symbole que le linker voit sont les mêmes.

Autres conseils

Vous ne précise pas si vous parlez de 32 bits ou 64 bits ici, et les difficultés évoquées par vous et les autres affiches appliquent principalement au code 32 bits. Sur Windows 64 bits, il y a essentiellement une seule convention d'appel (il est en outre dans l'article wikipedia lié par John Knoeller), ce qui signifie que vous faire connaître la convention d'appel (bien sûr, à l'exception de personne concocter leur propre).

En outre, avec la convention d'appel x64 Microsoft, ne connaissant pas le nombre de paramètres de la fonction à appeler ne vous empêche pas de l'appeler, en fournissant autant de paramètres que vous le souhaitez / l'utilisateur souhaite. En effet, vous appelant mis de côté l'espace de la pile et le nettoyer par la suite. -. Bien sûr, ne pas fournir le [nombre de] droit paramètres peuvent encore avoir la fonction appelée faire des choses stupides parce que vous fournissez une entrée invalide, mais c'est une autre histoire

Le code compilé ne dit pas simplement « Ici cette fonction est un fastcall, et celui-ci est stdcall ici » malheureusement.

Même pas désassemblé modernes comme IDA tentent de déduire les types d'appel par défaut (il pourrait y avoir un plugin ou une option idk quelque part).

En gros, si vous êtes un humain vous cn regard sur les premières instructions et dire 90% du temps. Si elles sont pop et pousser, son stdcall, si ses params de passage à travers les registres (en particulier ECX), puis son cdecl. Fastcall utilise également les registres, mais fait quelque chose de spécial .. je sais pas du haut de ma tête. Mais cette information est inutile parce que votre programme ne sera évidemment pas un être humain.

Si vous faites des tests, DonT vous avez au moins les fichiers d'en-tête ?? Ceci est un moyen terriblement difficile de la peau d'un chat ..

Si vous voulez savoir ce que la convention d'appel d'une fonction C ++ utilise, votre meilleur espoir est d'étudier

  1. L'en-tête qui déclare cette fonction, et
  2. La documentation pour le compilateur qui a compilé votre DLL particulier.

Mais tout cela ressemble à un peu de désordre, honnêtement. Pourquoi votre ami veut être en mesure de le faire, et pourquoi ne peut-il obtenir les informations dont il a besoin en analysant un en-tête qui déclare les fonctions pertinentes?

Cette page décrit la façon dont VC ++ 6 code paramètre et appelant info convention en un nom de symbole: http://www.bottledlight.com/docs/mangle.html

Je soupçonne que les versions ultérieures de VC ++ seront compatibles mais je ne l'ai pas confirmé.

Il y a aussi des outils qui automatisent ce qui accompagnent le compilateur: http: //msdn.microsoft.com/en-us/library/5x49w699.aspx

Le nom mutiler applique uniquement pour les fonctions C ++; si une fonction est « extern « C » » alors cela ne fonctionnera pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top