Saltar al contenido

Ejecutando código ensamblador con Python

Solución:

Una forma de hacer esto sería escribir una extensión (C) para Python. Puede echar un vistazo a esta documentación para obtener detalles completos sobre cómo hacerlo.

Otra forma de desarrollar extensiones de Python basadas en C sería interactuar directamente con una biblioteca externa usando el módulo ctypes.

En cualquier caso, necesitaría algo de código C compilado en una biblioteca o una extensión y una forma de llamarlo desde Python. Claramente, para lo que desea lograr, esto probablemente no sea óptimo, pero en realidad no es mucho trabajo exponer algunas funciones.

Puede incrustar el ensamblaje directamente dentro de su programa Python:

  • https://github.com/Maratyszcza/PeachPy
  • https://github.com//pycca/pycca
  • http://codeflow.org/entries/2009/jul/31/pyasm-python-x86-assembler/
  • https://github.com/AmihaiN/pyAsm

Estos funcionan compilando el ensamblado y cargándolo en la memoria ejecutable en tiempo de ejecución. Los primeros tres proyectos implementan ensambladores x86-64 o x86 en Python, mientras que el último llama a un compilador externo.

Como ejemplo específico, aquí se explica cómo llamar a una función que tomará un int y lo devolverá incrementado en uno.

Para obtener memoria con la bandera ejecutable establecida, mmap se utiliza el módulo.

Para llamar a la función, ctypes se utiliza el módulo.

Para poner el código de máquina en la memoria, hay una cadena de bytes codificada de código de máquina x86-64.

El código imprimirá 43.

En la práctica, escribiría el código en la biblioteca de objetos compartidos de C y usaría el ensamblaje en línea en C. Luego usaría cffi para cargar y ejecutar la biblioteca. La ventaja de este ejemplo es que es autónomo y solo necesita la biblioteca estándar de Python.

import ctypes
import mmap

buf = mmap.mmap(-1, mmap.PAGESIZE, prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)

ftype = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
fpointer = ctypes.c_void_p.from_buffer(buf)

f = ftype(ctypes.addressof(fpointer))

buf.write(
    b'x8bxc7'  # mov eax, edi
    b'x83xc0x01'  # add eax, 1
    b'xc3'  # ret
)

r = f(42)
print(r)

del fpointer
buf.close()
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *