2009-01-07 9 views
5

Cela peut sembler une question étrange, mais j'aimerais savoir comment je peux exécuter une fonction dans un fichier .dll à partir d'une 'signature' de la mémoire. Je ne comprends pas très bien comment cela fonctionne réellement, mais j'en avais vraiment besoin. C'est un moyen d'exécuter des fonctions non exportées depuis un fichier .dll, si vous connaissez la signature mémoire et l'adresse de celui-ci. Par exemple, j'ai ces:Exécuter des fonctions .dll non exportées avec python

respawn_f "_ZN9CCSPlayer12RoundRespawnEv" 
respawn_sig "568BF18B06FF90B80400008B86E80D00" 
respawn_mask "xxxxx?xxx??xxxx?" 

Et en utilisant une assez astucieux code C++, vous pouvez l'utiliser pour exécuter des fonctions à partir d'un .dll.

Voici un article bien expliqué à ce sujet: http://wiki.alliedmods.net/Signature_Scanning

, est-il possible à l'aide ctypes ou de toute autre façon de le faire python à l'intérieur?

Répondre

2

Si vous pouvez déjà les exécuter en utilisant C++ alors vous pouvez essayer d'utiliser SWIG pour générer des wrappers python pour le code C++ que vous avez écrit, le rendant ainsi appelable à partir de python.

http://www.swig.org/

Quelques mises en garde que je l'ai trouvé à l'aide SWIG:

Swig lève les yeux vers les types en fonction d'une valeur de chaîne. Par exemple un type entier dans Python (int) cherchera à s'assurer que le type cpp est "int" sinon swig se plaindra à propos des incompatibilités de type. Il n'y a pas de conversion automatique. Swig copie le code source mot pour mot, donc même les objets dans le même espace de noms devront être entièrement qualifiés pour que le fichier cxx compile correctement.

Espérons que ça aide.

0

Vous avez dit que vous essayiez d'appeler une fonction qui n'était pas exportée; pour autant que je sache, ce n'est pas possible à partir de Python. Cependant, votre problème semble être simplement que le nom est mutilé.

Vous pouvez appeler une exportation arbitraire à l'aide de ctypes. Comme le nom est tronqué et qu'il ne s'agit pas d'un identifiant Python valide, vous pouvez utiliser getattr().

Une autre approche si vous avez la bonne information est de trouver l'exportation par ordinal, ce que vous auriez à faire s'il n'y avait aucun nom exporté du tout. Une façon d'obtenir l'ordinal serait d'utiliser dumpbin.exe, inclus dans de nombreux langages compilés de Windows. Il s'agit en fait d'un frontal pour l'éditeur de liens, donc si vous avez MS LinK.exe, vous pouvez également l'utiliser avec les commutateurs de ligne de commande appropriés.

Pour obtenir la référence de la fonction (qui est un objet « fonction pointeur » lié à l'adresse de celui-ci), vous pouvez utiliser quelque chose comme:

ctypes importation func = getattr (ctypes.windll.msvcrt, "@@ myfunc") retval = func (Aucun)

Naturellement, vous remplacez le 'msvcrt' par la DLL que vous voulez appeler.

Ce que je ne montre pas ici est comment démonter le nom pour dériver la signature d'appel, et donc les arguments nécessaires. Faire cela nécessiterait un démangeur, et ceux-ci sont très spécifiques à la marque ET VERSION du compilateur C++ utilisé pour créer la DLL.

Il y a une certaine quantité de vérification d'erreur si la fonction est stdcall, donc vous pouvez parfois bidouiller avec les choses jusqu'à ce que vous les ayez correctement. Mais si la fonction est cdecl, il n'y a aucun moyen de vérifier automatiquement. De même, vous devez vous rappeler d'inclure le paramètre supplémentaire si approprié.

Questions connexes