mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-04-06 01:16:37 +02:00

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).
132 lines
3.3 KiB
Python
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
|
|
|