在mmap-ed内存中执行目标代码

时间:2016-10-03 03:13:39

标签: python python-3.x

我试图在python中编写一个简单的JIT,包括将机器代码写入mmap-ed内存然后执行它。

按照此blog post中的说明,双倍功能的目标代码

int multby2(int a) { return 2*a; }

(在我的macOS El Capitan机器上)

   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
   7:   8b 7d fc                mov    edi,DWORD PTR [rbp-0x4]
   a:   c1 e7 01                shl    edi,0x1
   d:   89 f8                   mov    eax,edi
   f:   5d                      pop    rbp
  10:   c3                      ret

将其写为Python 3字节对象:

MULT_BY_TWO_OBJ = b''.join([
    b'\x55',          # push   rbp
    b'\x48\x89\xe5',  # mov    rbp,rsp
    b'\x89\x7d\xfc',  # mov    DWORD PTR [rbp-0x4],edi
    b'\x8b\x7d\xfc',  # mov    edi,DWORD PTR [rbp-0x4]
    b'\xc1\xe7\x01',  # shl    edi,0x1
    b'\x89\xf8',      # mov    eax,edi
    b'\x5d',          # pop    rbp
    b'\xc3',          # ret
    ])

我的程序用于将此机器代码写入mmap-ed缓冲区,然后执行如下:

import mmap
import ctypes

mm_buf = mmap.mmap(
    -1, len(MULT_BY_TWO_OBJ),
    flags=mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE,
    prot=mmap.PROT_WRITE | mmap.PROT_EXEC)

mm_buf.write(MULT_BY_TWO_OBJ)

prototype = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
mm_buf_address = ctypes.c_int.from_buffer(mm_buf)
double_func = prototype(mm_buf_address.value)

print(double_func(ctypes.c_int(1)))

mm_buf.close()

运行此程序会导致分段错误:

Segmentation fault: 11

是否可以在Python中执行这样的mmap-ed机器代码? Python中使用mmapctypes是否有更好的方法?

0 个答案:

没有答案