Commit f23e83b7 by devttys0

Initial code for signature.py plugin added.

parent 27a8a4d6
......@@ -100,9 +100,9 @@ class Error(Result):
Result.__init__(self, **kwargs)
if self.exception:
sys.stderr.write(str(self.exception) + "\n")
sys.stderr.write("Exception: " + str(self.exception) + "\n")
elif self.description:
sys.stderr.write(self.description + "\n")
sys.stderr.write("Error: " + self.description + "\n")
class Module(object):
'''
......@@ -137,8 +137,22 @@ class Module(object):
def __init__(self, **kwargs):
# TODO: Instantiate plugins object
# self.plugins = x
self.errors = []
self.results = []
process_kwargs(self, kwargs)
try:
self.load()
except KeyboardInterrupt as e:
raise e
except Exception as e:
self.error(exception=e)
def load(self):
'''
Invoked at module load time.
May be overridden by the module sub-class.
'''
return None
def init(self):
'''
......@@ -225,8 +239,16 @@ class Module(object):
'''
e = Error(**kwargs)
self.errors.append(e)
if e.exception:
raise e.exception
def header(self):
self.config.display.format_strings(self.HEADER_FORMAT, self.RESULT_FORMAT)
if type(self.HEADER) == type([]):
self.config.display.header(*self.HEADER)
elif self.HEADER:
self.config.display.header(self.HEADER)
def footer(self):
self.config.display.footer()
def main(self):
'''
......@@ -242,12 +264,7 @@ class Module(object):
self.error(exception=e)
return False
self.config.display.format_strings(self.HEADER_FORMAT, self.RESULT_FORMAT)
if type(self.HEADER) == type([]):
self.config.display.header(*self.HEADER)
elif self.HEADER:
self.config.display.header(self.HEADER)
self.header()
self._plugins_pre_scan()
try:
......@@ -259,8 +276,8 @@ class Module(object):
return False
self._plugins_post_scan()
self.footer()
self.config.display.footer()
return retval
class Modules(object):
......@@ -277,13 +294,18 @@ class Modules(object):
Returns None.
'''
self.ok = True
self.config = None
self.argv = argv
self.arguments = argv
self.dependency_results = {}
if not dummy:
from binwalk.modules.configuration import Configuration
self.config = self.load(Configuration)
for e in self.config.errors:
if e.exception:
self.ok = False
break
def list(self, attribute="run"):
'''
......@@ -337,26 +359,31 @@ class Modules(object):
return run_modules
def run(self, module):
retval = False
obj = self.load(module)
if obj.enabled:
if isinstance(obj, Module) and obj.enabled:
try:
retval = obj.main()
obj.main()
except AttributeError as e:
print("WARNING:", e)
sys.stderr.write("WARNING: " + str(e) + "\n")
obj = None
else:
obj = None
return retval
return obj
def load(self, module):
kwargs = self.argv(module, argv=self.argv)
if self.ok:
kwargs = self.argv(module, argv=self.arguments)
kwargs.update(self.dependencies(module))
return module(**kwargs)
else:
return None
def dependencies(self, module):
kwargs = {}
if hasattr(module, "DEPENDS"):
if self.ok and hasattr(module, "DEPENDS"):
# Disable output when modules are loaded as dependencies
orig_log = self.config.display.log
orig_quiet = self.config.display.quiet
......@@ -365,8 +392,7 @@ class Modules(object):
for (kwarg, mod) in iterator(module.DEPENDS):
if not has_key(self.dependency_results, mod):
self.dependency_results[mod] = self.load(mod)
self.dependency_results[mod].main()
self.dependency_results[mod] = self.run(mod)
kwargs[kwarg] = self.dependency_results[mod]
self.config.display.log = orig_log
......@@ -449,6 +475,8 @@ class Modules(object):
if self.config is not None and not has_key(kwargs, 'config'):
kwargs['config'] = self.config
if not has_key(kwargs, 'enabled'):
kwargs['enabled'] = False
return kwargs
......@@ -473,9 +501,6 @@ class Modules(object):
for (k, v) in iterator(kwargs):
if not hasattr(module, k):
setattr(module, k, v)
if not hasattr(module, 'enabled'):
setattr(module, 'enabled', False)
else:
raise Exception("binwalk.module.Modules.process_kwargs: %s has no attribute 'KWARGS'" % str(module))
......@@ -489,7 +514,7 @@ def process_kwargs(obj, kwargs):
Returns None.
'''
return Modules(dummy=True).kwargs(module, kwargs)
return Modules(dummy=True).kwargs(obj, kwargs)
def show_help(fd=sys.stdout):
'''
......
......@@ -2,3 +2,4 @@ from configuration import Configuration
from hashmatch import HashMatch
from binvis import Plotter
from hexdiff import HexDiff
from signature import Signature
......@@ -8,6 +8,7 @@ from binwalk.compat import *
class Configuration(binwalk.module.Module):
RUN = False
NAME = "General"
CLI = [
binwalk.module.ModuleOption(long='length',
......@@ -83,10 +84,14 @@ class Configuration(binwalk.module.Module):
binwalk.module.ModuleKwarg(name='do_update', default=False),
]
def __init__(self, **kwargs):
def load(self):
self.target_files = []
binwalk.module.process_kwargs(self, kwargs)
self.display = binwalk.display.Display(log=self.log_file,
csv=self.csv,
quiet=self.quiet,
verbose=self.verbose,
fit_to_screen=self.format_to_terminal)
if self.show_help:
binwalk.module.show_help()
......@@ -99,12 +104,6 @@ class Configuration(binwalk.module.Module):
self._open_target_files()
self._set_verbosity()
self.display = binwalk.display.Display(log=self.log_file,
csv=self.csv,
quiet=self.quiet,
verbose=self.verbose,
fit_to_screen=self.format_to_terminal)
def __del__(self):
self._cleanup()
......@@ -145,7 +144,7 @@ class Configuration(binwalk.module.Module):
except KeyboardInterrupt as e:
raise e
except Exception as e:
self.error(description="Cannot open file : %s\n" % str(e))
self.error(description="Cannot open file : %s" % str(e))
# Unless -O was specified, don't run the scan unless we are able to scan all specified files
if len(self.target_files) != len(self.files) and not self.skip_unopened:
......
import magic
import binwalk.config
import binwalk.module
import binwalk.parser
import binwalk.filter
import binwalk.smartsignature
from binwalk.compat import *
class Signature(binwalk.module.Module):
CLI = [
binwalk.module.ModuleOption(short='B',
long='signature',
kwargs={'enabled' : True}),
]
KWARGS = [
binwalk.module.ModuleKwarg(name='enabled', default=False),
binwalk.module.ModuleKwarg(name='magic_files', default=[]),
]
HEADER="BINWALK"
HEADER_FORMAT="%s\n"
RESULT=["offset", "offset", "description"]
RESULT_FORMAT="%d 0x%X %s\n"
MAGIC_FLAGS = magic.MAGIC_NO_CHECK_TEXT | magic.MAGIC_NO_CHECK_ENCODING | magic.MAGIC_NO_CHECK_APPTYPE | magic.MAGIC_NO_CHECK_TOKENS
def init(self):
# Instantiate the config class so we can access file/directory paths
self.conf = binwalk.config.Config()
# Create SmartSignature and MagicParser class instances. These are mostly for internal use.
self.filter = binwalk.filter.MagicFilter()
self.smart = binwalk.smartsignature.SmartSignature(self.filter, ignore_smart_signatures=False)
self.parser = binwalk.parser.MagicParser(self.filter, self.smart)
# Use the system default magic file if no other was specified
if not self.magic_files or self.magic_files is None:
# Append the user's magic file first so that those signatures take precedence
self.magic_files = [
self.conf.paths['user'][self.conf.BINWALK_MAGIC_FILE],
self.conf.paths['system'][self.conf.BINWALK_MAGIC_FILE],
]
# Parse the magic file(s) and initialize libmagic
self.mfile = self.parser.parse(self.magic_files)
self.magic = magic.open(self.MAGIC_FLAGS)
self.magic.load(str2bytes(self.mfile))
# Once the temporary magic file is loaded into libmagic, we don't need it anymore; delete the temp file
self.parser.rm_magic_file()
def scan_file(self, fp):
data = fp.read()
for candidate in self.parser.find_signature_candidates(data, len(data)):
# In python3 we need a bytes object to pass to magic.buffer
candidate_data = str2bytes(data[candidate:candidate+fp.MAX_TRAILING_SIZE])
# Pass the data to libmagic, and split out multiple results into a list
for magic_result in self.parser.split(self.magic.buffer(candidate_data)):
if not self.filter.invalid(magic_result):
# The smart filter parser returns a dictionary of keyword values and the signature description.
smart = self.smart.parse(magic_result)
self.result(description=smart['description'], offset=candidate)
def run(self):
for fp in self.config.target_files:
self.scan_file(fp)
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