1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-06 01:16:37 +02:00
OJ 4424029d3c Add python extension multiprocessing
This commit includes code that was missing from the original Python PR which adds support for the multiprocessing module in Python. I have no idea why this was missed, but it was. The code also includes adjustments to the loader which attempts to resolve modules appropriately based on name. This is a bit of a kludge thanks to the way that Python module resolution hooks work, as it's not clear exactly which namespace the module is intended to be loaded from at runtime as it's not passed to the resolver. Down the track we may need to get smarter with the resolver so that we have a per-module resolver (ie. a tree of resolvers).
2015-12-19 09:40:44 +10:00

132 lines
3.3 KiB
Python

import sys, imp, marshal
met_dbg_trace = False
met_mod_name = None
met_mod_body = None
def met_init(dbg):
global met_dbg_trace
global met_finder
global met_lib_data
met_dbg_trace = dbg
met_finder = MetFinder(met_lib_data[1])
sys.meta_path=[met_finder]
if not dbg:
del met_lib_data
def met_dbg(s):
global met_dbg_trace
if met_dbg_trace:
print s
def met_import_code():
global met_mod_body
global met_mod_name
global met_finder
try:
if met_mod_body != None:
if met_mod_name == None:
met_mod_name = 'met_imported_code'
if met_mod_body[:4] == imp.get_magic():
met_mod_body = marshal.loads(met_mod_body[8:])
else:
met_mod_body = compile(met_mod_body, met_mod_name, 'exec')
met_finder.loader.add_module(met_mod_name, met_mod_body)
else:
raise ValueError("met_mod_body not specified")
finally:
# always reset these two
met_mod_name = None
met_mod_body = None
class MetLoader:
def __init__(self, libs):
self.libs = libs
if met_dbg_trace:
for l in libs.keys():
met_dbg(l)
met_dbg('Total libs: {0}'.format(len(libs.keys())))
def add_module(self, name, code):
imp.acquire_lock()
try:
mod = imp.new_module(name)
sys.modules[name] = mod
try:
mod.__file__ = name + ".py"
exec code in mod.__dict__
mod.__loader__ = self
met_dbg('Executed code for: {0}'.format(name))
except e:
del sys.modules[name]
mod = None
except:
mod = None
finally:
imp.release_lock()
met_dbg('Result for {0}: {1}'.format(name, mod != None))
def load_module(self, name):
met_dbg('Searching for: {0}'.format(name))
if name in sys.modules:
met_dbg('Already loaded: {0}'.format(name))
return sys.modules[name]
if not name in self.libs:
if '.' in name:
parts = name.split('.')
result = self.load_module('.'.join(parts[1:]))
if result == None and len(parts) >= 3:
result = self.load_module('.'.join(parts[0:-2] + [parts[-1]]))
return result
met_dbg('No lib: {0}'.format(name))
return None
met_dbg('Lib exists: {0}'.format(name))
filename, package, code = self.libs[name]
met_dbg('Lib details: {0} - {1}'.format(filename, package))
imp.acquire_lock()
mod = None
try:
mod = imp.new_module(name)
sys.modules[name] = mod
try:
mod.__file__ = filename
if package:
mod.__path__ = [name.replace('.', '\\')]
exec code in mod.__dict__
mod.__loader__ = self
met_dbg('Executed code for: {0}'.format(name))
except Exception as e:
met_dbg('Exception thrown importing module: {0} - {1}'.format(name, e))
del sys.modules[name]
mod = None
except Exception as ex:
met_dbg('Exception thrown starting import: {0} - {1}'.format(name, ex))
mod = None
finally:
imp.release_lock()
#if mod == None and '.' in name:
#return self.load_module('.'.join(name.split('.')[1:]))
met_dbg('Result for {0}: {1}'.format(name, mod != None))
return mod
class MetFinder:
def __init__(self, libs):
self.loader = MetLoader(libs)
def find_module(self, name, path = None):
met_dbg('find_module: {0} {1}'.format(name, path))
return self.loader