Commit 70432760 by devttys0

Integration of hexdiff as a module complete.

parent 54bfff03
...@@ -78,8 +78,8 @@ class Plotter(object): ...@@ -78,8 +78,8 @@ class Plotter(object):
self.window = gl.GLViewWidget() self.window = gl.GLViewWidget()
self.window.opts['distance'] = self.VIEW_DISTANCE self.window.opts['distance'] = self.VIEW_DISTANCE
if len(self.target_files) == 1: if len(self.config.target_files) == 1:
self.window.setWindowTitle(self.target_files[0].name) self.window.setWindowTitle(self.config.target_files[0].name)
def _print(self, message): def _print(self, message):
''' '''
...@@ -254,7 +254,7 @@ class Plotter(object): ...@@ -254,7 +254,7 @@ class Plotter(object):
ygrid.scale(12.8, 12.8, 12.8) ygrid.scale(12.8, 12.8, 12.8)
zgrid.scale(12.8, 12.8, 12.8) zgrid.scale(12.8, 12.8, 12.8)
for fd in self.target_files: for fd in self.config.target_files:
data_points = self._generate_data_points(fd) data_points = self._generate_data_points(fd)
self._print("Generating plot points from %d data points" % len(data_points)) self._print("Generating plot points from %d data points" % len(data_points))
......
...@@ -67,7 +67,7 @@ class Configuration(object): ...@@ -67,7 +67,7 @@ class Configuration(object):
binwalk.module.ModuleOption(long=None, binwalk.module.ModuleOption(long=None,
short=None, short=None,
type=binwalk.common.BlockFile, type=binwalk.common.BlockFile,
kwargs={'target_files' : []}), kwargs={'files' : []}),
binwalk.module.ModuleOption(short='u', binwalk.module.ModuleOption(short='u',
long='update', long='update',
kwargs={'do_update' : True}, kwargs={'do_update' : True},
...@@ -86,12 +86,14 @@ class Configuration(object): ...@@ -86,12 +86,14 @@ class Configuration(object):
binwalk.module.ModuleKwarg(name='verbose', default=[]), binwalk.module.ModuleKwarg(name='verbose', default=[]),
binwalk.module.ModuleKwarg(name='debug_verbose', default=False), binwalk.module.ModuleKwarg(name='debug_verbose', default=False),
binwalk.module.ModuleKwarg(name='skip_unopened', default=False), binwalk.module.ModuleKwarg(name='skip_unopened', default=False),
binwalk.module.ModuleKwarg(name='target_files', default=[]), binwalk.module.ModuleKwarg(name='files', default=[]),
binwalk.module.ModuleKwarg(name='show_help', default=False), binwalk.module.ModuleKwarg(name='show_help', default=False),
binwalk.module.ModuleKwarg(name='do_update', default=False), binwalk.module.ModuleKwarg(name='do_update', default=False),
] ]
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.target_files = []
binwalk.module.process_kwargs(self, kwargs) binwalk.module.process_kwargs(self, kwargs)
if self.show_help: if self.show_help:
...@@ -111,6 +113,19 @@ class Configuration(object): ...@@ -111,6 +113,19 @@ class Configuration(object):
verbose=self.verbose, verbose=self.verbose,
fit_to_screen=self.format_to_terminal) fit_to_screen=self.format_to_terminal)
def __del__(self):
self._cleanup()
def __exit__(self, a, b, c):
self._cleanup()
def __enter__(self):
return self
def _cleanup(self):
for fp in self.target_files:
fp.close()
def _set_verbosity(self): def _set_verbosity(self):
''' '''
Sets the appropriate verbosity. Sets the appropriate verbosity.
...@@ -123,33 +138,29 @@ class Configuration(object): ...@@ -123,33 +138,29 @@ class Configuration(object):
if len(self.target_files) > 1 and self.verbose == 0: if len(self.target_files) > 1 and self.verbose == 0:
self.verbose = 1 self.verbose = 1
def _test_target_files(self): def _open_target_files(self):
''' '''
Checks if the target files can be opened. Checks if the target files can be opened.
Any files that cannot be opened are removed from the self.target_files list. Any files that cannot be opened are removed from the self.target_files list.
''' '''
open_files = []
# Validate the target files listed in target_files # Validate the target files listed in target_files
for tfile in self.target_files: for tfile in self.files:
# Ignore directories. # Ignore directories.
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:
open_files.append(BlockFile(tfile, length=self.length, offset=self.offset)) self.target_files.append(binwalk.common.BlockFile(tfile, length=self.length, offset=self.offset))
except Exception as e: except Exception as e:
sys.stderr.write("Cannot open file : %s\n" % str(e)) sys.stderr.write("Cannot open file : %s\n" % str(e))
# Unless -O was specified, don't run the scan unless we are able to scan all specified files # Unless -O was specified, don't run the scan unless we are able to scan all specified files
if len(open_files) != len(self.target_files) and not self.skip_unopened: if len(self.target_files) != len(self.files) and not self.skip_unopened:
failed_open_count = len(self.target_files) - len(open_files) failed_open_count = len(self.files) - len(self.target_files)
if failed_open_count > 1: if failed_open_count > 1:
plural = 's' plural = 's'
else: else:
plural = '' plural = ''
raise Exception("Failed to open %d file%s for scanning" % (failed_open_count, plural)) raise Exception("Failed to open %d file%s for scanning" % (failed_open_count, plural))
else:
self.target_files = open_files
class Update(object): class Update(object):
''' '''
......
...@@ -351,8 +351,11 @@ class HashMatch(object): ...@@ -351,8 +351,11 @@ class HashMatch(object):
Main module method. Main module method.
''' '''
results = None results = None
needle = self.config.target_files[0] needle = self.config.target_files[0].name
haystack = self.config.target_files[1:] haystack = []
for fp in self.config.target_files[1:]:
haystack.append(fp.name)
self.config.display.format_strings(self.HEADER_FORMAT, self.RESULT_FORMAT) self.config.display.format_strings(self.HEADER_FORMAT, self.RESULT_FORMAT)
self.config.display.header(*self.HEADER) self.config.display.header(*self.HEADER)
......
#!/usr/bin/env python
# TODO: Use sane defaults for block size and file size, if not specified.
# Handle header output for multiple files.
import os import os
import sys import sys
import curses import curses
...@@ -34,7 +29,7 @@ class HexDiff(object): ...@@ -34,7 +29,7 @@ class HexDiff(object):
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', binwalk.module.ModuleOption(short='G',
long='green', long='green',
kwargs={'show_green' : True, 'show_blue' : False, 'show_green' : 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', binwalk.module.ModuleOption(short='i',
long='red', long='red',
...@@ -63,12 +58,6 @@ class HexDiff(object): ...@@ -63,12 +58,6 @@ class HexDiff(object):
self.block_hex = "" self.block_hex = ""
self.printed_alt_text = False self.printed_alt_text = False
if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty() and platform.system() != 'Windows':
curses.setupterm()
self.colorize = self._colorize
else:
self.colorize = self._no_colorize
def _no_colorize(self, c, color="red", bold=True): def _no_colorize(self, c, color="red", bold=True):
return c return c
...@@ -102,7 +91,7 @@ class HexDiff(object): ...@@ -102,7 +91,7 @@ class HexDiff(object):
self.printed_alt_text = False self.printed_alt_text = False
printed = True printed = True
elif not self.printed_alt_text: elif not self.printed_alt_text:
self.config.display.result("%s\n" % alt_text) self.config.display.result("%s" % alt_text)
self.printed_alt_text = True self.printed_alt_text = True
printed = True printed = True
...@@ -119,55 +108,67 @@ class HexDiff(object): ...@@ -119,55 +108,67 @@ class HexDiff(object):
else: else:
self.block_hex += c self.block_hex += c
def _build_header(self, files, block_size):
header = "OFFSET" + (" " * 4) + files[0].name
for i in range(1, len(files)):
header += " " * ((block_size * 3) + 2 + block_size + 8 - len(files[i-1].name))
header += files[i].name
return header
def run(self): def run(self):
i = 0 i = 0
total = 0 total = 0
fps = []
data = {} data = {}
delim = '/' delim = '/'
offset = self.config.offset offset = self.config.offset
size = self.config.length size = self.config.length
block = self.config.block block = self.config.block
files = self.config.target_files
if not block:
block = self.DEFAULT_BLOCK_SIZE
self.config.display.format_strings("\n%s\n", "%s\n") self.config.display.format_strings("\n%s\n", "%s\n")
if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty() and platform.system() != 'Windows':
curses.setupterm()
self.colorize = self._colorize
else:
self.colorize = self._no_colorize
# If negative offset, then we're going that far back from the end of the file # If negative offset, then we're going that far back from the end of the file
if offset < 0: if offset < 0:
size = offset * -1 size = offset * -1
# TODO: Display all file names in hexdump
if self.terse: if self.terse:
self.config.display.header(files[0]) header = self._build_header(self.config.target_files[:1], block)
else: else:
self.config.display.header(files[0]) header = self._build_header(self.config.target_files, block)
self.config.display.header(header)
if common.BlockFile.READ_BLOCK_SIZE < block: if common.BlockFile.READ_BLOCK_SIZE < block:
read_block_size = block read_block_size = block
else: else:
read_block_size = common.BlockFile.READ_BLOCK_SIZE read_block_size = common.BlockFile.READ_BLOCK_SIZE
for f in files:
fp = common.BlockFile(f, 'r', length=size, offset=offset)
fp.READ_BLOCK_SIZE = read_block_size
fp.MAX_TRAILING_SIZE = 0
fps.append(fp)
# BlockFile handles calculation of negative offsets, if one was specified # BlockFile handles calculation of negative offsets, if one was specified
offset = fps[0].offset offset = self.config.target_files[0].offset
size = self.config.target_files[0].length
while total < size: while total < size:
i = 0 i = 0
files_finished = 0 files_finished = 0
for fp in fps: for fp in self.config.target_files:
(ddata, dlen) = fp.read_block() (ddata, dlen) = fp.read_block()
data[fp.name] = ddata data[fp.name] = ddata
if not ddata or dlen == 0: if not ddata or dlen == 0:
files_finished += 1 files_finished += 1
if files_finished == len(fps): if files_finished == len(self.config.target_files):
break break
while i < read_block_size and (total+i) < size: while i < read_block_size and (total+i) < size:
...@@ -181,13 +182,13 @@ class HexDiff(object): ...@@ -181,13 +182,13 @@ class HexDiff(object):
byte_list = [] byte_list = []
try: try:
c = data[files[0]][j+i] c = data[self.config.target_files[0].name][j+i]
except: except:
c = None c = None
for f in files: for f in self.config.target_files:
try: try:
c = data[f][j+i] c = data[f.name][j+i]
except Exception as e: except Exception as e:
c = None c = None
...@@ -196,23 +197,23 @@ class HexDiff(object): ...@@ -196,23 +197,23 @@ class HexDiff(object):
if len(byte_list) == 1: if len(byte_list) == 1:
diff_same[j] = self.ALL_SAME diff_same[j] = self.ALL_SAME
elif len(byte_list) == len(files): elif len(byte_list) == len(self.config.target_files):
diff_same[j] = self.ALL_DIFF diff_same[j] = self.ALL_DIFF
else: else:
diff_same[j] = self.SOME_DIFF diff_same[j] = self.SOME_DIFF
for index in range(0, len(files)): for index in range(0, len(self.config.target_files)):
if self.terse and index > 0: if self.terse and index > 0:
break break
f = files[index] f = self.config.target_files[index]
alt_text += " " * (3 + (3 * block) + 3 + block + 3) alt_text += " " * (3 + (3 * block) + 3 + block + 3)
alt_text += delim alt_text += delim
for j in range(0, block): for j in range(0, block):
try: try:
self._build_block("%.2X " % ord(data[f][j+i]), highlight=diff_same[j]) self._build_block("%.2X " % ord(data[f.name][j+i]), highlight=diff_same[j])
except Exception as e: except Exception as e:
self._build_block(" ") self._build_block(" ")
...@@ -220,15 +221,15 @@ class HexDiff(object): ...@@ -220,15 +221,15 @@ class HexDiff(object):
self._build_block(" |") self._build_block(" |")
for k in range(0, block): for k in range(0, block):
try: try:
if data[f][k+i] in string.printable and data[f][k+i] not in string.whitespace: if data[f.name][k+i] in string.printable and data[f.name][k+i] not in string.whitespace:
self._build_block(data[f][k+i], highlight=diff_same[k]) self._build_block(data[f.name][k+i], highlight=diff_same[k])
else: else:
self._build_block('.', highlight=diff_same[k]) self._build_block('.', highlight=diff_same[k])
except: except:
self._build_block(' ') self._build_block(' ')
if index == len(files)-1 or (self.terse and index == 0): if index == len(self.config.target_files)-1 or (self.terse and index == 0):
self._build_block("|\n") self._build_block("|")
else: else:
self._build_block('| %s ' % delim) self._build_block('| %s ' % delim)
...@@ -241,9 +242,6 @@ class HexDiff(object): ...@@ -241,9 +242,6 @@ class HexDiff(object):
i += block i += block
total += read_block_size total += read_block_size
for fp in fps:
fp.close()
self.config.display.footer() self.config.display.footer()
return True return True
......
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