Commit f4345ded by devttys0

Fixed BlockFile.read bug

parent 338d94a4
......@@ -316,8 +316,18 @@ class BlockFile(io.FileIO):
else:
break
self.total_read += len(data)
return bytes2str(data)
def _internal_read(self, n=-1):
'''
Same as self.read, but doesn't increment self.total_read.
For use by self.read_block.
'''
data = self.read(n)
self.total_read -= len(data)
return data
def seek(self, n, whence=os.SEEK_SET):
if whence == os.SEEK_SET:
self.total_read = n
......@@ -341,7 +351,7 @@ class BlockFile(io.FileIO):
# Read in READ_BLOCK_SIZE plus MAX_TRAILING_SIZE bytes, but return a max dlen value
# of READ_BLOCK_SIZE. This ensures that there is a MAX_TRAILING_SIZE buffer at the
# end of the returned data in case a signature is found at or near data[dlen].
data = self.read(self.READ_BLOCK_SIZE + self.MAX_TRAILING_SIZE)
data = self._internal_read(self.READ_BLOCK_SIZE + self.MAX_TRAILING_SIZE)
if data and data is not None:
......
......@@ -495,12 +495,13 @@ class Modules(object):
else:
parser.add_argument('--' + module_option.long, action=action, dest=module_option.long)
print argv
args, unknown = parser.parse_known_args(argv)
args = args.__dict__
for module_option in module.CLI:
if module_option.type in [io.FileIO, argparse.FileType, binwalk.common.BlockFile]:
if module_option.type == binwalk.common.BlockFile:
for k in get_keys(module_option.kwargs):
kwargs[k] = []
......
......@@ -41,10 +41,6 @@ class Configuration(binwalk.module.Module):
short='c',
kwargs={'csv' : True},
description='Log results to file in CSV format'),
binwalk.module.ModuleOption(long='skip-unopened',
short='O',
kwargs={'skip_unopened' : True},
description='Ignore file open errors and process only the files that can be opened'),
binwalk.module.ModuleOption(long='term',
short='t',
kwargs={'format_to_terminal' : True},
......@@ -77,13 +73,15 @@ class Configuration(binwalk.module.Module):
binwalk.module.ModuleKwarg(name='format_to_terminal', default=False),
binwalk.module.ModuleKwarg(name='quiet', default=False),
binwalk.module.ModuleKwarg(name='verbose', default=[]),
binwalk.module.ModuleKwarg(name='skip_unopened', default=False),
binwalk.module.ModuleKwarg(name='files', default=[]),
binwalk.module.ModuleKwarg(name='show_help', default=False),
]
def load(self):
self.target_files = []
self._set_verbosity()
self._open_target_files()
self.settings = binwalk.config.Config()
self.display = binwalk.display.Display(log=self.log_file,
......@@ -96,9 +94,6 @@ class Configuration(binwalk.module.Module):
binwalk.module.show_help()
sys.exit(0)
self._open_target_files()
self._set_verbosity()
def __del__(self):
self._cleanup()
......@@ -135,18 +130,14 @@ class Configuration(binwalk.module.Module):
if not os.path.isdir(tfile):
# Make sure we can open the target files
try:
self.target_files.append(binwalk.common.BlockFile(tfile, length=self.length, offset=self.offset))
fp = binwalk.common.BlockFile(tfile, length=self.length, offset=self.offset)
self.target_files.append(fp)
except KeyboardInterrupt as e:
raise e
except Exception as e:
self.error(description="Cannot open file : %s" % str(e))
# Unless -O was specified, don't run the scan unless we are able to scan all specified files
if len(self.target_files) != len(self.files) and not self.skip_unopened:
failed_open_count = len(self.files) - len(self.target_files)
if failed_open_count > 1:
plural = 's'
else:
plural = ''
raise Exception("Failed to open %d file%s for scanning" % (failed_open_count, plural))
# If no files could be opened, quit permaturely
if len(self.target_files) == 0:
raise Exception("Failed to open any files for scanning")
......@@ -21,11 +21,18 @@ class Signature(binwalk.module.Module):
type=[],
dtype='file',
description='Specify a custom magic file to use'),
binwalk.module.ModuleOption(short='R',
long='raw-bytes',
nargs=1,
kwargs={'raw_bytes' : None},
type=str,
description='Specify a sequence of bytes to search for'),
]
KWARGS = [
binwalk.module.ModuleKwarg(name='enabled', default=False),
binwalk.module.ModuleKwarg(name='magic_files', default=[]),
binwalk.module.ModuleKwarg(name='raw_bytes', default=None),
]
HEADER = ["DECIMAL", "HEX", "DESCRIPTION"]
......@@ -41,6 +48,10 @@ class Signature(binwalk.module.Module):
self.smart = binwalk.smartsignature.SmartSignature(self.filter, ignore_smart_signatures=False)
self.parser = binwalk.parser.MagicParser(self.filter, self.smart)
# If a raw byte sequence was specified, build a magic file from that instead of using the default magic files
if self.raw_bytes is not None:
self.magic_files = [self.parser.file_from_string(self.raw_bytes)]
# Use the system default magic file if no other was specified
if not self.magic_files:
# Append the user's magic file first so that those signatures take precedence
......@@ -54,8 +65,8 @@ class Signature(binwalk.module.Module):
self.magic = magic.open(self.MAGIC_FLAGS)
self.magic.load(str2bytes(self.mfile))
# Once the temporary magic file is loaded into libmagic, we don't need it anymore; delete the temp file
self.parser.rm_magic_file()
# Once the temporary magic files are loaded into libmagic, we don't need them anymore; delete the temp files
self.parser.rm_magic_files()
def validate(self, r):
'''
......@@ -77,7 +88,7 @@ class Signature(binwalk.module.Module):
break
current_block_offset = 0
block_start = fp.tell() - dlen
block_start = fp.total_read - dlen
self.status.completed = block_start - fp.offset
for candidate_offset in self.parser.find_signature_candidates(data, dlen):
......
......@@ -60,9 +60,9 @@ class MagicParser:
except Exception:
pass
def rm_magic_file(self):
def rm_magic_files(self):
'''
Cleans up the temporary magic file generated by self.parse.
Cleans up the temporary magic file(s).
Returns None.
'''
......@@ -72,6 +72,13 @@ class MagicParser:
raise e
except Exception:
pass
try:
self.raw_fd.close()
except KeyboardInterrupt as e:
raise e
except Exception:
pass
def cleanup(self):
'''
......@@ -79,14 +86,7 @@ class MagicParser:
Returns None.
'''
self.rm_magic_file()
try:
self.raw_fd.close()
except KeyboardInterrupt as e:
raise e
except Exception:
pass
self.rm_magic_files()
def file_from_string(self, signature_string, offset=0, display_name=DEFAULT_DISPLAY_NAME):
'''
......
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