Commit b24fe1c7 by devttys0

Added zlibextractor plugin; removed FMK zlib extraction dependency

parent 38ac8074
...@@ -27,13 +27,13 @@ ...@@ -27,13 +27,13 @@
# These assume the firmware-mod-kit is installed to /opt/firmware-mod-kit. # These assume the firmware-mod-kit is installed to /opt/firmware-mod-kit.
# If not, change the file paths appropriately. # If not, change the file paths appropriately.
^squashfs filesystem:squashfs:/opt/firmware-mod-kit/unsquashfs_all.sh '%e'
^jffs2 filesystem:jffs2:/opt/firmware-mod-kit/src/jffs2/unjffs2 '%e' ^jffs2 filesystem:jffs2:/opt/firmware-mod-kit/src/jffs2/unjffs2 '%e'
^ascii cpio archive:cpio:/opt/firmware-mod-kit/uncpio.sh '%e' ^ascii cpio archive:cpio:/opt/firmware-mod-kit/uncpio.sh '%e'
#^squashfs filesystem:squashfs:/opt/firmware-mod-kit/unsquashfs_all.sh '%e'
#^cramfs filesystem:cramfs:/opt/firmware-mod-kit/uncramfs_all.sh '%e' #^cramfs filesystem:cramfs:/opt/firmware-mod-kit/uncramfs_all.sh '%e'
#^bff volume entry:bff:/opt/firmware-mod-kit/src/bff/bffxtractor.py '%e' #^bff volume entry:bff:/opt/firmware-mod-kit/src/bff/bffxtractor.py '%e'
#^wdk file system:wdk:/opt/firmware-mod-kit/src/firmware-tools/unwdk.py '%e' #^wdk file system:wdk:/opt/firmware-mod-kit/src/firmware-tools/unwdk.py '%e'
^zlib compressed data:zlib:/opt/firmware-mod-kit/src/firmware-tools/unzlib.py '%e' #^zlib compressed data:zlib:/opt/firmware-mod-kit/src/firmware-tools/unzlib.py '%e'
^cramfs filesystem:cramfs:mkdir cramfs-root && mount -t cramfs '%e' cramfs-root ^cramfs filesystem:cramfs:mkdir cramfs-root && mount -t cramfs '%e' cramfs-root
^ext2 filesystem:ext2:mkdir ext2-root && mount -t ext2 '%e' ext2-root ^ext2 filesystem:ext2:mkdir ext2-root && mount -t ext2 '%e' ext2-root
......
...@@ -31,10 +31,15 @@ class Disasm(Module): ...@@ -31,10 +31,15 @@ class Disasm(Module):
type=int, type=int,
kwargs={'min_insn_count' : 0}, kwargs={'min_insn_count' : 0},
description='Minimum number of consecutive instructions to be considered valid (default: %d)' % DEFAULT_MIN_INSN_COUNT), description='Minimum number of consecutive instructions to be considered valid (default: %d)' % DEFAULT_MIN_INSN_COUNT),
Option(long='continue',
short='k',
kwargs={'keep_going' : True},
description="Don't stop at the first match"),
] ]
KWARGS = [ KWARGS = [
Kwarg(name='enabled', default=False), Kwarg(name='enabled', default=False),
Kwarg(name='keep_going', default=False),
Kwarg(name='min_insn_count', default=DEFAULT_MIN_INSN_COUNT), Kwarg(name='min_insn_count', default=DEFAULT_MIN_INSN_COUNT),
] ]
...@@ -146,7 +151,7 @@ class Disasm(Module): ...@@ -146,7 +151,7 @@ class Disasm(Module):
if self.config.verbose: if self.config.verbose:
for (position, size, mnem, opnds) in result.insns: for (position, size, mnem, opnds) in result.insns:
self.result(offset=position, file=fp, description="\t\t%s %s" % (mnem, opnds)) self.result(offset=position, file=fp, description="\t\t%s %s" % (mnem, opnds))
if not self.config.keep_going: if not self.keep_going:
return return
total_read += dlen total_read += dlen
......
...@@ -24,7 +24,7 @@ class Extractor(Module): ...@@ -24,7 +24,7 @@ class Extractor(Module):
# Comments in the extract.conf files start with a pound # Comments in the extract.conf files start with a pound
COMMENT_DELIM ='#' COMMENT_DELIM ='#'
# Place holder for the extracted file name in the command # Place holder for the extracted file name in the command
FILE_NAME_PLACEHOLDER = '%e' FILE_NAME_PLACEHOLDER = '%e'
TITLE = 'Extraction' TITLE = 'Extraction'
...@@ -116,7 +116,7 @@ class Extractor(Module): ...@@ -116,7 +116,7 @@ class Extractor(Module):
if r.valid: if r.valid:
binwalk.core.common.debug("Extractor callback for %s:%d [%s & %s & %s]" % (r.file.name, r.offset, str(r.valid), str(r.display), str(r.extract))) binwalk.core.common.debug("Extractor callback for %s:%d [%s & %s & %s]" % (r.file.name, r.offset, str(r.valid), str(r.display), str(r.extract)))
# Only extract valid results that have been marked for extraction and displayed to the user. # Only extract valid results that have been marked for extraction and displayed to the user.
# Note that r.display is still True even if --quiet has been specified; it is False if the result has been # Note that r.display is still True even if --quiet has been specified; it is False if the result has been
# explicitly excluded via the -y/-x options. # explicitly excluded via the -y/-x options.
...@@ -173,9 +173,9 @@ class Extractor(Module): ...@@ -173,9 +173,9 @@ class Extractor(Module):
rules = [] rules = []
match = False match = False
r = { r = {
'extension' : '', 'extension' : '',
'cmd' : '', 'cmd' : '',
'regex' : None 'regex' : None
} }
# Process single explicitly specified rule # Process single explicitly specified rule
...@@ -184,8 +184,8 @@ class Extractor(Module): ...@@ -184,8 +184,8 @@ class Extractor(Module):
r['regex'] = re.compile(regex) r['regex'] = re.compile(regex)
if cmd: if cmd:
r['cmd'] = cmd r['cmd'] = cmd
self.append_rule(r) self.append_rule(r)
return return
# Process rule string, or list of rule strings # Process rule string, or list of rule strings
...@@ -193,7 +193,7 @@ class Extractor(Module): ...@@ -193,7 +193,7 @@ class Extractor(Module):
rules = [txtrule] rules = [txtrule]
else: else:
rules = txtrule rules = txtrule
for rule in rules: for rule in rules:
r['cmd'] = '' r['cmd'] = ''
r['extension'] = '' r['extension'] = ''
...@@ -210,7 +210,7 @@ class Extractor(Module): ...@@ -210,7 +210,7 @@ class Extractor(Module):
pass pass
# Verify that the match string was retrieved. # Verify that the match string was retrieved.
if match: if match:
self.append_rule(r) self.append_rule(r)
def remove_rule(self, text): def remove_rule(self, text):
...@@ -226,7 +226,7 @@ class Extractor(Module): ...@@ -226,7 +226,7 @@ class Extractor(Module):
for i in range(0, len(self.extract_rules)): for i in range(0, len(self.extract_rules)):
if self.extract_rules[i]['regex'].match(text): if self.extract_rules[i]['regex'].match(text):
rm.append(i) rm.append(i)
for i in rm: for i in rm:
self.extract_rules.pop(i) self.extract_rules.pop(i)
...@@ -251,7 +251,7 @@ class Extractor(Module): ...@@ -251,7 +251,7 @@ class Extractor(Module):
Loads extraction rules from the specified file. Loads extraction rules from the specified file.
@fname - Path to the extraction rule file. @fname - Path to the extraction rule file.
Returns None. Returns None.
''' '''
try: try:
...@@ -327,7 +327,7 @@ class Extractor(Module): ...@@ -327,7 +327,7 @@ class Extractor(Module):
self.remove_after_execute = tf self.remove_after_execute = tf
return self.remove_after_execute return self.remove_after_execute
def extract(self, offset, description, file_name, size, name=None): def extract(self, offset, description, file_name, size, name=None):
''' '''
Extract an embedded file from the target file, if it matches an extract rule. Extract an embedded file from the target file, if it matches an extract rule.
...@@ -353,13 +353,13 @@ class Extractor(Module): ...@@ -353,13 +353,13 @@ class Extractor(Module):
output_directory = self.build_output_directory(file_name) output_directory = self.build_output_directory(file_name)
# Extract to end of file if no size was specified # Extract to end of file if no size was specified
if not size: if not size:
size = file_size(file_path) - offset size = file_size(file_path) - offset
if os.path.isfile(file_path): if os.path.isfile(file_path):
os.chdir(output_directory) os.chdir(output_directory)
# Loop through each extraction rule until one succeeds # Loop through each extraction rule until one succeeds
for i in range(0, len(rules)): for i in range(0, len(rules)):
rule = rules[i] rule = rules[i]
...@@ -373,7 +373,7 @@ class Extractor(Module): ...@@ -373,7 +373,7 @@ class Extractor(Module):
# Many extraction utilities will extract the file to a new file, just without # Many extraction utilities will extract the file to a new file, just without
# the file extension (i.e., myfile.7z -> myfile). If the presumed resulting # the file extension (i.e., myfile.7z -> myfile). If the presumed resulting
# file name already exists before executing the extract command, do not attempt # file name already exists before executing the extract command, do not attempt
# to clean it up even if its resulting file size is 0. # to clean it up even if its resulting file size is 0.
if self.remove_after_execute: if self.remove_after_execute:
extracted_fname = os.path.splitext(fname)[0] extracted_fname = os.path.splitext(fname)[0]
...@@ -386,7 +386,7 @@ class Extractor(Module): ...@@ -386,7 +386,7 @@ class Extractor(Module):
else: else:
extract_ok = True extract_ok = True
# Only clean up files if remove_after_execute was specified # Only clean up files if remove_after_execute was specified
if extract_ok == True and self.remove_after_execute: if extract_ok == True and self.remove_after_execute:
# Remove the original file that we extracted # Remove the original file that we extracted
...@@ -406,7 +406,7 @@ class Extractor(Module): ...@@ -406,7 +406,7 @@ class Extractor(Module):
raise e raise e
except Exception as e: except Exception as e:
pass pass
# If the command executed OK, don't try any more rules # If the command executed OK, don't try any more rules
if extract_ok == True: if extract_ok == True:
break break
...@@ -497,15 +497,15 @@ class Extractor(Module): ...@@ -497,15 +497,15 @@ class Extractor(Module):
if not output_file_name or output_file_name is None: if not output_file_name or output_file_name is None:
bname = default_bname bname = default_bname
else: else:
# Strip the output file name of invalid/dangerous characters (like file paths) # Strip the output file name of invalid/dangerous characters (like file paths)
bname = os.path.basename(output_file_name) bname = os.path.basename(output_file_name)
fname = unique_file_name(bname, extension) fname = unique_file_name(bname, extension)
try: try:
# Open the target file and seek to the offset # Open the target file and seek to the offset
fdin = self.config.open_file(file_name, length=size, offset=offset) fdin = self.config.open_file(file_name, length=size, offset=offset)
# Open the output file # Open the output file
try: try:
fdout = BlockFile(fname, 'w') fdout = BlockFile(fname, 'w')
...@@ -531,8 +531,8 @@ class Extractor(Module): ...@@ -531,8 +531,8 @@ class Extractor(Module):
raise e raise e
except Exception as e: except Exception as e:
raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e))) raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e)))
binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" % (offset, offset+size, file_name, fname)) binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" % (offset, offset+size, file_name, fname))
return fname return fname
def execute(self, cmd, fname): def execute(self, cmd, fname):
...@@ -568,10 +568,10 @@ class Extractor(Module): ...@@ -568,10 +568,10 @@ class Extractor(Module):
# Replace all instances of FILE_NAME_PLACEHOLDER in the command with fname # Replace all instances of FILE_NAME_PLACEHOLDER in the command with fname
command = command.strip().replace(self.FILE_NAME_PLACEHOLDER, fname) command = command.strip().replace(self.FILE_NAME_PLACEHOLDER, fname)
binwalk.core.common.debug("subprocess.call(%s, stdout=%s, stderr=%s)" % (command, str(tmp), str(tmp))) binwalk.core.common.debug("subprocess.call(%s, stdout=%s, stderr=%s)" % (command, str(tmp), str(tmp)))
rval = subprocess.call(shlex.split(command), stdout=tmp, stderr=tmp) rval = subprocess.call(shlex.split(command), stdout=tmp, stderr=tmp)
binwalk.core.common.debug('External extractor command "%s" completed with return code %d' % (cmd, rval)) binwalk.core.common.debug('External extractor command "%s" completed with return code %d' % (cmd, rval))
if rval == 0: if rval == 0:
retval = True retval = True
else: else:
...@@ -587,10 +587,10 @@ class Extractor(Module): ...@@ -587,10 +587,10 @@ class Extractor(Module):
if binwalk.core.common.DEBUG or (not hasattr(e, 'errno') or e.errno != 2): if binwalk.core.common.DEBUG or (not hasattr(e, 'errno') or e.errno != 2):
binwalk.core.common.warning("Extractor.execute failed to run external extrator '%s': %s" % (str(cmd), str(e))) binwalk.core.common.warning("Extractor.execute failed to run external extrator '%s': %s" % (str(cmd), str(e)))
retval = None retval = None
if tmp is not None: if tmp is not None:
tmp.close() tmp.close()
return retval return retval
...@@ -34,10 +34,6 @@ class General(Module): ...@@ -34,10 +34,6 @@ class General(Module):
type=int, type=int,
kwargs={'block' : 0}, kwargs={'block' : 0},
description='Set file block size'), description='Set file block size'),
Option(long='continue',
short='k',
kwargs={'keep_going' : True},
description="Don't stop at the first match"),
Option(long='swap', Option(long='swap',
short='g', short='g',
type=int, type=int,
......
...@@ -24,10 +24,10 @@ class Signature(Module): ...@@ -24,10 +24,10 @@ class Signature(Module):
long='opcodes', long='opcodes',
kwargs={'enabled' : True, 'search_for_opcodes' : True}, kwargs={'enabled' : True, 'search_for_opcodes' : True},
description='Scan target file(s) for common executable opcode signatures'), description='Scan target file(s) for common executable opcode signatures'),
Option(short='C', #Option(short='C',
long='cast', # long='cast',
kwargs={'enabled' : True, 'cast_data_types' : True}, # kwargs={'enabled' : True, 'cast_data_types' : True},
description='Cast offsets as a given data type (use -y to specify the data type / endianness)'), # description='Cast offsets as a given data type (use -y to specify the data type / endianness)'),
Option(short='m', Option(short='m',
long='magic', long='magic',
kwargs={'enabled' : True, 'magic_files' : []}, kwargs={'enabled' : True, 'magic_files' : []},
......
import os
import zlib
import binwalk.core.common
import binwalk.core.plugin
class ZLIBExtractPlugin(binwalk.core.plugin.Plugin):
'''
Zlib extractor plugin.
'''
MODULES = ['Signature']
def init(self):
# If the extractor is enabled for the module we're currently loaded
# into, then register self.extractor as a zlib extraction rule.
if self.module.extractor.enabled:
self.module.extractor.add_rule(txtrule=None,
regex="^zlib compressed data",
extension="zlib",
cmd=self.extractor)
def extractor(self, fname):
outfile = os.path.splitext(fname)[0]
#print ("Extracting from '%s' to '%s'" % (fname, outfile))
try:
fpin = binwalk.core.common.BlockFile(fname)
fpout = binwalk.core.common.BlockFile(outfile, 'w')
plaintext = zlib.decompress(fpin.read())
fpout.write(plaintext)
fpin.close()
fpout.close()
except Exception, e:
pass
#print ("Failed to decompress data:", str(e))
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