À titre d'exemple concret, voici comment appeler une fonction qui prendra un int et le renverra incrémenté de un.
Pour obtenir la mémoire avec le drapeau exécutable activé, mmap
est utilisé.
Pour appeler la fonction, ctypes
est utilisé.
Pour mettre le code machine en mémoire, il existe une chaîne d'octets codée en dur du code machine x86-64.
Le code imprimera 43.
En pratique, j'écrirais le code dans une bibliothèque d'objets partagés en C et j'utiliserais l'assemblage en ligne en C. J'utiliserais alors cffi
pour charger et exécuter la bibliothèque. L'avantage de cet exemple est qu'il est autonome et ne nécessite que la bibliothèque Python standard.
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'\x8b\xc7' # mov eax, edi
b'\x83\xc0\x01' # add eax, 1
b'\xc3' # ret
)
r = f(42)
print(r)
del fpointer
buf.close()