Commit 458df42e by devttys0

Added ability to pass raw strings to be scanned via API

parent 11ad600c
...@@ -7,19 +7,8 @@ import sys ...@@ -7,19 +7,8 @@ import sys
import ast import ast
import hashlib import hashlib
import operator as op import operator as op
import binwalk.core.idb
from binwalk.core.compat import * from binwalk.core.compat import *
# This allows other modules/scripts to subclass BlockFile from a custom class. Defaults to io.FileIO.
if has_key(__builtins__, 'BLOCK_FILE_PARENT_CLASS'):
BLOCK_FILE_PARENT_CLASS = __builtins__['BLOCK_FILE_PARENT_CLASS']
else:
BLOCK_FILE_PARENT_CLASS = io.FileIO
# Special override for when we're running in IDA
if binwalk.core.idb.LOADED_IN_IDA:
BLOCK_FILE_PARENT_CLASS = binwalk.core.idb.IDBFileIO
# The __debug__ value is a bit backwards; by default it is set to True, but # The __debug__ value is a bit backwards; by default it is set to True, but
# then set to False if the Python interpreter is run with the -O option. # then set to False if the Python interpreter is run with the -O option.
if not __debug__: if not __debug__:
...@@ -222,8 +211,39 @@ class MathExpression(object): ...@@ -222,8 +211,39 @@ class MathExpression(object):
else: else:
raise TypeError(node) raise TypeError(node)
class StringFile(object):
'''
A class to allow access to strings as if they were read from a file.
Used internally as a conditional superclass to InternalBlockFile.
'''
def __init__(self, fname, mode='r'):
self.string = fname
self.name = "String"
self.args.size = len(self.string)
class BlockFile(BLOCK_FILE_PARENT_CLASS): def read(self, n=-1):
if n == -1:
data = self.string[self.total_read:]
else:
data = self.string[self.total_read:self.total_read+n]
return data
def tell(self):
return self.total_read
def write(self, *args, **kwargs):
pass
def seek(self, *args, **kwargs):
pass
def close(self):
pass
def BlockFile(fname, mode='r', subclass=io.FileIO, **kwargs):
# Defining a class inside a function allows it to be dynamically subclassed
class InternalBlockFile(subclass):
''' '''
Abstraction class for accessing binary files. Abstraction class for accessing binary files.
...@@ -452,16 +472,4 @@ class BlockFile(BLOCK_FILE_PARENT_CLASS): ...@@ -452,16 +472,4 @@ class BlockFile(BLOCK_FILE_PARENT_CLASS):
return (data, dlen) return (data, dlen)
def dup(self): return InternalBlockFile(fname, mode=mode, **kwargs)
'''
Creates a new BlockFile instance with all the same initialization settings as this one.
Returns new BlockFile object.
'''
return BlockFile(self.name,
length=self.length,
offset=self.offset,
block=self.base_block_read_size,
peek=self.base_peek_size,
swap=self.swap)
...@@ -354,10 +354,10 @@ class Module(object): ...@@ -354,10 +354,10 @@ class Module(object):
# Values in self.target_file_list are either already open files (BlockFile instances), or paths # Values in self.target_file_list are either already open files (BlockFile instances), or paths
# to files that need to be opened for scanning. # to files that need to be opened for scanning.
if isinstance(next_target_file, binwalk.core.common.BlockFile): if isinstance(next_target_file, str):
fp = next_target_file
else:
fp = self.config.open_file(next_target_file) fp = self.config.open_file(next_target_file)
else:
fp = next_target_file
self.status.clear() self.status.clear()
self.status.total = fp.length self.status.total = fp.length
......
# Module to process general user input options (scan length, starting offset, etc). # Module to process general user input options (scan length, starting offset, etc).
import io
import os import os
import sys import sys
import argparse import argparse
...@@ -67,6 +68,10 @@ class General(Module): ...@@ -67,6 +68,10 @@ class General(Module):
short=None, short=None,
type=binwalk.core.common.BlockFile, type=binwalk.core.common.BlockFile,
kwargs={'files' : []}), kwargs={'files' : []}),
# Hidden, API-only arguments
Option(long="string",
kwargs={'subclass' : binwalk.core.common.StringFile}),
] ]
KWARGS = [ KWARGS = [
...@@ -82,6 +87,7 @@ class General(Module): ...@@ -82,6 +87,7 @@ class General(Module):
Kwarg(name='files', default=[]), Kwarg(name='files', default=[]),
Kwarg(name='show_help', default=False), Kwarg(name='show_help', default=False),
Kwarg(name='keep_going', default=False), Kwarg(name='keep_going', default=False),
Kwarg(name='subclass', default=io.FileIO),
] ]
PRIMARY = False PRIMARY = False
...@@ -89,6 +95,10 @@ class General(Module): ...@@ -89,6 +95,10 @@ class General(Module):
def load(self): def load(self):
self.target_files = [] self.target_files = []
# A special case for when we're loaded into IDA
if self.subclass == io.FileIO and binwalk.core.idb.LOADED_IN_IDA:
self.subclass = binwalk.core.idb.IDBFileIO
# Order is important with these two methods # Order is important with these two methods
self._open_target_files() self._open_target_files()
self._set_verbosity() self._set_verbosity()
...@@ -141,7 +151,7 @@ class General(Module): ...@@ -141,7 +151,7 @@ class General(Module):
if swap is None: if swap is None:
swap = self.swap_size swap = self.swap_size
return binwalk.core.common.BlockFile(fname, length=length, offset=offset, swap=swap, block=block, peek=peek) return binwalk.core.common.BlockFile(fname, subclass=self.subclass, length=length, offset=offset, swap=swap, block=block, peek=peek)
def _open_target_files(self): def _open_target_files(self):
''' '''
...@@ -151,7 +161,7 @@ class General(Module): ...@@ -151,7 +161,7 @@ class General(Module):
# Validate the target files listed in target_files # Validate the target files listed in target_files
for tfile in self.files: for tfile in self.files:
# Ignore directories. # Ignore directories.
if not os.path.isdir(tfile): if not self.subclass == io.FileIO or not os.path.isdir(tfile):
# Make sure we can open the target files # Make sure we can open the target files
try: try:
self.target_files.append(self.open_file(tfile)) self.target_files.append(self.open_file(tfile))
......
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