Commit 9258050b by devttys0

Updated setup

parent ef96a6fd
...@@ -11,153 +11,168 @@ MODULE_NAME = "binwalk" ...@@ -11,153 +11,168 @@ MODULE_NAME = "binwalk"
# Python2/3 compliance # Python2/3 compliance
try: try:
raw_input raw_input
except NameError: except NameError:
raw_input = input raw_input = input
# This is super hacky. # This is super hacky.
if "--yes" in sys.argv: if "--yes" in sys.argv:
sys.argv.pop(sys.argv.index("--yes")) sys.argv.pop(sys.argv.index("--yes"))
IGNORE_WARNINGS = True IGNORE_WARNINGS = True
else: else:
IGNORE_WARNINGS = False IGNORE_WARNINGS = False
# cd into the src directory, no matter where setup.py was invoked from # cd into the src directory, no matter where setup.py was invoked from
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src")) os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src"))
def which(command): def which(command):
# /usr/local/bin is usually the default install path, though it may not be in $PATH # /usr/local/bin is usually the default install path, though it may not be in $PATH
usr_local_bin = os.path.sep.join([os.path.sep, 'usr', 'local', 'bin', command]) usr_local_bin = os.path.sep.join([os.path.sep, 'usr', 'local', 'bin', command])
try: try:
location = subprocess.Popen(["which", command], shell=False, stdout=subprocess.PIPE).communicate()[0].strip() location = subprocess.Popen(["which", command], shell=False, stdout=subprocess.PIPE).communicate()[0].strip()
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception as e: except Exception as e:
pass pass
if not location and os.path.exists(usr_local_bin): if not location and os.path.exists(usr_local_bin):
location = usr_local_bin location = usr_local_bin
return location return location
def warning(lines, terminate=True, prompt=True): def warning(lines, terminate=True, prompt=True):
WIDTH = 115 WIDTH = 115
if not IGNORE_WARNINGS:
print("\n" + "*" * WIDTH)
for line in lines:
print(line)
print("*" * WIDTH, "\n")
if prompt:
if raw_input('Continue installation anyway (Y/n)? ').lower().startswith('n'):
terminate = True
else:
terminate = False
if terminate:
sys.exit(1)
def find_binwalk_module_paths():
paths = []
try:
import binwalk
paths = binwalk.__path__
except KeyboardInterrupt as e:
raise e
except Exception:
pass
return paths
def remove_binwalk_module():
for path in find_binwalk_module_paths():
try:
remove_tree(path)
except OSError as e:
pass
script_path = which(MODULE_NAME)
if script_path:
try:
print("removing '%s'" % script_path)
os.unlink(script_path)
except KeyboardInterrupt as e:
pass
except Exception as e:
pass
if not IGNORE_WARNINGS: class UninstallCommand(Command):
print("\n" + "*" * WIDTH) description = "Uninstalls the Python module"
for line in lines: user_options = []
print(line)
print("*" * WIDTH, "\n")
if prompt: def initialize_options(self):
if raw_input('Continue installation anyway (Y/n)? ').lower().startswith('n'): pass
terminate = True
else:
terminate = False
if terminate: def finalize_options(self):
sys.exit(1) pass
class UninstallCommand(Command): def run(self):
description = "Uninstalls the Python module" remove_binwalk_module()
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
import binwalk
for path in binwalk.__path__:
try:
remove_tree(path)
except OSError as e:
pass
except KeyboardInterrupt as e:
raise e
except Exception as e:
pass
script_path = which(MODULE_NAME)
if script_path:
try:
print("removing '%s'" % script_path)
os.unlink(script_path)
except KeyboardInterrupt as e:
pass
except Exception as e:
pass
class CleanCommand(Command): class CleanCommand(Command):
description = "Clean Python build directories" description = "Clean Python build directories"
user_options = [] user_options = []
def initialize_options(self): def initialize_options(self):
pass pass
def finalize_options(self): def finalize_options(self):
pass pass
def run(self): def run(self):
try: try:
remove_tree("build") remove_tree("build")
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception: except Exception:
pass pass
try: try:
remove_tree("dist") remove_tree("dist")
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception: except Exception:
pass pass
# Check pre-requisite Python modules during an install # Check pre-requisite Python modules during an install
if "install" in sys.argv: if "install" in sys.argv:
print("checking pre-requisites") print("checking pre-requisites")
try: try:
import pyqtgraph import pyqtgraph
from pyqtgraph.Qt import QtCore, QtGui, QtOpenGL from pyqtgraph.Qt import QtCore, QtGui, QtOpenGL
except ImportError as e: except ImportError as e:
msg = ["Pre-requisite warning: " + str(e), msg = ["Pre-requisite warning: " + str(e),
"To take advantage of %s's graphing capabilities, please install this module." % MODULE_NAME, "To take advantage of %s's graphing capabilities, please install this module." % MODULE_NAME,
] ]
warning(msg, prompt=True) warning(msg, prompt=True)
# If an older version of binwalk is currently installed, completely remove it to prevent conflicts
existing_binwalk_modules = find_binwalk_module_paths()
if existing_binwalk_modules and not os.path.exists(os.path.join(existing_binwalk_modules[0], "core")):
remove_binwalk_module()
# Re-build the magic file during a build/install # Re-build the magic file during a build/install
if "install" in sys.argv or "build" in sys.argv: if "install" in sys.argv or "build" in sys.argv:
# Generate a new magic file from the files in the magic directory # Generate a new magic file from the files in the magic directory
print("creating %s magic file" % MODULE_NAME) print("creating %s magic file" % MODULE_NAME)
magic_files = os.listdir("magic") magic_files = os.listdir("magic")
magic_files.sort() magic_files.sort()
fd = open("%s/magic/%s" % (MODULE_NAME, MODULE_NAME), "wb") fd = open("%s/magic/%s" % (MODULE_NAME, MODULE_NAME), "wb")
for magic in magic_files: for magic in magic_files:
fpath = os.path.join("magic", magic) fpath = os.path.join("magic", magic)
if os.path.isfile(fpath): if os.path.isfile(fpath):
fd.write(open(fpath, "rb").read()) fd.write(open(fpath, "rb").read())
fd.close() fd.close()
# The data files to install along with the module # The data files to install along with the module
install_data_files = ["magic/*", "config/*", "plugins/*", "modules/*", "core/*"] install_data_files = ["magic/*", "config/*", "plugins/*", "modules/*", "core/*"]
# Install the module, script, and support files # Install the module, script, and support files
setup(name = MODULE_NAME, setup(name = MODULE_NAME,
version = "2.0.0 beta", version = "2.0.0 beta",
description = "Firmware analysis tool", description = "Firmware analysis tool",
author = "Craig Heffner", author = "Craig Heffner",
url = "https://github.com/devttys0/%s" % MODULE_NAME, url = "https://github.com/devttys0/%s" % MODULE_NAME,
requires = ["magic", "pyqtgraph"], requires = ["magic", "pyqtgraph"],
packages = [MODULE_NAME], packages = [MODULE_NAME],
package_data = {MODULE_NAME : install_data_files}, package_data = {MODULE_NAME : install_data_files},
scripts = [os.path.join("scripts", MODULE_NAME)], scripts = [os.path.join("scripts", MODULE_NAME)],
cmdclass = {'clean' : CleanCommand, 'uninstall' : UninstallCommand} cmdclass = {'clean' : CleanCommand, 'uninstall' : UninstallCommand}
) )
...@@ -9,248 +9,248 @@ from binwalk.core.module import Module, Option, Kwarg ...@@ -9,248 +9,248 @@ from binwalk.core.module import Module, Option, Kwarg
# TODO: This code is an effing mess. # TODO: This code is an effing mess.
class HexDiff(Module): class HexDiff(Module):
ALL_SAME = 0 ALL_SAME = 0
ALL_DIFF = 1 ALL_DIFF = 1
SOME_DIFF = 2 SOME_DIFF = 2
DEFAULT_DIFF_SIZE = 0x100 DEFAULT_DIFF_SIZE = 0x100
DEFAULT_BLOCK_SIZE = 16 DEFAULT_BLOCK_SIZE = 16
COLORS = { COLORS = {
'red' : '31', 'red' : '31',
'green' : '32', 'green' : '32',
'blue' : '34', 'blue' : '34',
} }
TITLE = "Binary Diffing" TITLE = "Binary Diffing"
CLI = [ CLI = [
Option(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'),
Option(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'),
Option(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'),
Option(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'),
Option(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 = [
Kwarg(name='show_red', default=True), Kwarg(name='show_red', default=True),
Kwarg(name='show_blue', default=True), Kwarg(name='show_blue', default=True),
Kwarg(name='show_green', default=True), Kwarg(name='show_green', default=True),
Kwarg(name='terse', default=False), Kwarg(name='terse', default=False),
Kwarg(name='enabled', default=False), Kwarg(name='enabled', default=False),
] ]
HEADER_FORMAT = "\n%s\n" HEADER_FORMAT = "\n%s\n"
RESULT_FORMAT = "%s\n" RESULT_FORMAT = "%s\n"
RESULT = ['description'] RESULT = ['description']
def _no_colorize(self, c, color="red", bold=True): def _no_colorize(self, c, color="red", bold=True):
return c return c
def _colorize(self, c, color="red", bold=True): def _colorize(self, c, color="red", bold=True):
attr = [] attr = []
attr.append(self.COLORS[color]) attr.append(self.COLORS[color])
if bold: if bold:
attr.append('1') attr.append('1')
return "\x1b[%sm%s\x1b[0m" % (';'.join(attr), c) return "\x1b[%sm%s\x1b[0m" % (';'.join(attr), c)
def _color_filter(self, data): def _color_filter(self, data):
red = '\x1b[' + self.COLORS['red'] + ';' red = '\x1b[' + self.COLORS['red'] + ';'
green = '\x1b[' + self.COLORS['green'] + ';' green = '\x1b[' + self.COLORS['green'] + ';'
blue = '\x1b[' + self.COLORS['blue'] + ';' blue = '\x1b[' + self.COLORS['blue'] + ';'
if self.show_blue and blue in data: if self.show_blue and blue in data:
return True return True
if self.show_green and green in data: if self.show_green and green in data:
return True return True
if self.show_red and red in data: if self.show_red and red in data:
return True return True
return False return False
def _print_block_hex(self, alt_text="*"): def _print_block_hex(self, alt_text="*"):
if self._color_filter(self.block_hex): if self._color_filter(self.block_hex):
desc = self.block_hex desc = self.block_hex
self.printed_alt_text = False self.printed_alt_text = False
elif not self.printed_alt_text: elif not self.printed_alt_text:
desc = "%s" % alt_text desc = "%s" % alt_text
self.printed_alt_text = True self.printed_alt_text = True
self.result(description=desc) self.result(description=desc)
self.block_hex = "" self.block_hex = ""
return True return True
def _build_block(self, c, highlight=None): def _build_block(self, c, highlight=None):
if highlight == self.ALL_DIFF: if highlight == self.ALL_DIFF:
self.block_hex += self.colorize(c, color="red") self.block_hex += self.colorize(c, color="red")
elif highlight == self.ALL_SAME: elif highlight == self.ALL_SAME:
self.block_hex += self.colorize(c, color="green") self.block_hex += self.colorize(c, color="green")
elif highlight == self.SOME_DIFF: elif highlight == self.SOME_DIFF:
self.block_hex += self.colorize(c, color="blue") self.block_hex += self.colorize(c, color="blue")
else: else:
self.block_hex += c self.block_hex += c
def _build_header(self, files, block_size): def _build_header(self, files, block_size):
header = "OFFSET" + (" " * 6) + files[0].name header = "OFFSET" + (" " * 6) + files[0].name
for i in range(1, len(files)): for i in range(1, len(files)):
header += " " * ((block_size * 3) + 2 + block_size + 8 - len(files[i-1].name)) header += " " * ((block_size * 3) + 2 + block_size + 8 - len(files[i-1].name))
header += files[i].name header += files[i].name
return header return header
def init(self): def init(self):
block = self.config.block block = self.config.block
if not block: if not block:
block = self.DEFAULT_BLOCK_SIZE block = self.DEFAULT_BLOCK_SIZE
if self.terse: if self.terse:
header_files = self.config.target_files[:1] header_files = self.config.target_files[:1]
else: else:
header_files = self.config.target_files header_files = self.config.target_files
self.HEADER = self._build_header(header_files, block) self.HEADER = self._build_header(header_files, block)
if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty() and platform.system() != 'Windows': if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty() and platform.system() != 'Windows':
curses.setupterm() curses.setupterm()
self.colorize = self._colorize self.colorize = self._colorize
else: else:
self.colorize = self._no_colorize self.colorize = self._no_colorize
def run(self): def run(self):
i = 0 i = 0
total = 0 total = 0
data = {} data = {}
delim = '/' delim = '/'
self.block_hex = "" self.block_hex = ""
self.printed_alt_text = False self.printed_alt_text = False
offset = self.config.offset offset = self.config.offset
size = self.config.length size = self.config.length
block = self.config.block block = self.config.block
self.header() self.header()
if not block: if not block:
block = self.DEFAULT_BLOCK_SIZE block = self.DEFAULT_BLOCK_SIZE
# 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
#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
read_block_size = common.BlockFile.DEFAULT_BLOCK_READ_SIZE read_block_size = common.BlockFile.DEFAULT_BLOCK_READ_SIZE
# BlockFile handles calculation of negative offsets, if one was specified # BlockFile handles calculation of negative offsets, if one was specified
offset = self.config.target_files[0].offset offset = self.config.target_files[0].offset
size = self.config.target_files[0].length 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 self.config.target_files: 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(self.config.target_files): 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:
diff_same = {} diff_same = {}
alt_text = "*" + " " * 8 alt_text = "*" + " " * 8
self._build_block("%.08X " % (total + i + offset)) self._build_block("%.08X " % (total + i + offset))
# For each byte in this block, is the byte the same in all files, the same in some files, or different in all files? # For each byte in this block, is the byte the same in all files, the same in some files, or different in all files?
for j in range(0, block): for j in range(0, block):
byte_list = [] byte_list = []
try: try:
c = data[self.config.target_files[0].name][j+i] c = data[self.config.target_files[0].name][j+i]
except: except:
c = None c = None
for f in self.config.target_files: for f in self.config.target_files:
try: try:
c = data[f.name][j+i] c = data[f.name][j+i]
except Exception as e: except Exception as e:
c = None c = None
if c not in byte_list: if c not in byte_list:
byte_list.append(c) byte_list.append(c)
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(self.config.target_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(self.config.target_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 = self.config.target_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.name][j+i]), highlight=diff_same[j]) self._build_block("%.2X " % ord(data[f.name][j+i]), highlight=diff_same[j])
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception as e: except Exception as e:
self._build_block(" ") self._build_block(" ")
if (j+1) == block: if (j+1) == block:
self._build_block(" |") self._build_block(" |")
for k in range(0, block): for k in range(0, block):
try: try:
if data[f.name][k+i] in string.printable and data[f.name][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.name][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(self.config.target_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("|") self._build_block("|")
else: else:
self._build_block('| %s ' % delim) self._build_block('| %s ' % delim)
if self._print_block_hex(alt_text=alt_text[:-1].strip()): if self._print_block_hex(alt_text=alt_text[:-1].strip()):
if delim == '\\': if delim == '\\':
delim = '/' delim = '/'
else: else:
delim = '\\' delim = '\\'
i += block i += block
total += read_block_size total += read_block_size
self.footer() self.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