2009-01-07 23 views
5

Esto puede parecer una pregunta extraña, pero me gustaría saber cómo puedo ejecutar una función en un .dll desde una 'firma' de memoria. No entiendo mucho sobre cómo funciona en realidad, pero lo necesitaba mucho. Es una forma de ejecutar funciones no exportadas desde un .dll, si conoce la firma de la memoria y la dirección de la misma. Por ejemplo, tengo estos:Ejecutando funciones .dll no expulsadas con python

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

Y el uso de algunos bastante ingenioso código C++ puede utilizar esto para ejecutar funciones desde dentro de un archivo .dll.

Aquí es un artículo bien explicado en él: http://wiki.alliedmods.net/Signature_Scanning

Por lo tanto, es posible utilizar ctypes o cualquier otra forma de hacer esto pitón dentro?

Respuesta

2

Si ya puede ejecutarlos usando C++, puede intentar usar SWIG para generar envoltorios de Python para el código de C++ que ha escrito haciendo que se pueda invocar desde python.

http://www.swig.org/

Algunas advertencias que he encontrado usando el TRAGO:

trago mira hacia arriba tipos en función de un valor de cadena. Por ejemplo, , un tipo de entero en Python (int) buscará asegurarse de que el tipo de cpp es "int"; de lo contrario, swig se quejará sobre el tipo no coincide. No hay conversión automática

Swig copia el código fuente literal, por lo tanto, incluso los objetos en el mismo espacio de nombres deberán estar totalmente calificados para que el archivo cxx se compile correctamente.

Espero que ayude.

0

Dijiste que intentabas llamar a una función que no se había exportado; por lo que sé, eso no es posible desde Python. Sin embargo, su problema parece ser simplemente que el nombre está destrozado.

Puede invocar una exportación arbitraria utilizando ctypes. Como el nombre está mutilado y no es un identificador de Python válido, puede usar getattr().

Otro enfoque si tiene la información correcta es encontrar la exportación por ordinal, lo que tendría que hacer si no hubiera ningún nombre exportado. Una forma de obtener el ordinal sería usando dumpbin.exe, incluido en muchos lenguajes compilados de Windows. En realidad, es un front-end del enlazador, por lo que si tiene el MS LinK.exe, también puede usarlo con los conmutadores de línea de comando apropiados.

Para obtener la referencia de función (que es un objeto "función triple" con destino a la dirección de la misma), se puede usar algo como:

ctypes importación func = getattr (ctypes.windll.msvcrt, "@@ myfunc") retval = func (Ninguno)

Naturalmente, debe reemplazar el 'msvcrt' con el dll al que desea llamar específicamente.

Lo que no se muestra aquí es cómo desmantelar el nombre para derivar la firma de la llamada y, por lo tanto, los argumentos necesarios. Hacer eso requeriría un demangler, y esos son muy específicos para la marca Y LA VERSIÓN del compilador C++ utilizado para crear el archivo DLL.

Hay una cierta cantidad de errores comprobando si la función es stdcall, por lo que a veces puedes jugar con las cosas hasta que las tengas bien. Pero si la función es cdecl, entonces no hay forma de verificar automáticamente. Asimismo, debe recordar incluir el parámetro adicional si corresponde.

Cuestiones relacionadas