29 votes

Exécution du code assembleur avec python

Je veux exécuter du code assembleur à l'intérieur d'un script de python. Est-ce possible ?

En C, la programmation serait la suivante

static inline getesp(){
        __asm__("mov %esp, %eax");
}

Mais comment faire cela avec Python ? Est-ce possible ?

19voto

jkp Points 20410

Une façon de le faire serait d'écrire une extension (C) pour Python. Vous pouvez jeter un coup d'œil à este pour plus de détails sur la façon de procéder.

Une autre façon de développer des extensions Python basées sur le langage C serait de s'interfacer directement avec une bibliothèque externe en utilisant la fonction ctypes module.

Dans tous les cas, vous aurez besoin de code C compilé dans une bibliothèque ou une extension et d'un moyen de l'appeler depuis Python. Il est clair que pour ce que vous voulez réaliser, ce n'est probablement pas optimal, mais en fait, cela ne représente pas beaucoup de travail d'exposer quelques fonctions.

19voto

Luke Points 4250

Vous pouvez intégrer l'assembleur directement dans votre programme Python :

Ceux-ci fonctionnent en compilant l'assemblage et en le chargeant dans la mémoire exécutable au moment de l'exécution. Les trois premiers projets implémentent des assembleurs x86-64 ou x86 dans Python, tandis que le dernier fait appel à un compilateur externe.

15voto

user1047788 Points 80

À 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()

6voto

Крайст Points 169

Désolé pour le nécropostage mais je pense que vous pouvez écrire votre propre DLL en utilisant asm et appeler ses fonctions depuis Python.

1voto

detly Points 11267

En théorie, vous pourriez :

  1. Ecrivez une fonction simple en C qui appelle l'assemblage
  2. Utilisez Cython o Pyrex pour appeler cette fonction depuis Python

Je dois admettre que je n'ai pas utilisé Pyrex ou Cython, mais ils pourraient être en mesure de faire ce dont vous avez besoin sans avoir à vous donner la peine d'écrire une extension C complète.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X