在mmaped内存中执行目标代码

2024-05-12 21:54:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用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更好的方法吗?你知道吗


Tags: 代码机器byctypesintmmmovmmap