Created
February 25, 2015 08:08
-
-
Save markrwilliams/01f1d9ff1084b7ea8cc4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from spyce import (Rights, CAP_READ, CAP_LOOKUP, CAP_SEEK, CAP_MMAP, | |
CAP_FSTAT, CAP_MMAP_RX, enterCapabilityMode) | |
import imp | |
import re | |
import cffi | |
import ctypes | |
import os | |
import sys | |
from fsnix import fs | |
ffi = cffi.FFI() | |
ffi.cdef(''' | |
static const int RTLD_NOW; | |
static const int RTLD_LAZY; | |
struct __dlfunc_arg { | |
...; | |
}; | |
typedef void (*dlfunc_t)(struct __dlfunc_arg); | |
typedef void (*initmodule_func_t)(void); | |
void * | |
fdlopen(int fd, int mode); | |
dlfunc_t | |
dlfunc(void * restrict handle, const char * restrict symbol); | |
void * | |
dlsym(void * restrict handle, const char * restrict symbol); | |
char * | |
dlerror(void); | |
initmodule_func_t | |
convert(dlfunc_t f); | |
void | |
invoke(dlfunc_t f); | |
''') | |
lib = ffi.verify(''' | |
#include <dlfcn.h> | |
typedef void (*initmodule_func_t)(void); | |
initmodule_func_t | |
convert(dlfunc_t f) | |
{ | |
return (initmodule_func_t)f; | |
} | |
void | |
invoke(dlfunc_t f) | |
{ | |
initmodule_func_t initfunc; | |
initfunc = (initmodule_func_t)f; | |
initfunc(); | |
} | |
''') | |
ADDR_EXTRACTOR = re.compile('<.+ 0x((?:[0-9]|[A-H]|[a-h])+)>') | |
def _addr_of(cdata): | |
match = ADDR_EXTRACTOR.search(repr(cdata)) | |
if not match: | |
raise RuntimeError("could not hack out an addr for %r" % cdata) | |
return int(match.group(1), 16) | |
fdlopen = lib.fdlopen | |
dlfunc = lib.dlfunc | |
def _import_so(path_fd, module_fn, module_name): | |
imp.acquire_lock() | |
try: | |
so_fd = fs.openat(path_fd, module_fn, os.O_RDONLY) | |
loaded_so = fdlopen(so_fd, lib.RTLD_NOW) | |
if loaded_so == ffi.NULL: | |
raise RuntimeError(ffi.string(lib.dlerror())) | |
initmodule_pointer = dlfunc(loaded_so, 'init%s' % module_name) | |
initmodule = ctypes.PYFUNCTYPE(None)(_addr_of(initmodule_pointer)) | |
initmodule() | |
return sys.modules[module_name] | |
finally: | |
imp.release_lock() | |
def test(): | |
dynload = os.open("/usr/local/lib/python2.7/lib-dynload/", | |
os.O_RDONLY) | |
Rights([CAP_READ, CAP_LOOKUP, CAP_FSTAT, CAP_SEEK, | |
CAP_MMAP_RX, CAP_MMAP]).limitFile(dynload) | |
enterCapabilityMode() | |
mmap = _import_so(dynload, | |
"mmap.so", 'mmap') | |
print mmap.mmap(-1, 1024) | |
test() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment