Commit e9d9055a by devttys0

Restructured binwalk directory

parent 659126cb
from binwalk.module import Modules from binwalk.core.module import Modules
# Contains all the command line options and usage output for the binwlak script.
# Placed here so that other scripts can programmatically access the command line options list (e.g., for auto-completion generation).
import os
import sys
import binwalk.config
short_options = "23AaBbCcdEeGHhIiJkLMNnOPpQqrSTtUuVvWwz?D:F:f:g:j:K:o:l:m:R:s:X:x:Y:y:Z:"
long_options = [
"2D",
"3D",
"3d",
"rm",
"help",
"green",
"red",
"blue",
"rehash",
"examples",
"quiet",
"csv",
"verbose",
"opcodes",
"cast",
"update",
"binwalk",
"keep-going",
"show-invalid",
"show-grids",
"ignore-time-skew",
"honor-footers",
"profile",
"delay", # delay is depreciated, but kept for backwards compatability
"skip-unopened",
"term",
"tim",
"terse",
"diff",
"dumb",
"entropy",
"heuristic",
"math",
"gzip",
"save-plot",
"no-plot",
"no-legend",
"strings",
"carve",
"max-points=",
"matryoshka=",
"list-plugins",
"disable-plugins",
"disable-plugin=",
"enable-plugin=",
"max-size=",
"marker=",
"strlen=",
"file=",
"block=",
"offset=",
"length=",
"exclude=",
"include=",
"search=",
"extract=",
"dd=",
"grep=",
"magic=",
"raw-bytes=",
]
def usage(fd):
fd.write("\n")
fd.write("Binwalk v%s\n" % binwalk.config.Config.VERSION)
fd.write("Craig Heffner, http://www.devttys0.com\n")
fd.write("\n")
fd.write("Usage: %s [OPTIONS] [FILE1] [FILE2] [FILE3] ...\n" % os.path.basename(sys.argv[0]))
fd.write("\n")
fd.write("Signature Analysis:\n")
fd.write("\t-B, --binwalk Perform a file signature scan (default)\n")
fd.write("\t-R, --raw-bytes=<string> Search for a custom signature\n")
fd.write("\t-A, --opcodes Scan for executable code signatures\n")
fd.write("\t-C, --cast Cast file contents as various data types\n")
fd.write("\t-m, --magic=<file> Specify an alternate magic file to use\n")
fd.write("\t-x, --exclude=<filter> Exclude matches that have <filter> in their description\n")
fd.write("\t-y, --include=<filter> Only search for matches that have <filter> in their description\n")
fd.write("\t-I, --show-invalid Show results marked as invalid\n")
fd.write("\t-T, --ignore-time-skew Do not show results that have timestamps more than 1 year in the future\n")
fd.write("\t-k, --keep-going Show all matching results at a given offset, not just the first one\n")
fd.write("\t-b, --dumb Disable smart signature keywords\n")
fd.write("\n")
fd.write("Strings Analysis:\n")
fd.write("\t-S, --strings Scan for ASCII strings (may be combined with -B, -R, -A, or -E)\n")
fd.write("\t-s, --strlen=<n> Set the minimum string length to search for (default: 3)\n")
fd.write("\n")
fd.write("Entropy Analysis:\n")
fd.write("\t-E, --entropy Plot file entropy (may be combined with -B, -R, -A, or -S)\n")
fd.write("\t-H, --heuristic Identify unknown compression/encryption based on entropy heuristics (implies -E)\n")
fd.write("\t-K, --block=<int> Set the block size for entropy analysis (default: %d)\n" % binwalk.entropy.FileEntropy.DEFAULT_BLOCK_SIZE)
fd.write("\t-a, --gzip Use gzip compression ratios to measure entropy\n")
fd.write("\t-N, --no-plot Do not generate an entropy plot graph\n")
fd.write("\t-F, --marker=<offset:name> Add a marker to the entropy plot graph\n")
fd.write("\t-Q, --no-legend Omit the legend from the entropy plot graph\n")
fd.write("\t-J, --save-plot Save plot as a PNG (implied if multiple files are specified)\n")
fd.write("\n")
fd.write("Binary Visualization:\n")
fd.write("\t-3, --3D Generate a 3D binary visualization\n")
fd.write("\t-2, --2D Project data points onto 3D cube walls only\n")
fd.write("\t-Z, --max-points Set the maximum number of plotted data points (defulat: %d)\n" % binwalk.plotter.Plotter.MAX_PLOT_POINTS)
fd.write("\t-V, --show-grids Display the x-y-z grids in the resulting plot\n")
fd.write("\n")
fd.write("Binary Diffing:\n")
fd.write("\t-W, --diff Hexdump / diff the specified files\n")
fd.write("\t-K, --block=<int> Number of bytes to display per line (default: %d)\n" % binwalk.hexdiff.HexDiff.DEFAULT_BLOCK_SIZE)
fd.write("\t-G, --green Only show hex dump lines that contain bytes which were the same in all files\n")
fd.write("\t-i, --red Only show hex dump lines that contain bytes which were different in all files\n")
fd.write("\t-U, --blue Only show hex dump lines that contain bytes which were different in some files\n")
fd.write("\t-w, --terse Diff all files, but only display a hex dump of the first file\n")
fd.write("\n")
fd.write("Extraction Options:\n")
fd.write("\t-D, --dd=<type:ext:cmd> Extract <type> signatures, give the files an extension of <ext>, and execute <cmd>\n")
fd.write("\t-e, --extract=[file] Automatically extract known file types; load rules from file, if specified\n")
fd.write("\t-M, --matryoshka=[n] Recursively scan extracted files, up to n levels deep (8 levels of recursion is the default)\n")
fd.write("\t-j, --max-size=<int> Limit extracted file sizes (default: no limit)\n")
fd.write("\t-r, --rm Cleanup extracted files and zero-size files\n")
fd.write("\t-d, --honor-footers Only extract files up to their corresponding footer signatures\n")
fd.write("\t-z, --carve Carve data from files, but don't execute extraction utilities (implies -d)\n")
fd.write("\t-P, --rehash Recursively diff data extracted from FILE1 with the data extracted from all other files.\n")
fd.write("\n")
fd.write("Plugin Options:\n")
fd.write("\t-X, --disable-plugin=<name> Disable a plugin by name\n")
fd.write("\t-Y, --enable-plugin=<name> Enable a plugin by name\n")
fd.write("\t-p, --disable-plugins Do not load any binwalk plugins\n")
fd.write("\t-L, --list-plugins List all user and system plugins by name\n")
fd.write("\n")
fd.write("General Options:\n")
fd.write("\t-o, --offset=<int> Start scan at this file offset\n")
fd.write("\t-l, --length=<int> Number of bytes to scan\n")
fd.write("\t-g, --grep=<text> Grep results for the specified text\n")
fd.write("\t-f, --file=<file> Log results to file\n")
fd.write("\t-c, --csv Log results to file in csv format\n")
fd.write("\t-O, --skip-unopened Ignore file open errors and process only the files that can be opened\n")
fd.write("\t-t, --term Format output to fit the terminal window\n")
fd.write("\t-q, --quiet Suppress output to stdout\n")
fd.write("\t-v, --verbose Be verbose (specify twice for very verbose)\n")
fd.write("\t-u, --update Update magic signature files\n")
fd.write("\t-?, --examples Show example usage\n")
fd.write("\t-h, --help Show help output\n")
fd.write("\n")
if fd == sys.stderr:
sys.exit(1)
else:
sys.exit(0)
#!/usr/bin/env python
# Routines to perform Monte Carlo Pi approximation and Chi Squared tests.
# Used for fingerprinting unknown areas of high entropy (e.g., is this block of high entropy data compressed or encrypted?).
# Inspired by people who actually know what they're doing: http://www.fourmilab.ch/random/
import math
import binwalk.common as common
from binwalk.compat import *
class MonteCarloPi(object):
'''
Performs a Monte Carlo Pi approximation.
Currently unused.
'''
def __init__(self):
'''
Class constructor.
Returns None.
'''
self.reset()
def reset(self):
'''
Reset state to the beginning.
'''
self.pi = 0
self.error = 0
self.m = 0
self.n = 0
def update(self, data):
'''
Update the pi approximation with new data.
@data - A string of bytes to update (length must be >= 6).
Returns None.
'''
c = 0
dlen = len(data)
while (c+6) < dlen:
# Treat 3 bytes as an x coordinate, the next 3 bytes as a y coordinate.
# Our box is 1x1, so divide by 2^24 to put the x y values inside the box.
x = ((ord(data[c]) << 16) + (ord(data[c+1]) << 8) + ord(data[c+2])) / 16777216.0
c += 3
y = ((ord(data[c]) << 16) + (ord(data[c+1]) << 8) + ord(data[c+2])) / 16777216.0
c += 3
# Does the x,y point lie inside the circle inscribed within our box, with diameter == 1?
if ((x**2) + (y**2)) <= 1:
self.m += 1
self.n += 1
def montecarlo(self):
'''
Approximates the value of Pi based on the provided data.
Returns a tuple of (approximated value of pi, percent deviation).
'''
if self.n:
self.pi = (float(self.m) / float(self.n) * 4.0)
if self.pi:
self.error = math.fabs(1.0 - (math.pi / self.pi)) * 100.0
return (self.pi, self.error)
else:
return (0.0, 0.0)
class ChiSquare(object):
'''
Performs a Chi Squared test against the provided data.
'''
IDEAL = 256.0
def __init__(self):
'''
Class constructor.
Returns None.
'''
self.bytes = {}
self.freedom = self.IDEAL - 1
# Initialize the self.bytes dictionary with keys for all possible byte values (0 - 255)
for i in range(0, int(self.IDEAL)):
self.bytes[chr(i)] = 0
self.reset()
def reset(self):
self.xc2 = 0.0
self.byte_count = 0
for key in self.bytes.keys():
self.bytes[key] = 0
def update(self, data):
'''
Updates the current byte counts with new data.
@data - String of bytes to update.
Returns None.
'''
# Count the number of occurances of each byte value
for i in data:
self.bytes[i] += 1
self.byte_count += len(data)
def chisq(self):
'''
Calculate the Chi Square critical value.
Returns the critical value.
'''
expected = self.byte_count / self.IDEAL
if expected:
for byte in self.bytes.values():
self.xc2 += ((byte - expected) ** 2 ) / expected
return self.xc2
class CompressionEntropyAnalyzer(object):
'''
Class wrapper around ChiSquare.
Performs analysis and attempts to interpret the results.
'''
BLOCK_SIZE = 32
CHI_CUTOFF = 512
DESCRIPTION = "Statistical Compression Analysis"
def __init__(self, fname, start, length, binwalk=None):
'''
Class constructor.
@fname - The file to scan.
@start - The start offset to begin analysis at.
@length - The number of bytes to analyze.
@binwalk - Binwalk class object.
Returns None.
'''
self.fp = common.BlockFile(fname, 'r', offset=start, length=length)
# Read block size must be at least as large as our analysis block size
if self.fp.READ_BLOCK_SIZE < self.BLOCK_SIZE:
self.fp.READ_BLOCK_SIZE = self.BLOCK_SIZE
self.start = self.fp.offset
self.length = length
self.binwalk = binwalk
def __del__(self):
try:
self.fp.close()
except KeyboardInterrupt as e:
raise e
except Exception:
pass
def analyze(self):
'''
Perform analysis and interpretation.
Returns a descriptive string containing the results and attempted interpretation.
'''
i = 0
num_error = 0
analyzer_results = []
if self.binwalk:
self.binwalk.display.header(file_name=self.fp.name, description=self.DESCRIPTION)
chi = ChiSquare()
while i < self.length:
j = 0
(d, dlen) = self.fp.read_block()
while j < dlen:
chi.reset()
data = d[j:j+self.BLOCK_SIZE]
if len(data) < self.BLOCK_SIZE:
break
chi.update(data)
if chi.chisq() >= self.CHI_CUTOFF:
num_error += 1
j += self.BLOCK_SIZE
i += dlen
if num_error > 0:
verdict = 'Moderate entropy data, best guess: compressed'
else:
verdict = 'High entropy data, best guess: encrypted'
result = [{'offset' : self.start, 'description' : '%s, size: %d, %d low entropy blocks' % (verdict, self.length, num_error)}]
if self.binwalk:
self.binwalk.display.results(self.start, result)
self.binwalk.display.footer()
return result
...@@ -5,7 +5,7 @@ import re ...@@ -5,7 +5,7 @@ import re
import ast import ast
import hashlib import hashlib
import operator as op import operator as op
from binwalk.compat import * from binwalk.core.compat import *
# This allows other modules/scripts to subclass BlockFile from a custom class. Defaults to io.FileIO. # This allows other modules/scripts to subclass BlockFile from a custom class. Defaults to io.FileIO.
if has_key(__builtins__, 'BLOCK_FILE_PARENT_CLASS'): if has_key(__builtins__, 'BLOCK_FILE_PARENT_CLASS'):
......
import os import os
import binwalk.common as common import binwalk.core.common as common
from binwalk.compat import * from binwalk.core.compat import *
class Config: class Config:
''' '''
...@@ -117,7 +117,7 @@ class Config: ...@@ -117,7 +117,7 @@ class Config:
root = __file__ root = __file__
if os.path.islink(root): if os.path.islink(root):
root = os.path.realpath(root) root = os.path.realpath(root)
return os.path.dirname(os.path.abspath(root)) return os.path.dirname(os.path.dirname(os.path.abspath(root)))
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception: except Exception:
......
import re import re
import binwalk.common as common import binwalk.core.common as common
from binwalk.smartsignature import SmartSignature from binwalk.core.smartsignature import SmartSignature
from binwalk.compat import * from binwalk.core.compat import *
class MagicFilter: class MagicFilter:
''' '''
......
...@@ -3,12 +3,12 @@ import os ...@@ -3,12 +3,12 @@ import os
import sys import sys
import inspect import inspect
import argparse import argparse
import binwalk.common import binwalk.core.common
import binwalk.config import binwalk.core.config
import binwalk.plugin import binwalk.core.plugin
from binwalk.compat import * from binwalk.core.compat import *
class ModuleOption(object): class Option(object):
''' '''
A container class that allows modules to declare command line options. A container class that allows modules to declare command line options.
''' '''
...@@ -22,7 +22,7 @@ class ModuleOption(object): ...@@ -22,7 +22,7 @@ class ModuleOption(object):
@description - A description to be displayed in the help output. @description - A description to be displayed in the help output.
@short - The short option to use (optional). @short - The short option to use (optional).
@long - The long option to use (if None, this option will not be displayed in help output). @long - The long option to use (if None, this option will not be displayed in help output).
@type - The accepted data type (one of: io.FileIO/argparse.FileType/binwalk.common.BlockFile, list, str, int, float). @type - The accepted data type (one of: io.FileIO/argparse.FileType/binwalk.core.common.BlockFile, list, str, int, float).
@dtype - The displayed accepted type string, to be shown in help output. @dtype - The displayed accepted type string, to be shown in help output.
Returns None. Returns None.
...@@ -36,14 +36,14 @@ class ModuleOption(object): ...@@ -36,14 +36,14 @@ class ModuleOption(object):
self.dtype = str(dtype) self.dtype = str(dtype)
if not self.dtype: if not self.dtype:
if self.type in [io.FileIO, argparse.FileType, binwalk.common.BlockFile]: if self.type in [io.FileIO, argparse.FileType, binwalk.core.common.BlockFile]:
self.dtype = 'file' self.dtype = 'file'
elif self.type in [int, float, str]: elif self.type in [int, float, str]:
self.dtype = self.type.__name__ self.dtype = self.type.__name__
else: else:
self.dtype = str.__name__ self.dtype = str.__name__
class ModuleKwarg(object): class Kwarg(object):
''' '''
A container class allowing modules to specify their expected __init__ kwarg(s). A container class allowing modules to specify their expected __init__ kwarg(s).
''' '''
...@@ -93,12 +93,12 @@ class Result(object): ...@@ -93,12 +93,12 @@ class Result(object):
class Error(Result): class Error(Result):
''' '''
A subclass of binwalk.module.Result. A subclass of binwalk.core.module.Result.
''' '''
def __init__(self, **kwargs): def __init__(self, **kwargs):
''' '''
Accepts all the same kwargs as binwalk.module.Result, but the following are also added: Accepts all the same kwargs as binwalk.core.module.Result, but the following are also added:
@exception - In case of an exception, this is the exception object. @exception - In case of an exception, this is the exception object.
...@@ -114,13 +114,13 @@ class Module(object): ...@@ -114,13 +114,13 @@ class Module(object):
# The module title, as displayed in help output # The module title, as displayed in help output
TITLE = "" TITLE = ""
# A list of binwalk.module.ModuleOption command line options # A list of binwalk.core.module.ModuleOption command line options
CLI = [] CLI = []
# A list of binwalk.module.ModuleKwargs accepted by __init__ # A list of binwalk.core.module.ModuleKwargs accepted by __init__
KWARGS = [] KWARGS = []
# A dictionary of module dependencies; all modules depend on binwalk.modules.configuration.Configuration # A dictionary of module dependencies; all modules depend on binwalk.core.modules.configuration.Configuration
DEPENDS = {'config' : 'Configuration', 'extractor' : 'Extractor'} DEPENDS = {'config' : 'Configuration', 'extractor' : 'Extractor'}
# Format string for printing the header during a scan # Format string for printing the header during a scan
...@@ -144,7 +144,7 @@ class Module(object): ...@@ -144,7 +144,7 @@ class Module(object):
self.results = [] self.results = []
self.status = None self.status = None
self.name = self.__class__.__name__ self.name = self.__class__.__name__
self.plugins = binwalk.plugin.Plugins(self) self.plugins = binwalk.core.plugin.Plugins(self)
process_kwargs(self, kwargs) process_kwargs(self, kwargs)
...@@ -187,11 +187,11 @@ class Module(object): ...@@ -187,11 +187,11 @@ class Module(object):
''' '''
return False return False
def process_result(self, r): def callback(self, r):
''' '''
Processes the result. Passed to all dependency modules when a valid result is found. Processes the result from all modules. Called for all dependency modules when a valid result is found.
@r - The result, an instance of binwalk.module.Result. @r - The result, an instance of binwalk.core.module.Result.
Returns None. Returns None.
''' '''
...@@ -202,7 +202,7 @@ class Module(object): ...@@ -202,7 +202,7 @@ class Module(object):
Validates the result. Validates the result.
May be overridden by the module sub-class. May be overridden by the module sub-class.
@r - The result, an instance of binwalk.module.Result. @r - The result, an instance of binwalk.core.module.Result.
Returns None. Returns None.
''' '''
...@@ -235,9 +235,9 @@ class Module(object): ...@@ -235,9 +235,9 @@ class Module(object):
def result(self, r=None, **kwargs): def result(self, r=None, **kwargs):
''' '''
Validates a result, stores it in self.results and prints it. Validates a result, stores it in self.results and prints it.
Accepts the same kwargs as the binwalk.module.Result class. Accepts the same kwargs as the binwalk.core.module.Result class.
@r - An existing instance of binwalk.module.Result. @r - An existing instance of binwalk.core.module.Result.
Returns None. Returns None.
''' '''
...@@ -245,13 +245,14 @@ class Module(object): ...@@ -245,13 +245,14 @@ class Module(object):
r = Result(**kwargs) r = Result(**kwargs)
self.validate(r) self.validate(r)
self._plugins_result(r)
if r.valid:
for (attribute, module) in iterator(self.DEPENDS): for (attribute, module) in iterator(self.DEPENDS):
dependency = getattr(self, attribute) dependency = getattr(self, attribute)
dependency.process_result(r) dependency.callback(r)
self._plugins_result(r)
if r.valid:
self.results.append(r) self.results.append(r)
# Update the progress status automatically if it is not being done manually by the module # Update the progress status automatically if it is not being done manually by the module
...@@ -268,7 +269,7 @@ class Module(object): ...@@ -268,7 +269,7 @@ class Module(object):
''' '''
Stores the specified error in self.errors. Stores the specified error in self.errors.
Accepts the same kwargs as the binwalk.module.Error class. Accepts the same kwargs as the binwalk.core.module.Error class.
Returns None. Returns None.
''' '''
...@@ -331,6 +332,9 @@ class Module(object): ...@@ -331,6 +332,9 @@ class Module(object):
return retval return retval
class Status(object): class Status(object):
'''
Class used for tracking module status (e.g., % complete).
'''
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.kwargs = kwargs self.kwargs = kwargs
...@@ -391,17 +395,17 @@ class Modules(object): ...@@ -391,17 +395,17 @@ class Modules(object):
Returns a list of modules that contain the specified attribute. Returns a list of modules that contain the specified attribute.
''' '''
import binwalk.modules import binwalk.core.modules
modules = [] modules = []
for (name, module) in inspect.getmembers(binwalk.modules): for (name, module) in inspect.getmembers(binwalk.core.modules):
if inspect.isclass(module) and hasattr(module, attribute): if inspect.isclass(module) and hasattr(module, attribute):
modules.append(module) modules.append(module)
return modules return modules
def help(self): def help(self):
help_string = "\nBinwalk v%s\nCraig Heffner, http://www.binwalk.org\n" % binwalk.config.Config.VERSION help_string = "\nBinwalk v%s\nCraig Heffner, http://www.binwalk.core.org\n" % binwalk.core.config.Config.VERSION
for obj in self.list(attribute="CLI"): for obj in self.list(attribute="CLI"):
if obj.CLI: if obj.CLI:
...@@ -449,7 +453,7 @@ class Modules(object): ...@@ -449,7 +453,7 @@ class Modules(object):
def run(self, module): def run(self, module):
obj = self.load(module) obj = self.load(module)
if isinstance(obj, binwalk.module.Module) and obj.enabled: if isinstance(obj, binwalk.core.module.Module) and obj.enabled:
obj.main(status=self.status) obj.main(status=self.status)
self.status.clear() self.status.clear()
...@@ -465,17 +469,17 @@ class Modules(object): ...@@ -465,17 +469,17 @@ class Modules(object):
return module(**kwargs) return module(**kwargs)
def dependencies(self, module): def dependencies(self, module):
import binwalk.modules import binwalk.core.modules
kwargs = {} kwargs = {}
if hasattr(module, "DEPENDS"): if hasattr(module, "DEPENDS"):
for (kwarg, dependency) in iterator(module.DEPENDS): for (kwarg, dependency) in iterator(module.DEPENDS):
# The dependency module must be imported by binwalk.modules.__init__.py # The dependency module must be imported by binwalk.core.modules.__init__.py
if hasattr(binwalk.modules, dependency): if hasattr(binwalk.core.modules, dependency):
dependency = getattr(binwalk.modules, dependency) dependency = getattr(binwalk.core.modules, dependency)
else: else:
sys.stderr.write("WARNING: %s depends on %s which was not found in binwalk.modules.__init__.py\n" % (str(module), dependency)) sys.stderr.write("WARNING: %s depends on %s which was not found in binwalk.core.modules.__init__.py\n" % (str(module), dependency))
continue continue
# No recursive dependencies, thanks # No recursive dependencies, thanks
...@@ -530,7 +534,7 @@ class Modules(object): ...@@ -530,7 +534,7 @@ class Modules(object):
# Only add parsed options pertinent to the requested module # Only add parsed options pertinent to the requested module
for module_option in module.CLI: for module_option in module.CLI:
if module_option.type == binwalk.common.BlockFile: if module_option.type == binwalk.core.common.BlockFile:
for k in get_keys(module_option.kwargs): for k in get_keys(module_option.kwargs):
kwargs[k] = [] kwargs[k] = []
...@@ -590,14 +594,14 @@ class Modules(object): ...@@ -590,14 +594,14 @@ class Modules(object):
if not hasattr(module, k): if not hasattr(module, k):
setattr(module, k, v) setattr(module, k, v)
else: else:
raise Exception("binwalk.module.Modules.process_kwargs: %s has no attribute 'KWARGS'" % str(module)) raise Exception("binwalk.core.module.Modules.process_kwargs: %s has no attribute 'KWARGS'" % str(module))
def process_kwargs(obj, kwargs): def process_kwargs(obj, kwargs):
''' '''
Convenience wrapper around binwalk.module.Modules.kwargs. Convenience wrapper around binwalk.core.module.Modules.kwargs.
@obj - The class object (an instance of a sub-class of binwalk.module.Module). @obj - The class object (an instance of a sub-class of binwalk.core.module.Module).
@kwargs - The kwargs provided to the object's __init__ method. @kwargs - The kwargs provided to the object's __init__ method.
Returns None. Returns None.
...@@ -606,7 +610,7 @@ def process_kwargs(obj, kwargs): ...@@ -606,7 +610,7 @@ def process_kwargs(obj, kwargs):
def show_help(fd=sys.stdout): def show_help(fd=sys.stdout):
''' '''
Convenience wrapper around binwalk.module.Modules.help. Convenience wrapper around binwalk.core.module.Modules.help.
@fd - An object with a write method (e.g., sys.stdout, sys.stderr, etc). @fd - An object with a write method (e.g., sys.stdout, sys.stderr, etc).
......
...@@ -2,8 +2,8 @@ import io ...@@ -2,8 +2,8 @@ import io
import re import re
import os.path import os.path
import tempfile import tempfile
from binwalk.compat import * from binwalk.core.compat import *
from binwalk.common import str2int from binwalk.core.common import str2int
class MagicParser: class MagicParser:
''' '''
......
import os import os
import sys import sys
import imp import imp
import binwalk.config import binwalk.core.config
from binwalk.compat import * from binwalk.core.compat import *
class Plugins: class Plugins:
''' '''
...@@ -54,7 +54,7 @@ class Plugins: ...@@ -54,7 +54,7 @@ class Plugins:
self.pre_scan = [] self.pre_scan = []
self.post_scan = [] self.post_scan = []
self.parent = parent self.parent = parent
self.config = binwalk.config.Config() self.config = binwalk.core.config.Config()
def __del__(self): def __del__(self):
pass pass
......
import re import re
import binwalk.module import binwalk.core.module
from binwalk.compat import * from binwalk.core.compat import *
from binwalk.common import str2int, get_quoted_strings, MathExpression from binwalk.core.common import str2int, get_quoted_strings, MathExpression
class SmartSignature: class SmartSignature:
''' '''
...@@ -127,7 +127,7 @@ class SmartSignature: ...@@ -127,7 +127,7 @@ class SmartSignature:
results['valid'] = self.valid results['valid'] = self.valid
return binwalk.module.Result(**results) return binwalk.core.module.Result(**results)
def _is_valid(self, data): def _is_valid(self, data):
''' '''
......
from signature import Signature from binwalk.modules.signature import Signature
from binvis import Plotter from binwalk.modules.binvis import Plotter
from hexdiff import HexDiff from binwalk.modules.hexdiff import HexDiff
from hashmatch import HashMatch from binwalk.modules.hashmatch import HashMatch
from configuration import Configuration from binwalk.modules.configuration import Configuration
from extractor import Extractor from binwalk.modules.extractor import Extractor
import os import os
import binwalk.module from binwalk.core.compat import *
from binwalk.compat import * from binwalk.core.common import BlockFile
from binwalk.common import BlockFile from binwalk.core.module import Module, Option, Kwarg
class Plotter(binwalk.module.Module): class Plotter(Module):
''' '''
Base class for visualizing binaries in Qt. Base class for visualizing binaries in Qt.
Other plotter classes are derived from this. Other plotter classes are derived from this.
...@@ -15,29 +15,29 @@ class Plotter(binwalk.module.Module): ...@@ -15,29 +15,29 @@ class Plotter(binwalk.module.Module):
TITLE = "Binary Visualization" TITLE = "Binary Visualization"
CLI = [ CLI = [
binwalk.module.ModuleOption(short='3', Option(short='3',
long='3D', long='3D',
kwargs={'axis' : 3, 'enabled' : True}, kwargs={'axis' : 3, 'enabled' : True},
description='Generate a 3D binary visualization'), description='Generate a 3D binary visualization'),
binwalk.module.ModuleOption(short='2', Option(short='2',
long='2D', long='2D',
kwargs={'axis' : 2, 'enabled' : True}, kwargs={'axis' : 2, 'enabled' : True},
description='Project data points onto 3D cube walls only'), description='Project data points onto 3D cube walls only'),
binwalk.module.ModuleOption(short='Z', Option(short='Z',
long='max-points', long='max-points',
type=int, type=int,
kwargs={'max_points' : 0}, kwargs={'max_points' : 0},
description='Set the maximum number of plotted data points'), description='Set the maximum number of plotted data points'),
binwalk.module.ModuleOption(short='V', Option(short='V',
long='show-grids', long='show-grids',
kwargs={'show_grids' : True}, kwargs={'show_grids' : True},
description='Display the x-y-z grids in the resulting plot'), description='Display the x-y-z grids in the resulting plot'),
] ]
KWARGS = [ KWARGS = [
binwalk.module.ModuleKwarg(name='axis', default=3), Kwarg(name='axis', default=3),
binwalk.module.ModuleKwarg(name='max_points', default=0), Kwarg(name='max_points', default=0),
binwalk.module.ModuleKwarg(name='show_grids', default=False), Kwarg(name='show_grids', default=False),
] ]
# There isn't really any useful data to print to console. Disable header and result output. # There isn't really any useful data to print to console. Disable header and result output.
......
import os import os
import sys import sys
import argparse import argparse
import binwalk.common import binwalk.core.common
import binwalk.module import binwalk.core.config
import binwalk.config import binwalk.core.display
import binwalk.display from binwalk.core.config import *
from binwalk.config import * from binwalk.core.compat import *
from binwalk.compat import * from binwalk.core.module import Module, Option, Kwarg, show_help
class Configuration(binwalk.module.Module): class Configuration():
TITLE = "General" TITLE = "General"
DEPENDS = {} DEPENDS = {}
CLI = [ CLI = [
binwalk.module.ModuleOption(long='length', Option(long='length',
short='l', short='l',
type=int, type=int,
kwargs={'length' : 0}, kwargs={'length' : 0},
description='Number of bytes to scan'), description='Number of bytes to scan'),
binwalk.module.ModuleOption(long='offset', Option(long='offset',
short='o', short='o',
type=int, type=int,
kwargs={'offset' : 0}, kwargs={'offset' : 0},
description='Start scan at this file offset'), description='Start scan at this file offset'),
binwalk.module.ModuleOption(long='block', Option(long='block',
short='K', short='K',
type=int, type=int,
kwargs={'block' : 0}, kwargs={'block' : 0},
description='Set file block size'), description='Set file block size'),
binwalk.module.ModuleOption(long='swap', Option(long='swap',
short='g', short='g',
type=int, type=int,
kwargs={'swap_size' : 0}, kwargs={'swap_size' : 0},
description='Reverse every n bytes before scanning'), description='Reverse every n bytes before scanning'),
binwalk.module.ModuleOption(long='log', Option(long='log',
short='f', short='f',
type=argparse.FileType, type=argparse.FileType,
kwargs={'log_file' : None}, kwargs={'log_file' : None},
description='Log results to file'), description='Log results to file'),
binwalk.module.ModuleOption(long='csv', Option(long='csv',
short='c', short='c',
kwargs={'csv' : True}, kwargs={'csv' : True},
description='Log results to file in CSV format'), description='Log results to file in CSV format'),
binwalk.module.ModuleOption(long='term', Option(long='term',
short='t', short='t',
kwargs={'format_to_terminal' : True}, kwargs={'format_to_terminal' : True},
description='Format output to fit the terminal window'), description='Format output to fit the terminal window'),
binwalk.module.ModuleOption(long='quiet', Option(long='quiet',
short='q', short='q',
kwargs={'quiet' : True}, kwargs={'quiet' : True},
description='Supress output to stdout'), description='Supress output to stdout'),
binwalk.module.ModuleOption(long='verbose', Option(long='verbose',
short='v', short='v',
type=list, type=list,
kwargs={'verbose' : True}, kwargs={'verbose' : True},
description='Enable verbose output (specify twice for more verbosity)'), description='Enable verbose output (specify twice for more verbosity)'),
binwalk.module.ModuleOption(short='h', Option(short='h',
long='help', long='help',
kwargs={'show_help' : True}, kwargs={'show_help' : True},
description='Show help output'), description='Show help output'),
binwalk.module.ModuleOption(long=None, Option(long=None,
short=None, short=None,
type=binwalk.common.BlockFile, type=binwalk.core.common.BlockFile,
kwargs={'files' : []}), kwargs={'files' : []}),
] ]
KWARGS = [ KWARGS = [
binwalk.module.ModuleKwarg(name='length', default=0), Kwarg(name='length', default=0),
binwalk.module.ModuleKwarg(name='offset', default=0), Kwarg(name='offset', default=0),
binwalk.module.ModuleKwarg(name='block', default=0), Kwarg(name='block', default=0),
binwalk.module.ModuleKwarg(name='swap_size', default=0), Kwarg(name='swap_size', default=0),
binwalk.module.ModuleKwarg(name='log_file', default=None), Kwarg(name='log_file', default=None),
binwalk.module.ModuleKwarg(name='csv', default=False), Kwarg(name='csv', default=False),
binwalk.module.ModuleKwarg(name='format_to_terminal', default=False), Kwarg(name='format_to_terminal', default=False),
binwalk.module.ModuleKwarg(name='quiet', default=False), Kwarg(name='quiet', default=False),
binwalk.module.ModuleKwarg(name='verbose', default=[]), Kwarg(name='verbose', default=[]),
binwalk.module.ModuleKwarg(name='files', default=[]), Kwarg(name='files', default=[]),
binwalk.module.ModuleKwarg(name='show_help', default=False), Kwarg(name='show_help', default=False),
] ]
def load(self): def load(self):
...@@ -87,15 +87,15 @@ class Configuration(binwalk.module.Module): ...@@ -87,15 +87,15 @@ class Configuration(binwalk.module.Module):
self._set_verbosity() self._set_verbosity()
self._open_target_files() self._open_target_files()
self.settings = binwalk.config.Config() self.settings = binwalk.core.config.Config()
self.display = binwalk.display.Display(log=self.log_file, self.display = binwalk.core.display.Display(log=self.log_file,
csv=self.csv, csv=self.csv,
quiet=self.quiet, quiet=self.quiet,
verbose=self.verbose, verbose=self.verbose,
fit_to_screen=self.format_to_terminal) fit_to_screen=self.format_to_terminal)
if self.show_help: if self.show_help:
binwalk.module.show_help() show_help()
sys.exit(0) sys.exit(0)
def __del__(self): def __del__(self):
...@@ -134,7 +134,7 @@ class Configuration(binwalk.module.Module): ...@@ -134,7 +134,7 @@ class Configuration(binwalk.module.Module):
if not os.path.isdir(tfile): if not os.path.isdir(tfile):
# Make sure we can open the target files # Make sure we can open the target files
try: try:
fp = binwalk.common.BlockFile(tfile, length=self.length, offset=self.offset, swap=self.swap_size) fp = binwalk.core.common.BlockFile(tfile, length=self.length, offset=self.offset, swap=self.swap_size)
self.target_files.append(fp) self.target_files.append(fp)
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
......
...@@ -4,9 +4,9 @@ import magic ...@@ -4,9 +4,9 @@ import magic
import fnmatch import fnmatch
import ctypes import ctypes
import ctypes.util import ctypes.util
import binwalk.common import binwalk.core.common
import binwalk.module from binwalk.core.compat import *
from binwalk.compat import * from binwalk.core.module import Module, Option, Kwarg
class HashResult(object): class HashResult(object):
''' '''
...@@ -19,7 +19,7 @@ class HashResult(object): ...@@ -19,7 +19,7 @@ class HashResult(object):
self.hash = hash self.hash = hash
self.strings = strings self.strings = strings
class HashMatch(binwalk.module.Module): class HashMatch(Module):
''' '''
Class for fuzzy hash matching of files and directories. Class for fuzzy hash matching of files and directories.
''' '''
...@@ -29,50 +29,50 @@ class HashMatch(binwalk.module.Module): ...@@ -29,50 +29,50 @@ class HashMatch(binwalk.module.Module):
TITLE = "Fuzzy Hash" TITLE = "Fuzzy Hash"
CLI = [ CLI = [
binwalk.module.ModuleOption(short='F', Option(short='F',
long='fuzzy', long='fuzzy',
kwargs={'enabled' : True}, kwargs={'enabled' : True},
description='Perform fuzzy hash matching on files/directories'), description='Perform fuzzy hash matching on files/directories'),
binwalk.module.ModuleOption(short='u', Option(short='u',
long='cutoff', long='cutoff',
priority=100, priority=100,
type=int, type=int,
kwargs={'cutoff' : DEFAULT_CUTOFF}, kwargs={'cutoff' : DEFAULT_CUTOFF},
description='Set the cutoff percentage'), description='Set the cutoff percentage'),
binwalk.module.ModuleOption(short='S', Option(short='S',
long='strings', long='strings',
kwargs={'strings' : True}, kwargs={'strings' : True},
description='Diff strings inside files instead of the entire file'), description='Diff strings inside files instead of the entire file'),
binwalk.module.ModuleOption(short='s', Option(short='s',
long='same', long='same',
kwargs={'same' : True, 'cutoff' : CONSERVATIVE_CUTOFF}, kwargs={'same' : True, 'cutoff' : CONSERVATIVE_CUTOFF},
description='Only show files that are the same'), description='Only show files that are the same'),
binwalk.module.ModuleOption(short='p', Option(short='p',
long='diff', long='diff',
kwargs={'same' : False, 'cutoff' : CONSERVATIVE_CUTOFF}, kwargs={'same' : False, 'cutoff' : CONSERVATIVE_CUTOFF},
description='Only show files that are different'), description='Only show files that are different'),
binwalk.module.ModuleOption(short='n', Option(short='n',
long='name', long='name',
kwargs={'filter_by_name' : True}, kwargs={'filter_by_name' : True},
description='Only compare files whose base names are the same'), description='Only compare files whose base names are the same'),
binwalk.module.ModuleOption(short='L', Option(short='L',
long='symlinks', long='symlinks',
kwargs={'symlinks' : True}, kwargs={'symlinks' : True},
description="Don't ignore symlinks"), description="Don't ignore symlinks"),
] ]
KWARGS = [ KWARGS = [
binwalk.module.ModuleKwarg(name='cutoff', default=DEFAULT_CUTOFF), Kwarg(name='cutoff', default=DEFAULT_CUTOFF),
binwalk.module.ModuleKwarg(name='strings', default=False), Kwarg(name='strings', default=False),
binwalk.module.ModuleKwarg(name='same', default=True), Kwarg(name='same', default=True),
binwalk.module.ModuleKwarg(name='symlinks', default=False), Kwarg(name='symlinks', default=False),
binwalk.module.ModuleKwarg(name='name', default=False), Kwarg(name='name', default=False),
binwalk.module.ModuleKwarg(name='max_results', default=None), Kwarg(name='max_results', default=None),
binwalk.module.ModuleKwarg(name='abspath', default=False), Kwarg(name='abspath', default=False),
binwalk.module.ModuleKwarg(name='matches', default={}), Kwarg(name='matches', default={}),
binwalk.module.ModuleKwarg(name='types', default={}), Kwarg(name='types', default={}),
binwalk.module.ModuleKwarg(name='filter_by_name', default=False), Kwarg(name='filter_by_name', default=False),
binwalk.module.ModuleKwarg(name='symlinks', default=False), Kwarg(name='symlinks', default=False),
] ]
# Requires libfuzzy.so # Requires libfuzzy.so
...@@ -89,21 +89,6 @@ class HashMatch(binwalk.module.Module): ...@@ -89,21 +89,6 @@ class HashMatch(binwalk.module.Module):
RESULT = ["percentage", "description"] RESULT = ["percentage", "description"]
def init(self): def init(self):
'''
Class constructor.
@cutoff - The fuzzy cutoff which determines if files are different or not.
@strings - Only hash strings inside of the file, not the entire file itself.
@same - Set to True to show files that are the same, False to show files that are different.
@symlinks - Set to True to include symbolic link files.
@name - Set to True to only compare files whose base names match.
@max_results - Stop searching after x number of matches.
@abspath - Set to True to display absolute file paths.
@matches - A dictionary of file names to diff.
@types - A dictionary of file types to diff.
Returns None.
'''
self.total = 0 self.total = 0
self.last_file1 = HashResult(None) self.last_file1 = HashResult(None)
self.last_file2 = HashResult(None) self.last_file2 = HashResult(None)
...@@ -118,7 +103,7 @@ class HashMatch(binwalk.module.Module): ...@@ -118,7 +103,7 @@ class HashMatch(binwalk.module.Module):
self.types[k][i] = re.compile(self.types[k][i]) self.types[k][i] = re.compile(self.types[k][i])
def _get_strings(self, fname): def _get_strings(self, fname):
return ''.join(list(binwalk.common.strings(fname, minimum=10))) return ''.join(list(binwalk.core.common.strings(fname, minimum=10)))
def _show_result(self, match, fname): def _show_result(self, match, fname):
if self.abspath: if self.abspath:
......
...@@ -2,12 +2,12 @@ import os ...@@ -2,12 +2,12 @@ import os
import sys import sys
import curses import curses
import platform import platform
import binwalk.module import binwalk.core.common as common
import binwalk.common as common from binwalk.core.compat import *
from binwalk.compat import * from binwalk.core.module import Module, Option, Kwarg
# TODO: This code is an effing mess. # TODO: This code is an effing mess.
class HexDiff(binwalk.module.Module): class HexDiff(Module):
ALL_SAME = 0 ALL_SAME = 0
ALL_DIFF = 1 ALL_DIFF = 1
...@@ -25,33 +25,33 @@ class HexDiff(binwalk.module.Module): ...@@ -25,33 +25,33 @@ class HexDiff(binwalk.module.Module):
TITLE = "Binary Diffing" TITLE = "Binary Diffing"
CLI = [ CLI = [
binwalk.module.ModuleOption(short='W', Option(short='W',
long='hexdump', long='hexdump',
kwargs={'enabled' : True}, kwargs={'enabled' : True},
description='Perform a hexdump / diff of a file or files'), description='Perform a hexdump / diff of a file or files'),
binwalk.module.ModuleOption(short='G', Option(short='G',
long='green', long='green',
kwargs={'show_green' : True, 'show_blue' : False, 'show_red' : False}, kwargs={'show_green' : True, 'show_blue' : False, 'show_red' : False},
description='Only show lines containing bytes that are the same among all files'), description='Only show lines containing bytes that are the same among all files'),
binwalk.module.ModuleOption(short='i', Option(short='i',
long='red', long='red',
kwargs={'show_red' : True, 'show_blue' : False, 'show_green' : False}, kwargs={'show_red' : True, 'show_blue' : False, 'show_green' : False},
description='Only show lines containing bytes that are different among all files'), description='Only show lines containing bytes that are different among all files'),
binwalk.module.ModuleOption(short='U', Option(short='U',
long='blue', long='blue',
kwargs={'show_blue' : True, 'show_red' : False, 'show_green' : False}, kwargs={'show_blue' : True, 'show_red' : False, 'show_green' : False},
description='Only show lines containing bytes that are different among some files'), description='Only show lines containing bytes that are different among some files'),
binwalk.module.ModuleOption(short='w', Option(short='w',
long='terse', long='terse',
kwargs={'terse' : True}, kwargs={'terse' : True},
description='Diff all files, but only display a hex dump of the first file'), description='Diff all files, but only display a hex dump of the first file'),
] ]
KWARGS = [ KWARGS = [
binwalk.module.ModuleKwarg(name='show_red', default=True), Kwarg(name='show_red', default=True),
binwalk.module.ModuleKwarg(name='show_blue', default=True), Kwarg(name='show_blue', default=True),
binwalk.module.ModuleKwarg(name='show_green', default=True), Kwarg(name='show_green', default=True),
binwalk.module.ModuleKwarg(name='terse', default=False), Kwarg(name='terse', default=False),
] ]
HEADER_FORMAT = "\n%s\n" HEADER_FORMAT = "\n%s\n"
......
import magic import magic
import binwalk.module import binwalk.core.parser
import binwalk.parser import binwalk.core.filter
import binwalk.filter import binwalk.core.smartsignature
import binwalk.smartsignature from binwalk.core.compat import *
from binwalk.compat import * from binwalk.core.module import Module, Option, Kwarg
class Signature(binwalk.module.Module): class Signature(Module):
TITLE = "Signature Scan" TITLE = "Signature Scan"
CLI = [ CLI = [
binwalk.module.ModuleOption(short='B', Option(short='B',
long='signature', long='signature',
kwargs={'enabled' : True}, kwargs={'enabled' : True},
description='Scan target file(s) for file signatures'), description='Scan target file(s) for file signatures'),
binwalk.module.ModuleOption(short='m', Option(short='m',
long='magic', long='magic',
kwargs={'magic_files' : []}, kwargs={'magic_files' : []},
type=list, type=list,
dtype='file', dtype='file',
description='Specify a custom magic file to use'), description='Specify a custom magic file to use'),
binwalk.module.ModuleOption(short='R', Option(short='R',
long='raw-bytes', long='raw-bytes',
kwargs={'raw_bytes' : None}, kwargs={'raw_bytes' : None},
type=str, type=str,
description='Specify a sequence of bytes to search for'), description='Specify a sequence of bytes to search for'),
binwalk.module.ModuleOption(short='b', Option(short='b',
long='dumb', long='dumb',
kwargs={'dumb_scan' : True}, kwargs={'dumb_scan' : True},
description='Disable smart signature keywords'), description='Disable smart signature keywords'),
binwalk.module.ModuleOption(short='I', Option(short='I',
long='show-invalid', long='show-invalid',
kwargs={'show_invalid' : True}, kwargs={'show_invalid' : True},
description='Show results marked as invalid'), description='Show results marked as invalid'),
binwalk.module.ModuleOption(short='x', Option(short='x',
long='exclude', long='exclude',
kwargs={'exclude_filters' : []}, kwargs={'exclude_filters' : []},
type=list, type=list,
dtype=str.__name__, dtype=str.__name__,
description='Exclude results that match <str>'), description='Exclude results that match <str>'),
binwalk.module.ModuleOption(short='y', Option(short='y',
long='include', long='include',
kwargs={'include_filters' : []}, kwargs={'include_filters' : []},
type=list, type=list,
...@@ -49,13 +49,13 @@ class Signature(binwalk.module.Module): ...@@ -49,13 +49,13 @@ class Signature(binwalk.module.Module):
] ]
KWARGS = [ KWARGS = [
binwalk.module.ModuleKwarg(name='enabled', default=False), Kwarg(name='enabled', default=False),
binwalk.module.ModuleKwarg(name='dumb_scan', default=False), Kwarg(name='dumb_scan', default=False),
binwalk.module.ModuleKwarg(name='show_invalid', default=False), Kwarg(name='show_invalid', default=False),
binwalk.module.ModuleKwarg(name='raw_bytes', default=None), Kwarg(name='raw_bytes', default=None),
binwalk.module.ModuleKwarg(name='magic_files', default=[]), Kwarg(name='magic_files', default=[]),
binwalk.module.ModuleKwarg(name='exclude_filters', default=[]), Kwarg(name='exclude_filters', default=[]),
binwalk.module.ModuleKwarg(name='include_filters', default=[]), Kwarg(name='include_filters', default=[]),
] ]
HEADER = ["DECIMAL", "HEX", "DESCRIPTION"] HEADER = ["DECIMAL", "HEX", "DESCRIPTION"]
...@@ -67,9 +67,9 @@ class Signature(binwalk.module.Module): ...@@ -67,9 +67,9 @@ class Signature(binwalk.module.Module):
def init(self): def init(self):
# Create SmartSignature and MagicParser class instances. These are mostly for internal use. # Create SmartSignature and MagicParser class instances. These are mostly for internal use.
self.filter = binwalk.filter.MagicFilter() self.filter = binwalk.core.filter.MagicFilter()
self.smart = binwalk.smartsignature.SmartSignature(self.filter, ignore_smart_signatures=self.dumb_scan) self.smart = binwalk.core.smartsignature.SmartSignature(self.filter, ignore_smart_signatures=self.dumb_scan)
self.parser = binwalk.parser.MagicParser(self.filter, self.smart) self.parser = binwalk.core.parser.MagicParser(self.filter, self.smart)
# Set any specified include/exclude filters # Set any specified include/exclude filters
for regex in self.exclude_filters: for regex in self.exclude_filters:
......
import ctypes import ctypes
import ctypes.util import ctypes.util
from binwalk.common import * from binwalk.core.common import *
class Plugin: class Plugin:
''' '''
......
from binwalk.plugin import *
class Plugin: class Plugin:
''' '''
Ensures that ASCII CPIO archive entries only get extracted once. Ensures that ASCII CPIO archive entries only get extracted once.
......
import os import os
import shutil import shutil
from binwalk.compat import * from binwalk.core.compat import *
from binwalk.common import BlockFile from binwalk.core.common import BlockFile
class Plugin: class Plugin:
''' '''
...@@ -15,22 +15,23 @@ class Plugin: ...@@ -15,22 +15,23 @@ class Plugin:
def __init__(self, module): def __init__(self, module):
self.original_cmd = '' self.original_cmd = ''
self.enabled = (module.name == 'Signature') self.enabled = (module.name == 'Signature')
self.module = module
#if module.extractor.enabled: if self.enabled:
# Replace the existing LZMA extraction command with our own # Replace the existing LZMA extraction command with our own
# rules = self.binwalk.extractor.get_rules() rules = self.extractor.get_rules()
# for i in range(0, len(rules)): for i in range(0, len(rules)):
# if rules[i]['regex'].match(self.SIGNATURE): if rules[i]['regex'].match(self.SIGNATURE):
# self.original_cmd = rules[i]['cmd'] self.original_cmd = rules[i]['cmd']
# rules[i]['cmd'] = self.lzma_cable_extractor rules[i]['cmd'] = self.lzma_cable_extractor
# break break
def lzma_cable_extractor(self, fname): def lzma_cable_extractor(self, fname):
# Try extracting the LZMA file without modification first # Try extracting the LZMA file without modification first
if not self.binwalk.extractor.execute(self.original_cmd, fname): if not self.module.extractor.execute(self.original_cmd, fname):
out_name = os.path.splitext(fname)[0] + '-patched' + os.path.splitext(fname)[1] out_name = os.path.splitext(fname)[0] + '-patched' + os.path.splitext(fname)[1]
fp_out = BlockFile(out_name, 'w') fp_out = BlockFile(out_name, 'w')
fp_in = BlockFile(fname) fp_in = BlockFile(fname, swap=self.module.config.swap_size)
fp_in.MAX_TRAILING_SIZE = 0 fp_in.MAX_TRAILING_SIZE = 0
i = 0 i = 0
...@@ -51,11 +52,11 @@ class Plugin: ...@@ -51,11 +52,11 @@ class Plugin:
# Overwrite the original file so that it can be cleaned up if -r was specified # Overwrite the original file so that it can be cleaned up if -r was specified
shutil.move(out_name, fname) shutil.move(out_name, fname)
self.binwalk.extractor.execute(self.original_cmd, fname) self.module.extractor.execute(self.original_cmd, fname)
def scan(self, result): def scan(self, result):
# The modified cable modem LZMA headers all have valid dictionary sizes and a properties byte of 0x5D. # The modified cable modem LZMA headers all have valid dictionary sizes and a properties byte of 0x5D.
if result.description.lower().startswith(self.SIGNATURE) and "invalid uncompressed size" in result.description: if self.enabled and result.description.lower().startswith(self.SIGNATURE) and "invalid uncompressed size" in result.description:
if "properties: 0x5D" in result.description and "invalid dictionary size" not in result.description: if "properties: 0x5D" in result.description and "invalid dictionary size" not in result.description:
result.valid = True result.valid = True
result.description = result.description.split("invalid uncompressed size")[0] + "missing uncompressed size" result.description = result.description.split("invalid uncompressed size")[0] + "missing uncompressed size"
......
...@@ -7,11 +7,12 @@ class Plugin: ...@@ -7,11 +7,12 @@ class Plugin:
Searches for and validates zlib compressed data. Searches for and validates zlib compressed data.
''' '''
MIN_DECOMP_SIZE = 16*1024 MIN_DECOMP_SIZE = 16 * 1024
MAX_DATA_SIZE = 33 * 1024 MAX_DATA_SIZE = 33 * 1024
def __init__(self, module): def __init__(self, module):
self.tinfl = None self.tinfl = None
self.module = module
# Only initialize this plugin if this is a signature scan # Only initialize this plugin if this is a signature scan
if module.name == 'Signature': if module.name == 'Signature':
...@@ -22,8 +23,7 @@ class Plugin: ...@@ -22,8 +23,7 @@ class Plugin:
# If this result is a zlib signature match, try to decompress the data # If this result is a zlib signature match, try to decompress the data
if self.tinfl and result.file and result.description.lower().startswith('zlib'): if self.tinfl and result.file and result.description.lower().startswith('zlib'):
# Seek to and read the suspected zlib data # Seek to and read the suspected zlib data
fd = BlockFile(result.file.name, "r") fd = BlockFile(result.file.name, offset=result.offset, swap=self.module.config.swap_size)
fd.seek(result.offset)
data = fd.read(self.MAX_DATA_SIZE) data = fd.read(self.MAX_DATA_SIZE)
fd.close() fd.close()
......
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