-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexecasm.py
69 lines (56 loc) · 2.02 KB
/
execasm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import os
import ctypes
RET = b'\xC3'
def get_buffer(buffer):
try:
buffer = memoryview(buffer)
except TypeError:
buffer = memoryview(bytes(buffer))
buftype = ctypes.c_char * buffer.nbytes
if buffer.readonly:
return buftype.from_buffer_copy(buffer)
return buftype.from_buffer(buffer)
if os.name == 'nt':
kernel32 = ctypes.windll.kernel32
kernel32.VirtualAlloc.restype = ctypes.c_void_p
MEM_COMMIT = 0x00001000
PAGE_READWRITE = 0x04
PAGE_EXECUTE_READ = 0x20
MEM_RELEASE = 0x8000
def asm_func(code, restype=None, *argtypes):
code = get_buffer(code)
buff = ctypes.c_void_p(
kernel32.VirtualAlloc(None, len(code), MEM_COMMIT, PAGE_READWRITE))
ctypes.memmove(buff, code, len(code))
oldp = ctypes.c_uint32()
kernel32.VirtualProtect(
buff, len(code), PAGE_EXECUTE_READ, ctypes.byref(oldp))
funcptr = ctypes.cast(buff, ctypes.CFUNCTYPE(restype, *argtypes))
return funcptr
def free_asm_func(funcptr):
kernel32.VirtualFree(funcptr, 0, MEM_RELEASE)
else:
import mmap
libc = ctypes.CDLL(None)
libc.mmap.restype = ctypes.c_void_p
def asm_func(code, restype=None, *argtypes):
code = get_buffer(code)
buff = ctypes.c_void_p(libc.mmap(
None, len(code), mmap.PROT_READ | mmap.PROT_WRITE,
mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS, -1, 0))
ctypes.memmove(buff, code, len(code))
libc.mprotect(buff, len(code), mmap.PROT_READ | mmap.PROT_EXEC)
funcptr = ctypes.cast(buff, ctypes.CFUNCTYPE(restype, *argtypes))
funcptr.length = len(code)
return funcptr
def free_asm_func(funcptr):
libc.munmap(funcptr, getattr(funcptr, 'length', mmap.PAGESIZE))
def exec_asm(code, restype=None, argtypes=(), args=(), add_ret=False):
if add_ret:
code = bytes(code) + RET
funcptr = asm_func(code, restype, *argtypes)
try:
res = funcptr(*args)
finally:
free_asm_func(funcptr)
return res