Commit aba30b02 by devttys0

Added dependency feature to modules.

parent 6106d337
import io import io
import sys import sys
import inspect
import argparse import argparse
import binwalk.common import binwalk.common
from binwalk.compat import * from binwalk.compat import *
...@@ -42,109 +43,169 @@ class ModuleKwarg(object): ...@@ -42,109 +43,169 @@ class ModuleKwarg(object):
self.default = default self.default = default
self.description = description self.description = description
def list_modules():
pass def process_kwargs(module, kwargs):
return Modules(dummy=True).kwargs(module, kwargs)
def process_argv(module, config=None, argv=sys.argv[1:]):
''' class Modules(object):
Processes argv for any options specific to the specified module.
def __init__(self, dummy=False):
@module - The module to process argv for. self.config = None
@config - An instance of the binwalk.modules.configuration.Configuration class.
@argv - A list of command line arguments (excluding argv[0]).
Returns a dictionary of kwargs for the specified module.
'''
kwargs = {}
last_priority = {}
longs = []
shorts = ""
parser = argparse.ArgumentParser(add_help=False)
if hasattr(module, "CLI"):
for module_option in module.CLI:
if not module_option.long:
continue
if module_option.nargs == 0:
action = 'store_true'
else:
action = None
if module_option.short:
parser.add_argument('-' + module_option.short, '--' + module_option.long, action=action, dest=module_option.long)
else:
parser.add_argument('--' + module_option.long, action=action, dest=module_option.long)
args, unknown = parser.parse_known_args(argv)
args = args.__dict__
for module_option in module.CLI:
if module_option.type in [io.FileIO, argparse.FileType, binwalk.common.BlockFile]:
for k in get_keys(module_option.kwargs):
kwargs[k] = []
for unk in unknown:
if not unk.startswith('-'):
kwargs[k].append(unk)
elif has_key(args, module_option.long) and args[module_option.long] not in [None, False]:
i = 0
for (name, value) in iterator(module_option.kwargs):
if not has_key(last_priority, name) or last_priority[name] <= module_option.priority:
if module_option.nargs > i:
value = args[module_option.long]
i += 1
last_priority[name] = module_option.priority
# Do this manually as argparse doesn't seem to be able to handle hexadecimal values
if module_option.type == int:
kwargs[name] = int(kwargs[name], 0)
elif module_option.type == float:
kwargs[name] = float(kwargs[name])
elif module_option.type == dict:
if not has_key(kwargs, name):
kwargs[name] = {}
kwargs[name][len(kwargs[name])] = value
elif module_option.type == list:
if not has_key(kwargs, name):
kwargs[name] = []
kwargs[name].append(value)
else:
kwargs[name] = value
else:
raise Exception("binwalk.module.process_argv: %s has no attribute 'CLI'" % str(module))
if config is not None and not has_key(kwargs, 'config'):
kwargs['config'] = config
return kwargs if not dummy:
from binwalk.modules.configuration import Configuration
self.config = self.load(Configuration)
def list(self):
import binwalk.modules
objects = []
for (name, obj) in inspect.getmembers(binwalk.modules):
if inspect.isclass(obj) and hasattr(obj, "run"):
objects.append(obj)
return objects
def run(self, module):
results = None
obj = self.load()
if obj.enabled:
try:
obj.run()
except AttributeError:
pass
return results
def load(self, module):
kwargs = self.argv(module)
kwargs.update(self.dependencies(module))
return module(**kwargs)
def dependencies(self, module):
kwargs = {}
if hasattr(module, "DEPENDS"):
# Disable output when modules are loaded as dependencies
orig_log = self.config.display.log
orig_quiet = self.config.display.quiet
self.config.display.log = False
self.config.display.quiet = True
for (kwarg, mod) in module.DEPENDS:
kwargs[kwarg] = self.run(mod)
self.config.display.log = orig_log
self.config.display.quiet = orig_quiet
def process_kwargs(module, kwargs): return kwargs
'''
Processes a module's kwargs. All modules should use this for kwarg processing. def argv(self, module, argv=sys.argv[1:]):
'''
@module - An instance of the module (e.g., self) Processes argv for any options specific to the specified module.
@kwargs - The kwargs passed to the module
@module - The module to process argv for.
Returns None. @argv - A list of command line arguments (excluding argv[0]).
'''
if hasattr(module, "KWARGS"): Returns a dictionary of kwargs for the specified module.
for module_argument in module.KWARGS: '''
if has_key(kwargs, module_argument.name): kwargs = {}
arg_value = kwargs[module_argument.name] last_priority = {}
else: longs = []
arg_value = module_argument.default shorts = ""
parser = argparse.ArgumentParser(add_help=False)
setattr(module, module_argument.name, arg_value)
if hasattr(module, "CLI"):
if has_key(kwargs, 'config'):
setattr(module, 'config', kwargs['config']) for module_option in module.CLI:
else: if not module_option.long:
raise Exception("binwalk.module.parse_module_kwargs: %s has no attribute 'KWARGS'" % str(module)) continue
if module_option.nargs == 0:
action = 'store_true'
else:
action = None
if module_option.short:
parser.add_argument('-' + module_option.short, '--' + module_option.long, action=action, dest=module_option.long)
else:
parser.add_argument('--' + module_option.long, action=action, dest=module_option.long)
args, unknown = parser.parse_known_args(argv)
args = args.__dict__
for module_option in module.CLI:
if module_option.type in [io.FileIO, argparse.FileType, binwalk.common.BlockFile]:
for k in get_keys(module_option.kwargs):
kwargs[k] = []
for unk in unknown:
if not unk.startswith('-'):
kwargs[k].append(unk)
elif has_key(args, module_option.long) and args[module_option.long] not in [None, False]:
i = 0
for (name, value) in iterator(module_option.kwargs):
if not has_key(last_priority, name) or last_priority[name] <= module_option.priority:
if module_option.nargs > i:
value = args[module_option.long]
i += 1
last_priority[name] = module_option.priority
# Do this manually as argparse doesn't seem to be able to handle hexadecimal values
if module_option.type == int:
kwargs[name] = int(kwargs[name], 0)
elif module_option.type == float:
kwargs[name] = float(kwargs[name])
elif module_option.type == dict:
if not has_key(kwargs, name):
kwargs[name] = {}
kwargs[name][len(kwargs[name])] = value
elif module_option.type == list:
if not has_key(kwargs, name):
kwargs[name] = []
kwargs[name].append(value)
else:
kwargs[name] = value
else:
raise Exception("binwalk.module.argv: %s has no attribute 'CLI'" % str(module))
if self.config is not None and not has_key(kwargs, 'config'):
kwargs['config'] = self.config
# If some command line arguments for this module were parsed, then set it to enabled.
# Else, disable it by default.
if kwargs:
kwargs['enabled'] = True
else:
kwargs['enabled'] = False
return kwargs
def kwargs(self, module, kwargs):
'''
Processes a module's kwargs. All modules should use this for kwarg processing.
@module - An instance of the module (e.g., self)
@kwargs - The kwargs passed to the module
Returns None.
'''
if hasattr(module, "KWARGS"):
for module_argument in module.KWARGS:
if has_key(kwargs, module_argument.name):
arg_value = kwargs[module_argument.name]
else:
arg_value = module_argument.default
setattr(module, module_argument.name, arg_value)
if has_key(kwargs, 'config'):
setattr(module, 'config', kwargs['config'])
else:
raise Exception("binwalk.module.process_kwargs: %s has no attribute 'KWARGS'" % str(module))
from configuration import Configuration
from hashmatch import HashFile, HashFiles, HashDirectories
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment