Merge branch 'master' into temporary branch debian
authorSophie Brun <sophie@freexian.com>
Fri, 30 Jan 2015 10:10:15 +0000 (11:10 +0100)
committerSophie Brun <sophie@freexian.com>
Fri, 30 Jan 2015 10:10:15 +0000 (11:10 +0100)
121 files changed:
API.md [new file with mode: 0644]
INSTALL.md [new file with mode: 0644]
LICENSE [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
README.md [new file with mode: 0644]
bin/binwalk [deleted file]
binwalk/__init__.py [deleted file]
binwalk/common.py [deleted file]
binwalk/compression.py [deleted file]
binwalk/config.py [deleted file]
binwalk/config/extract.conf [deleted file]
binwalk/entropy.py [deleted file]
binwalk/extractor.py [deleted file]
binwalk/filter.py [deleted file]
binwalk/hexdiff.py [deleted file]
binwalk/magic/binarch [deleted file]
binwalk/magic/bincast [deleted file]
binwalk/magic/binwalk [deleted file]
binwalk/magic/zlib [deleted file]
binwalk/maths.py [deleted file]
binwalk/parser.py [deleted file]
binwalk/plugins.py [deleted file]
binwalk/plugins/armopcodes.py [deleted file]
binwalk/plugins/cpio.py [deleted file]
binwalk/plugins/strcompat.py [deleted file]
binwalk/plugins/zlib.py [deleted file]
binwalk/prettyprint.py [deleted file]
binwalk/smartsignature.py [deleted file]
binwalk/smartstrings.py [deleted file]
binwalk/update.py [deleted file]
configure [new file with mode: 0755]
configure.ac [new file with mode: 0644]
debian/README.source [new file with mode: 0644]
debian/binwalk.1 [new file with mode: 0644]
debian/changelog
debian/compat
debian/control
debian/copyright
debian/docs
debian/manpages [new file with mode: 0644]
debian/patches/0001-Some-typos-fixed.patch [new file with mode: 0644]
debian/patches/0002-fix-hardening-no-fortify-functions-debian-lintian-wa.patch [new file with mode: 0644]
debian/patches/0003-fix-return-exit-value-shared-libs-cannot-use-exit-bu.patch [new file with mode: 0644]
debian/patches/destdir.patch [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]
debian/preinst [deleted file]
debian/rules
debian/watch
debian_quick_install.sh [deleted file]
deps.sh [new file with mode: 0755]
docs/API [deleted file]
docs/LICENSE [deleted file]
docs/README [deleted file]
magic/archives [deleted file]
magic/bootloaders [deleted file]
magic/compressed [deleted file]
magic/crypto [deleted file]
magic/executables [deleted file]
magic/filesystems [deleted file]
magic/firmware [deleted file]
magic/images [deleted file]
magic/kernels [deleted file]
magic/lzma [deleted file]
magic/sql [deleted file]
setup.py
src/C/Makefile [new file with mode: 0644]
src/C/compress/Makefile [new file with mode: 0644]
src/C/compress/README [new file with mode: 0644]
src/C/compress/compress42.c [new file with mode: 0644]
src/C/miniz/Makefile [new file with mode: 0644]
src/C/miniz/README [new file with mode: 0644]
src/C/miniz/tinfl.c [new file with mode: 0644]
src/binwalk/__init__.py [new file with mode: 0644]
src/binwalk/config/extract.conf [new file with mode: 0644]
src/binwalk/core/C.py [new file with mode: 0644]
src/binwalk/core/__init__.py [new file with mode: 0644]
src/binwalk/core/common.py [new file with mode: 0644]
src/binwalk/core/compat.py [new file with mode: 0644]
src/binwalk/core/display.py [new file with mode: 0644]
src/binwalk/core/filter.py [new file with mode: 0644]
src/binwalk/core/magic.py [new file with mode: 0644]
src/binwalk/core/module.py [new file with mode: 0644]
src/binwalk/core/parser.py [new file with mode: 0644]
src/binwalk/core/plugin.py [new file with mode: 0644]
src/binwalk/core/settings.py [new file with mode: 0644]
src/binwalk/core/smart.py [new file with mode: 0644]
src/binwalk/libs/.gitignore [new file with mode: 0644]
src/binwalk/magic/binarch [new file with mode: 0644]
src/binwalk/magic/bincast [new file with mode: 0644]
src/binwalk/magic/binwalk [new file with mode: 0644]
src/binwalk/modules/__init__.py [new file with mode: 0644]
src/binwalk/modules/binvis.py [new file with mode: 0644]
src/binwalk/modules/compression.py [new file with mode: 0644]
src/binwalk/modules/entropy.py [new file with mode: 0644]
src/binwalk/modules/extractor.py [new file with mode: 0644]
src/binwalk/modules/general.py [new file with mode: 0644]
src/binwalk/modules/hashmatch.py [new file with mode: 0644]
src/binwalk/modules/heuristics.py [new file with mode: 0644]
src/binwalk/modules/hexdiff.py [new file with mode: 0644]
src/binwalk/modules/signature.py [new file with mode: 0644]
src/binwalk/plugins/compressd.py [new file with mode: 0644]
src/binwalk/plugins/cpio.py [new file with mode: 0644]
src/binwalk/plugins/lzmamod.py [new file with mode: 0644]
src/binwalk/plugins/tar.py [new file with mode: 0644]
src/binwalk/plugins/zlibvalid.py [new file with mode: 0644]
src/magic/archives [new file with mode: 0644]
src/magic/bootloaders [new file with mode: 0644]
src/magic/compressed [new file with mode: 0644]
src/magic/crypto [new file with mode: 0644]
src/magic/executables [new file with mode: 0644]
src/magic/filesystems [new file with mode: 0644]
src/magic/firmware [new file with mode: 0644]
src/magic/images [new file with mode: 0644]
src/magic/kernels [new file with mode: 0644]
src/magic/lzma [new file with mode: 0644]
src/magic/misc [new file with mode: 0644]
src/magic/network [new file with mode: 0644]
src/magic/sql [new file with mode: 0644]
src/scripts/binwalk [new file with mode: 0755]
src/scripts/examples/binwalk_simple.py [new file with mode: 0755]
src/scripts/examples/signature_scan.py [new file with mode: 0755]

diff --git a/API.md b/API.md
new file mode 100644 (file)
index 0000000..ba7c441
--- /dev/null
+++ b/API.md
@@ -0,0 +1,85 @@
+Description
+===========
+
+The binwalk python module can be used by any python script to programmatically perform binwalk scans and obtain the results of those scans. 
+
+The classes, methods and objects in the binwalk modules are documented via pydoc, including examples, so those interested in using the binwalk module are encouraged to look there. However, several common usage examples are provided here to help jump-start development efforts.
+
+
+Binwalk Scripting
+=================
+
+Each of binwalk's features (signature scans, entropy analysis, etc) are implemented as separate modules. These modules can be invoked via the binwalk.core.module.Modules class, which makes scripting trivial through its execute method.
+
+In fact, the binwalk command line utility can be duplicated nearly entirely with just two lines of code:
+
+```python
+import binwalk
+binwalk.Modules().execute()
+```
+
+The Modules class constructor as well as the execute method accept both Python args and kwargs corresponding to the normal command line options accepted by the binwalk command line utility, providing a large amount of freedom in how you choose to specify binwalk options (if none are specified, sys.argv is used by default).
+
+For example, to execute a signature scan, you at the very least have to specify the --signature command line option, as well as a list of files to scan. This can be done in a number of ways:
+
+```python
+binwalk.Modules().execute('firmware1.bin', 'firmware2.bin', signature=True)
+
+binwalk.Modules().execute('firmware1.bin', 'firmware2.bin', **{'signature' : True})
+        
+binwalk.Modules().execute(*['firmware1.bin', 'firmware2.bin'], signature=True)
+        
+binwalk.Modules().execute(*['--signature', 'firmware1.bin', 'firmware2.bin',])
+
+binwalk.Modules().execute('--signature', 'firmware1.bin', 'firmware2.bin')
+```
+
+All args and kwargs keys/values correspond to binwalk's command line options. Either args or kwargs, or a combination of the two may be used, with the following caveats:
+
+* All command line switches passed via args must be preceeded by hyphens (not required for kwargs)
+* All file names must be passed via args, not kwargs
+
+Accessing Scan Results
+======================
+
+binwalk.Modules.execute returns a list of objects. Each object corresponds to a module that was run. For example, if you specified --signature and --entropy, then both the Signature and Entropy modules would be executed and you would be returned a list of two objects.
+
+The two attributes of interest for each object are the 'results' and 'errors' objects. Each is a list of binwalk.core.module.Result and binwalk.core.module.Error objects respectively. Each Result or Error object may contain custom attributes set by each module, but are guarunteed to have at least the following attributes (though modules are not required to populate all attributes):
+
+|  Attribute  | Description |
+|-------------|-------------|
+| offset      | The file offset of the result/error (usually unused for errors) |
+| description | The result/error description, as displayed to the user |
+| module      | Name of the module that generated the result/error |
+| file        | The file object of the scanned file |
+| valid       | Set to True if the result if value, False if invalid (usually unused for errors) |
+| display     | Set to True to display the result to the user, False to hide it (usually unused for errors) |
+| extract     | Set to True to flag this result for extraction (not used for errors) |
+| plot        | Set to Flase to exclude this result from entropy plots (not used for errors) |
+
+binwalk.core.module.Error has the additional guarunteed attribute:
+
+|  Attribute  | Description |
+|-------------|-------------|
+| exception   | Contains the Python execption object if the encountered error was an exception |
+
+Thus, scan results and errors can be programatically accessed rather easily:
+
+```python
+for module in binwalk.Modules().execute('firmware1.bin', 'firmware2.bin', signature=True):
+    print ("%s Results:" % module.name)
+    for result in module.results:
+        print ("\t%s    0x%.8X    %s" % (result.file.name, result.offset, result.description))
+```
+
+Module Exceptions
+=================
+
+The only expected exception that should be raised by binwalk.Modules is that of binwalk.ModuleException. This exception is thrown only if a required module encountered a fatal error (e.g., one of the specified target files could not be opened):
+
+```python
+try:
+    binwalk.Modules().execute()
+except binwalk.ModuleException as e:
+    print ("Critical failure:", e)
+```
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644 (file)
index 0000000..9165340
--- /dev/null
@@ -0,0 +1,101 @@
+Before You Start
+================
+
+Binwalk supports Python 2.7 - 3.x. Although binwalk is slightly faster in Python 3, the Python OpenGL bindings are still experimental for Python 3, so Python 2.7 is recommended.
+
+The following installation procedures assume that you are installing binwalk to be run using Python 2.7. If you want to use binwalk in Python 3, some package
+names and installation procedures may differ slightly.
+
+Installation
+============
+
+Installation follows the typical configure/make process (standard development tools such as gcc, make, and Python must be installed in order to build):
+
+    $ ./configure
+    $ make
+    $ sudo make install
+
+Binwalk's core features will work out of the box without any additional dependencies. However, to take advantage of binwalk's graphing and extraction capabilities, multiple supporting utilities/packages need to be installed.
+
+To ease "dependency hell", a shell script named `deps.sh` is included which attempts to install all required dependencies for Debian and RedHat based systems:
+
+    $ ./deps.sh
+
+If you are running a different system, or prefer to install these dependencies manually, see the Dependencies section below.
+
+Dependencies
+============
+
+The following dependencies are only required for optional binwalk features, such as file extraction and graphing capabilities. Unless otherwise specified, these dependencies are available from most Linux package managers.
+
+Binwalk uses [pyqtgraph](http://www.pyqtgraph.org) to generate graphs and visualizations, which requires the following: 
+
+    libqt4-opengl 
+    python-opengl 
+    python-qt4 
+    python-qt4-gl 
+    python-numpy 
+    python-scipy
+
+Binwalk relies on multiple external utilties in order to automatically extract/decompress files and data:
+
+    mtd-utils
+    zlib1g-dev
+    liblzma-dev
+    ncompress
+    gzip
+    bzip2
+    tar
+    arj
+    p7zip
+    cabextract
+    p7zip-full
+    openjdk-6-jdk
+    firmware-mod-kit [https://code.google.com/p/firmware-mod-kit]
+
+Bundled Software
+================
+
+For convenience, the following libraries are bundled with binwalk and will not conflict with system-wide libraries:
+
+    libmagic
+    libfuzzy
+    pyqtgraph
+
+Installation of any individual bundled library can be disabled at build time:
+
+    $ ./configure --disable-libmagic --disable-libfuzzy --disable-pyqtgraph
+
+Alternatively, installation of all bundled libraries can be disabled at build time:
+
+    $ ./configure --disable-bundles
+
+If a bundled library is disabled, the equivalent library must be installed to a standard system library location (e.g., `/usr/lib`, `/usr/local/lib`, etc) in order for binwalk to function properly.
+
+**Note:** If the bundled libmagic library is not used, be aware that:
+
+1. Some versions of libmagic have known bugs that are triggered by binwalk under some circumstances.
+2. Minor version releases of libmagic may not be backwards compatible with each other and installation of the wrong version of libmagic may cause binwalk to fail to function properly. 
+3. Conversely, updating libmagic to a version that works with binwalk may cause other utilities that rely on libmagic to fail. 
+
+Currently, the following libmagic versions are known to work properly with binwalk (other versions may or may not work):
+
+    5.18
+    5.19
+
+
+Specifying a Python Interpreter
+===============================
+
+The default python interpreter used during install is the system-wide `python` interpreter. A different interpreter (e.g., `python2`, `python3`) can be specified at build time:
+
+    $ ./configure --with-python=python3
+
+
+Uninstallation
+==============
+
+The following command will remove binwalk from your system. Note that this will *not* remove manually installed packages, or utilities installed via deps.sh:
+
+    $ sudo make uninstall
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..ae9d847
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2010-2014 Craig Heffner
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..ac2e3d9
--- /dev/null
@@ -0,0 +1,55 @@
+export CC=@CC@
+export CFLAGS=@CFLAGS@
+export SONAME=@SONAME@
+export SOEXT=@SOEXT@
+export prefix=@prefix@
+export exec_prefix=@exec_prefix@
+export LIBDIR=@libdir@
+export INSTALL_OPTIONS=@INSTALL_OPTIONS@
+export PLATFORM=@PLATFORM@
+export BUILD_MAGIC=@BUILD_MAGIC@
+export BUILD_FUZZY=@BUILD_FUZZY@
+export BUILD_PYQTGRAPH=@BUILD_PYQTGRAPH@
+export PYLIBDIR="./binwalk/libs"
+
+BUILD_C_LIBS=@BUILD_C_LIBS@
+BUILD_BUNDLES=@BUILD_BUNDLES@
+PYTHON=@PYTHON@
+
+SRC_C_DIR="./src/C"
+SRC_BUNDLES_DIR="./src/bundles"
+
+ifeq ($(strip $(prefix)),)
+       PREFIX=""
+else
+       PREFIX="--prefix=$(prefix)"
+endif
+
+.PHONY: all install build deps clean uninstall
+
+all: build
+
+install: build
+       $(PYTHON) ./setup.py install $(PREFIX)
+
+build:
+       if [ "$(BUILD_C_LIBS)" -eq "1" ]; then make -C $(SRC_C_DIR); fi
+       if [ "$(BUILD_BUNDLES)" -eq "1" ]; then make -C $(SRC_BUNDLES_DIR); fi
+       $(PYTHON) ./setup.py build
+
+deps:
+       ./deps.sh
+
+clean:
+       if [ "$(BUILD_C_LIBS)" -eq "1" ]; then make -C $(SRC_C_DIR) clean; fi
+       if [ "$(BUILD_BUNDLES)" -eq "1" ]; then make -C $(SRC_BUNDLES_DIR) clean; fi
+       $(PYTHON) ./setup.py clean
+
+distclean: clean
+       if [ "$(BUILD_C_LIBS)" -eq "1" ]; then make -C $(SRC_C_DIR) distclean; fi
+       if [ "$(BUILD_BUNDLES)" -eq "1" ]; then make -C $(SRC_BUNDLES_DIR) distclean; fi
+       rm -rf Makefile config.* *.cache
+
+uninstall:
+       $(PYTHON) ./setup.py uninstall --pydir=`find $(prefix)/lib -name binwalk | head -1` --pybin=`find $(prefix)/bin -name binwalk | head -1`
+
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..926b841
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+Description
+===========
+
+Binwalk is a fast, easy to use tool for analyzing, reverse engineering, and extracting firmware images.
+
+Installation
+============
+
+Binwalk follows the standard Unix configure/make installation procedure:
+
+    $ ./configure
+    $ make
+    $ sudo make install
+
+For convenience, optional dependencies for automatic extraction and graphical visualizations can be installed by running the included `deps.sh` script:
+
+    $ ./deps.sh
+
+If your system is not supported by `deps.sh`, or if you wish to manually install dependencies, see `INSTALL.md`.
+
+For advanced installation options, see `INSTALL.md`.
+
+Usage
+=====
+
+Basic usage is simple:
+
+    $ binwalk firmware.bin
+
+For additional examples and desriptions of advanced options, see the [wiki](https://github.com/devttys0/binwalk/wiki).
diff --git a/bin/binwalk b/bin/binwalk
deleted file mode 100755 (executable)
index b872469..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import os.path
-import binwalk
-from threading import Thread
-from getopt import GetoptError, gnu_getopt as GetOpt
-
-def display_status():
-       global bwalk
-
-       while bwalk is not None:
-               # Display the current scan progress when the enter key is pressed.
-               try:
-                       raw_input()
-                       print "Progress: %.2f%% (%d / %d)\n" % (((float(bwalk.total_scanned) / float(bwalk.scan_length)) * 100), bwalk.total_scanned, bwalk.scan_length)
-               except Exception, e:
-                       pass
-
-def examples():
-       name = os.path.basename(sys.argv[0])
-
-       print """
-Scanning firmware for file signatures:
-
-\t$ %s firmware.bin
-
-Extracting files from firmware:
-
-\t$ %s -Me firmware.bin
-
-Hueristic compression/encryption analysis:
-
-\t$ %s -H firmware.bin
-
-Scanning firmware for executable code:
-
-\t$ %s -A firmware.bin
-
-Performing a firmware strings analysis:
-
-\t$ %s -S firmware.bin
-
-Performing a firmware entropy analysis:
-
-\t$ %s -E firmware.bin
-
-Display identified file signatures on entropy graph:
-
-\t$ %s -EB firmware.bin
-
-Diffing multiple files:
-
-\t$ %s -W firmware1.bin firmware2.bin firmware3.bin
-
-See http://code.google.com/p/binwalk/wiki/TableOfContents for more.
-""" % (name, name, name, name, name, name, name, name)
-       sys.exit(0)
-
-def usage(fd):
-       fd.write("\n")
-       
-       fd.write("Binwalk v%s\n" % binwalk.Config.VERSION)
-       fd.write("Craig Heffner, http://www.devttys0.com\n")
-       fd.write("\n")
-       
-       fd.write("Usage: %s [OPTIONS] [FILE1] [FILE2] [FILE3] ...\n" % os.path.basename(sys.argv[0]))
-       fd.write("\n")
-       
-       fd.write("Signature Analysis:\n")
-       fd.write("\t-B, --binwalk                 Perform a file signature scan (default)\n")
-       fd.write("\t-R, --raw-bytes=<string>      Search for a custom signature\n")
-       fd.write("\t-A, --opcodes                 Scan for executable code signatures\n")
-       fd.write("\t-C, --cast                    Cast file contents as various data types\n")
-       fd.write("\t-m, --magic=<file>            Specify an alternate magic file to use\n")
-       fd.write("\t-x, --exclude=<filter>        Exclude matches that have <filter> in their description\n")
-       fd.write("\t-y, --include=<filter>        Only search for matches that have <filter> in their description\n")
-       fd.write("\t-I, --show-invalid            Show results marked as invalid\n")
-       fd.write("\t-T, --ignore-time-skew        Do not show results that have timestamps more than 1 year in the future\n")
-       fd.write("\t-k, --keep-going              Show all matching results at a given offset, not just the first one\n")
-       fd.write("\t-b, --dumb                    Disable smart signature keywords\n")
-       fd.write("\n")
-
-       fd.write("Strings Analysis:\n")
-       fd.write("\t-S, --strings                 Scan for ASCII strings (may be combined with -B, -R, -A, or -E)\n")
-       fd.write("\t-s, --strlen=<n>              Set the minimum string length to search for (default: 3)\n")
-       fd.write("\n")
-       
-       fd.write("Entropy Analysis:\n")
-       fd.write("\t-E, --entropy                 Plot file entropy (may be combined with -B, -R, -A, or -S)\n")
-       fd.write("\t-H, --heuristic               Identify unknown compression/encryption based on entropy heuristics (implies -E)\n")
-       fd.write("\t-K, --block=<int>             Set the block size for entropy analysis (default: %d)\n" % binwalk.entropy.FileEntropy.DEFAULT_BLOCK_SIZE)
-       fd.write("\t-a, --gzip                    Use gzip compression ratios to measure entropy\n")
-       fd.write("\t-N, --no-plot                 Do not generate an entropy plot graph\n")
-       fd.write("\t-F, --marker=<offset:name>    Add a marker to the entropy plot graph\n")
-       fd.write("\t-Q, --no-legend               Omit the legend from the entropy plot graph\n")
-       fd.write("\t-J, --save-plot               Save plot as an SVG (implied if multiple files are specified)\n")
-       fd.write("\n")
-
-       fd.write("Binary Diffing:\n")
-       fd.write("\t-W, --diff                    Hexdump / diff the specified files\n")
-       fd.write("\t-K, --block=<int>             Number of bytes to display per line (default: %d)\n" % binwalk.hexdiff.HexDiff.DEFAULT_BLOCK_SIZE)
-       fd.write("\t-G, --green                   Only show hex dump lines that contain bytes which were the same in all files\n")
-       fd.write("\t-i, --red                     Only show hex dump lines that contain bytes which were different in all files\n")
-       fd.write("\t-U, --blue                    Only show hex dump lines that contain bytes which were different in some files\n")
-       fd.write("\t-w, --terse                   Diff all files, but only display a hex dump of the first file\n")
-       fd.write("\n")
-
-       fd.write("Extraction Options:\n")
-       fd.write("\t-D, --dd=<type:ext[:cmd]>     Extract <type> signatures, give the files an extension of <ext>, and execute <cmd>\n")
-       fd.write("\t-e, --extract=[file]          Automatically extract known file types; load rules from file, if specified\n")
-       fd.write("\t-M, --matryoshka              Recursively scan extracted files, up to 8 levels deep\n")
-       fd.write("\t-r, --rm                      Cleanup extracted files and zero-size files\n")
-       fd.write("\t-d, --delay                   Delay file extraction for files with known footers\n")
-       fd.write("\n")
-
-       fd.write("Plugin Options:\n")
-       fd.write("\t-X, --disable-plugin=<name>   Disable a plugin by name\n")
-       fd.write("\t-Y, --enable-plugin=<name>    Enable a plugin by name\n")
-       fd.write("\t-p, --disable-plugins         Do not load any binwalk plugins\n")
-       fd.write("\t-L, --list-plugins            List all user and system plugins by name\n")
-       fd.write("\n")
-
-       fd.write("General Options:\n")  
-       fd.write("\t-o, --offset=<int>            Start scan at this file offset\n")
-       fd.write("\t-l, --length=<int>            Number of bytes to scan\n")
-       fd.write("\t-g, --grep=<text>             Grep results for the specified text\n")
-       fd.write("\t-f, --file=<file>             Log results to file\n")
-       fd.write("\t-c, --csv                     Log results to file in csv format\n")
-       fd.write("\t-O, --skip-unopened           Ignore file open errors and process only the files that can be opened\n")
-       fd.write("\t-t, --term                    Format output to fit the terminal window\n")
-       fd.write("\t-q, --quiet                   Supress output to stdout\n")
-       fd.write("\t-v, --verbose                 Be verbose (specify twice for very verbose)\n")
-       fd.write("\t-u, --update                  Update magic signature files\n")
-       fd.write("\t-?, --examples                Show example usage\n")
-       fd.write("\t-h, --help                    Show help output\n")
-       fd.write("\n")
-
-       if fd == sys.stderr:
-               sys.exit(1)
-       else:
-               sys.exit(0)
-
-def main():
-       # The Binwalk class instance must be global so that the display_status thread can access it.
-       global bwalk
-
-       MIN_ARGC = 2
-
-       requested_scans = []    
-       offset = 0
-       length = 0
-       strlen = 0
-       verbose = 0
-       matryoshka = 1
-       block_size = 0
-       failed_open_count = 0
-       quiet = False
-       do_comp = False
-       do_files = False
-       log_file = None
-       do_csv = False
-       save_plot = False
-       show_plot = True
-       show_legend = True
-       entropy_scan = False
-       enable_plugins = True
-       show_invalid = False
-       entropy_algorithm = None
-       format_to_terminal = False
-       custom_signature = None
-       delay_extraction = False
-       ignore_time_skew = True
-       extract_rules_file = None
-       ignore_failed_open = False
-       extract_from_config = False
-       show_single_hex_dump = False
-       cleanup_after_extract = False
-       explicit_signature_scan = False
-       ignore_signature_keywords = False
-       magic_flags = binwalk.magic.MAGIC_NONE
-       markers = []
-       magic_files = []
-       file_opt_list = []
-       target_files = []
-       greps = []
-       excludes = []
-       searches = []
-       extracts = []
-       options = []
-       arguments = []
-       plugin_whitelist = []
-       plugin_blacklist = []
-
-       config = binwalk.Config()
-
-       short_options = "AaBbCcdEeGHhIiJkLMNnOPpQqrSTtUuvWw?D:F:f:g:K:o:l:m:R:s:X:x:Y:y:"
-       long_options = [
-                       "rm",
-                       "help",
-                       "green",
-                       "red",
-                       "blue",
-                       "examples",
-                       "quiet", 
-                       "csv",
-                       "verbose",
-                       "opcodes",
-                       "cast",
-                       "update",
-                       "binwalk", 
-                       "keep-going",
-                       "show-invalid",
-                       "ignore-time-skew",
-                       "profile",
-                       "delay",
-                       "skip-unopened",
-                       "term",
-                       "tim",
-                       "terse",
-                       "diff",
-                       "dumb",
-                       "entropy",
-                       "heuristic",
-                       "math",
-                       "gzip",
-                       "save-plot",
-                       "no-plot",
-                       "no-legend", 
-                       "matryoshka",
-                       "strings",
-                       "list-plugins",
-                       "disable-plugins",
-                       "disable-plugin=",
-                       "enable-plugin=",
-                       "marker=",
-                       "strlen=",
-                       "file=", 
-                       "block=",
-                       "offset=", 
-                       "length=", 
-                       "exclude=",
-                       "include=",
-                       "search=",
-                       "extract=",
-                       "dd=",
-                       "grep=",
-                       "magic=",
-                       "raw-bytes=",
-       ]
-
-       # Require at least one argument (the target file)
-       if len(sys.argv) < MIN_ARGC:
-               usage(sys.stderr)
-
-       try:
-               opts, args = GetOpt(sys.argv[1:], short_options, long_options)
-       except GetoptError, e:
-               sys.stderr.write("%s\n" % str(e))
-               usage(sys.stderr)
-
-       for opt, arg in opts:
-               if opt in ("-h", "--help"):
-                       usage(sys.stdout)
-               elif opt in ("-?", "--examples"):
-                       examples()
-               elif opt in ("-d", "--delay"):
-                       delay_extraction = True
-               elif opt in ("-f", "--file"):
-                       log_file = arg
-               elif opt in ("-c", "--csv"):
-                       do_csv = True
-               elif opt in ("-q", "--quiet"):
-                       quiet = True
-               elif opt in ("-s", "--strlen"):
-                       strlen = binwalk.common.str2int(arg)
-               elif opt in ("-Q", "--no-legend"):
-                       show_legend = False
-               elif opt in ("-J", "--save-plot"):
-                       save_plot = True
-               elif opt in ("-N", "--no-plot"):
-                       show_plot = False
-               elif opt in ("-E", "--entropy"):
-                       requested_scans.append(binwalk.Binwalk.ENTROPY)
-               elif opt in ("-W", "--diff"):
-                       requested_scans.append(binwalk.Binwalk.HEXDIFF)
-               elif opt in ("-w", "--terse"):
-                       show_single_hex_dump = True
-               elif opt in ("-a", "--gzip"):
-                       entropy_algorithm = 'gzip'
-               elif opt in("-t", "--term", "--tim"):
-                       format_to_terminal = True
-               elif opt in("-p", "--disable-plugins"):
-                       enable_plugins = False
-               elif opt in ("-b", "--dumb"):
-                       ignore_signature_keywords = True
-               elif opt in ("-v", "--verbose"):
-                       verbose += 1
-               elif opt in ("-S", "--strings"):
-                       requested_scans.append(binwalk.Binwalk.STRINGS)
-               elif opt in ("-O", "--skip-unopened"):
-                       ignore_failed_open = True
-               elif opt in ("-o", "--offset"):
-                       offset = binwalk.common.str2int(arg)
-               elif opt in ("-l", "--length"):
-                       length = binwalk.common.str2int(arg)
-               elif opt in ("-y", "--search", "--include"):
-                       searches.append(arg)
-               elif opt in ("-x", "--exclude"):
-                       excludes.append(arg)
-               elif opt in ("-D", "--dd"):
-                       extracts.append(arg)
-               elif opt in ("-g", "--grep"):
-                       greps.append(arg)
-               elif opt in ("-G", "--green"):
-                       greps.append("32;")
-               elif opt in ("-i", "--red"):
-                       greps.append("31;")
-               elif opt in ("-U", "--blue"):
-                       greps.append("34;")
-               elif opt in ("-r", "--rm"):
-                       cleanup_after_extract = True
-               elif opt in ("-m", "--magic"):
-                       magic_files.append(arg)
-               elif opt in ("-k", "--keep-going"):
-                       magic_flags |= binwalk.magic.MAGIC_CONTINUE
-               elif opt in ("-I", "--show-invalid"):
-                       show_invalid = True
-               elif opt in ("-B", "--binwalk"):
-                       requested_scans.append(binwalk.Binwalk.BINWALK)
-               elif opt in ("-M", "--matryoshka"):
-                       # Original Zvyozdochkin matrhoska set had 8 dolls. This is a good number.
-                       matryoshka = 8
-               elif opt in ("-K", "--block"):
-                       block_size = binwalk.common.str2int(arg)
-               elif opt in ("-X", "--disable-plugin"):
-                       plugin_blacklist.append(arg)
-               elif opt in ("-Y", "--enable-plugin"):
-                       plugin_whitelist.append(arg)
-               elif opt in ("-T", "--ignore-time-skew"):
-                       ignore_time_skew = False
-
-               elif opt in ("-H", "--heuristic", "--math"):
-                       do_comp = True
-                       if binwalk.Binwalk.ENTROPY not in requested_scans:
-                               requested_scans.append(binwalk.Binwalk.ENTROPY)
-               elif opt in ("-F", "--marker"):
-                       if ':' in arg:
-                               (location, description) = arg.split(':', 1)
-                               location = int(location)
-                               markers.append((location, [{'description' : description, 'offset' : location}]))
-               elif opt in("-L", "--list-plugins"):
-                       # List all user and system plugins, then exit
-                       print ''
-                       print 'NAME             TYPE       ENABLED    DESCRIPTION'
-                       print '-' * 115
-                       with binwalk.Binwalk() as bw:
-                               for (key, info) in binwalk.plugins.Plugins(bw).list_plugins().iteritems():
-                                       for module_name in info['modules']:
-                                               print '%-16s %-10s %-10s %s' % (module_name, key, info['enabled'][module_name], info['descriptions'][module_name])
-                       print ''
-                       sys.exit(1)
-               elif opt in ("-e", "--extract"):
-                       # If a file path was specified, use that as the extraction rules file
-                       if arg:
-                               extract_from_config = False
-                               extract_rules_file = arg
-                       # Else, use the default rules file
-                       else:
-                               extract_from_config = True
-               elif opt in ("-A", "--opcodes"):
-                       requested_scans.append(binwalk.Binwalk.BINARCH)
-                       # Load user file first so its signatures take precedence
-                       magic_files.append(config.paths['user'][config.BINARCH_MAGIC_FILE])
-                       magic_files.append(config.paths['system'][config.BINARCH_MAGIC_FILE])
-               elif opt in ("-C", "--cast"):
-                       requested_scans.append(binwalk.Binwalk.BINCAST)
-                       # Don't stop at the first match (everything matches everything in this scan)
-                       magic_flags |= binwalk.magic.MAGIC_CONTINUE
-                       # Load user file first so its signatures take precedence
-                       magic_files.append(config.paths['user'][config.BINCAST_MAGIC_FILE])
-                       magic_files.append(config.paths['system'][config.BINCAST_MAGIC_FILE])
-               elif opt in ("-R", "--raw-bytes"):
-                       custom_signature = arg
-                       requested_scans.append(binwalk.Binwalk.BINWALK)
-                       explicit_signature_scan = True
-               elif opt in ("-u", "--update"):
-                       try:
-                               sys.stdout.write("Updating signatures...")
-                               sys.stdout.flush()
-
-                               binwalk.Update().update()
-
-                               sys.stdout.write("done.\n")
-                               sys.exit(0)
-                       except Exception, e:
-                               if 'Permission denied' in str(e):
-                                       sys.stderr.write("failed (permission denied). Check your user permissions, or run the update as root.\n")
-                               else:
-                                       sys.stderr.write('\n' + str(e) + '\n')
-                               sys.exit(1)
-               
-               # The --profile option is handled prior to calling main()
-               elif opt not in ('-P', '--profile'):
-                       usage(sys.stderr)
-
-               # Keep track of the options and arguments.
-               # This is used later to determine which argv entries are file names.
-               options.append(opt)
-               options.append("%s%s" % (opt, arg))
-               options.append("%s=%s" % (opt, arg))
-               arguments.append(arg)
-               
-       # Treat any command line options not processed by getopt as target file paths.
-       for opt in sys.argv[1:]:
-               if opt not in arguments and opt not in options and not opt.startswith('-'):
-                       file_opt_list.append(opt)
-
-       # Validate the target files listed in target_files
-       for tfile in file_opt_list:
-               # Ignore directories.
-               if not os.path.isdir(tfile):
-                       # Make sure we can open the target files
-                       try:
-                               fd = open(tfile, "rb")
-                               fd.close()
-                               target_files.append(tfile)
-                       except Exception, e:
-                               sys.stdout.write("Cannot open file : %s\n" % str(e))
-                               failed_open_count += 1
-
-       # Unless -O was specified, don't run the scan unless we are able to scan all specified files
-       if failed_open_count > 0 and not ignore_failed_open:
-               if failed_open_count > 1:
-                       plural = 's'
-               else:
-                       plural = ''
-               sys.stdout.write("Failed to open %d file%s for scanning, quitting...\n" % (failed_open_count, plural))
-               sys.exit(1)
-
-       # If more than one target file was specified, enable verbose mode; else, there is
-       # nothing in the output to indicate which scan corresponds to which file.
-       if (matryoshka > 1 or len(target_files) > 1):
-               save_plot = True
-               if not verbose:
-                       verbose = 1
-       elif len(target_files) == 0:
-               usage(sys.stderr)
-
-       # Instantiate the Binwalk class
-       bwalk = binwalk.Binwalk(magic_files=magic_files, flags=magic_flags, verbose=verbose, log=log_file, quiet=quiet, ignore_smart_keywords=ignore_signature_keywords, load_plugins=enable_plugins, ignore_time_skews=ignore_time_skew)
-
-       # If a custom signature was specified, create a temporary magic file containing the custom signature
-       # and ensure that it is the only magic file that will be loaded when Binwalk.scan() is called.
-       if custom_signature is not None:
-               bwalk.magic_files = [bwalk.parser.file_from_string(custom_signature)]
-
-       # Set any specified filters
-       bwalk.filter.exclude(excludes)
-       bwalk.filter.include(searches)
-       bwalk.filter.grep(filters=greps)
-
-       # Add any specified extract rules
-       bwalk.extractor.add_rule(extracts)
-
-       # If -e was specified, load the default extract rules
-       if extract_from_config:
-               bwalk.extractor.load_defaults()
-
-       # If --extract was specified, load the specified extraction rules file
-       if extract_rules_file is not None:
-               bwalk.extractor.load_from_file(extract_rules_file)
-
-       # Set the extractor cleanup value (True to clean up files, False to leave them on disk)
-       bwalk.extractor.cleanup_extracted_files(cleanup_after_extract)
-
-       # Enable delayed extraction, which will prevent supported file types from having trailing data when extracted
-       bwalk.extractor.enable_delayed_extract(delay_extraction)
-
-       # Load the magic file(s)
-       #bwalk.load_signatures(magic_files=magic_files)
-
-       # If --term was specified, enable output formatting to terminal
-       if format_to_terminal:
-               bwalk.display.enable_formatting(True)
-
-       # Enable log file CSV formatting, if specified
-       if do_csv:
-               bwalk.display.enable_csv()
-
-       # If no scan was explicitly rquested, do a binwalk scan
-       if not requested_scans:
-               requested_scans.append(binwalk.Binwalk.BINWALK)
-
-       # Sort the scan types to ensure the entropy scan is performed last
-       requested_scans.sort()
-
-       # Everything is set up, let's do a scan
-       try:
-               results = {}
-
-               # Start the display_status function as a daemon thread.
-               t = Thread(target=display_status)
-               t.setDaemon(True)
-               t.start()
-               
-               for scan_type in requested_scans:
-
-                       if scan_type in [binwalk.Binwalk.BINWALK, binwalk.Binwalk.BINARCH, binwalk.Binwalk.BINCAST]:
-
-                               # There's no generic way for the binwalk class to know what
-                               # scan type is being run, since these are all signature scans,
-                               # just with different magic files. Manually set the scan sub-type
-                               # here to ensure that plugins can differentiate between the
-                               # scans being performed.
-                               bwalk.scan_type = scan_type
-
-                               r = bwalk.scan(target_files,
-                                               offset=offset, 
-                                               length=length, 
-                                               show_invalid_results=show_invalid, 
-                                               callback=bwalk.display.results, 
-                                               start_callback=bwalk.display.header,
-                                               end_callback=bwalk.display.footer,
-                                               matryoshka=matryoshka,
-                                               plugins_whitelist=plugin_whitelist,
-                                               plugins_blacklist=plugin_blacklist)
-
-                               bwalk.concatenate_results(results, r)
-
-                       elif scan_type == binwalk.Binwalk.STRINGS:
-
-                               r = bwalk.analyze_strings(target_files, 
-                                                       length=length, 
-                                                       offset=offset, 
-                                                       n=strlen, 
-                                                       block=block_size, 
-                                                       load_plugins=enable_plugins, 
-                                                       whitelist=plugin_whitelist, 
-                                                       blacklist=plugin_blacklist)
-                                       
-                               bwalk.concatenate_results(results, r)
-
-                       elif scan_type == binwalk.Binwalk.COMPRESSION:
-
-                               r = bwalk.analyze_compression(target_files, offset=offset, length=length)
-                               bwalk.concatenate_results(results, r)
-
-                       elif scan_type == binwalk.Binwalk.ENTROPY:
-
-                               if not results:
-                                       for target_file in target_files:
-                                               results[target_file] = []
-                               else:
-                                       bwalk.display.quiet = True
-                                       bwalk.display.cleanup()
-
-                               for target_file in results.keys():
-                                       bwalk.concatenate_results(results, {target_file : markers})
-
-                               bwalk.analyze_entropy(results,
-                                                       offset, 
-                                                       length, 
-                                                       block_size, 
-                                                       show_plot, 
-                                                       show_legend, 
-                                                       save_plot,
-                                                       algorithm=entropy_algorithm,
-                                                       load_plugins=enable_plugins,
-                                                       whitelist=plugin_whitelist,
-                                                       blacklist=plugin_blacklist,
-                                                       compcheck=do_comp)
-
-                       elif scan_type == binwalk.Binwalk.HEXDIFF:
-                               
-                               bwalk.hexdiff(target_files, offset=offset, length=length, block=block_size, first=show_single_hex_dump)
-
-       except KeyboardInterrupt:
-               pass
-       except IOError:
-               pass
-       except Exception, e:
-               print "Unexpected error:", str(e)
-               
-       bwalk.cleanup()
-
-try:
-       # Special options for profiling the code. For debug use only.
-       if '--profile' in sys.argv or '-P' in sys.argv:
-               import cProfile
-               cProfile.run('main()')
-       else:
-               main()
-except KeyboardInterrupt:
-       pass
-
-
diff --git a/binwalk/__init__.py b/binwalk/__init__.py
deleted file mode 100644 (file)
index d1fca17..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-__all__ = ["Binwalk"]
-
-import os
-import re
-import time
-import magic
-from config import *
-from update import *
-from filter import *
-from parser import *
-from plugins import *
-from hexdiff import *
-from entropy import *
-from extractor import *
-from prettyprint import *
-from smartstrings import *
-from smartsignature import *
-from common import file_size, unique_file_name
-
-class Binwalk(object):
-       '''
-       Primary Binwalk class.
-
-       Useful class objects:
-
-               self.filter        - An instance of the MagicFilter class.
-               self.extractor     - An instance of the Extractor class.
-               self.parser        - An instance of the MagicParser class.
-               self.display       - An instance of the PrettyPrint class.
-               self.magic_files   - A list of magic file path strings to use whenever the scan() method is invoked.
-               self.scan_length   - The total number of bytes to be scanned.
-               self.total_scanned - The number of bytes that have already been scanned.
-               self.scan_type     - The type of scan being performed, one of: BINWALK, BINCAST, BINARCH, STRINGS, ENTROPY.
-
-       Performing a simple binwalk scan:
-
-               from binwalk import Binwalk
-                       
-               scan = Binwalk().scan(['firmware1.bin', 'firmware2.bin'])
-               for (filename, file_results) in scan.iteritems():
-                       print "Results for %s:" % filename
-                       for (offset, results) in file_results:
-                               for result in results:
-                                       print offset, result['description']
-       '''
-
-       # Default libmagic flags. Basically disable anything we don't need in the name of speed.
-       DEFAULT_FLAGS = magic.MAGIC_NO_CHECK_TEXT | magic.MAGIC_NO_CHECK_ENCODING | magic.MAGIC_NO_CHECK_APPTYPE | magic.MAGIC_NO_CHECK_TOKENS
-
-       # The MAX_SIGNATURE_SIZE limits the amount of data available to a signature.
-       # While most headers/signatures are far less than this value, some may reference 
-       # pointers in the header structure which may point well beyond the header itself.
-       # Passing the entire remaining buffer to libmagic is resource intensive and will
-       # significantly slow the scan; this value represents a reasonable buffer size to
-       # pass to libmagic which will not drastically affect scan time.
-       MAX_SIGNATURE_SIZE = 8 * 1024
-
-       # Max number of bytes to process at one time. This needs to be large enough to 
-       # limit disk I/O, but small enough to limit the size of processed data blocks.
-       READ_BLOCK_SIZE = 1 * 1024 * 1024
-
-       # Minimum verbosity level at which to enable extractor verbosity.
-       VERY_VERBOSE = 2
-
-       # Scan every byte by default.
-       DEFAULT_BYTE_ALIGNMENT = 1
-
-       # Valid scan_type values.
-       # ENTROPY must be the largest value to ensure it is performed last if multiple scans are performed.
-       BINWALK = 0x01
-       BINARCH = 0x02
-       BINCAST = 0x04
-       STRINGS = 0x08
-       COMPRESSION = 0x10
-       HEXDIFF = 0x20
-       ENTROPY = 0x40
-
-       def __init__(self, magic_files=[], flags=magic.MAGIC_NONE, log=None, quiet=False, verbose=0, ignore_smart_keywords=False, ignore_time_skews=False, load_extractor=False, load_plugins=True):
-               '''
-               Class constructor.
-
-               @magic_files            - A list of magic files to use.
-               @flags                  - Flags to pass to magic_open. [TODO: Might this be more appropriate as an argument to load_signaures?]
-               @log                    - Output PrettyPrint data to log file as well as to stdout.
-               @quiet                  - If set to True, supress PrettyPrint output to stdout.
-               @verbose                - Verbosity level.
-               @ignore_smart_keywords  - Set to True to ignore smart signature keywords.
-               @ignore_time_skews      - Set to True to ignore file results with timestamps in the future.
-               @load_extractor         - Set to True to load the default extraction rules automatically.
-               @load_plugins           - Set to False to disable plugin support.
-
-               Returns None.
-               '''
-               self.flags = self.DEFAULT_FLAGS | flags
-               self.last_extra_data_section = ''
-               self.load_plugins = load_plugins
-               self.magic_files = magic_files
-               self.verbose = verbose
-               self.total_scanned = 0
-               self.scan_length = 0
-               self.total_read = 0
-               self.matryoshka = 1
-               self.epoch = 0
-               self.year = 0
-               self.plugins = None
-               self.magic = None
-               self.mfile = None
-               self.entropy = None
-               self.strings = None
-               self.scan_type = self.BINWALK
-
-               if not ignore_time_skews:
-                       # Consider timestamps up to 1 year in the future valid,
-                       # to account for any minor time skew on the local system.
-                       self.year = time.localtime().tm_year + 1
-                       self.epoch = int(time.time()) + (60 * 60 * 24 * 365)
-
-               # Instantiate the config class so we can access file/directory paths
-               self.config = Config()
-
-               # Use the system default magic file if no other was specified
-               if not self.magic_files or self.magic_files is None:
-                       # Append the user's magic file first so that those signatures take precedence
-                       self.magic_files = [
-                                       self.config.paths['user'][self.config.BINWALK_MAGIC_FILE],
-                                       self.config.paths['system'][self.config.BINWALK_MAGIC_FILE],
-                       ]
-
-               # Only set the extractor verbosity if told to be very verbose
-               if self.verbose >= self.VERY_VERBOSE:
-                       extractor_verbose = True
-               else:
-                       extractor_verbose = False
-
-               # Create an instance of the PrettyPrint class, which can be used to print results to screen/file.
-               self.display = PrettyPrint(self, log=log, quiet=quiet, verbose=verbose)
-
-               # Create MagicFilter and Extractor class instances. These can be used to:
-               #
-               #       o Create include/exclude filters
-               #       o Specify file extraction rules to be applied during a scan
-               #
-               self.filter = MagicFilter()
-               self.extractor = Extractor(verbose=extractor_verbose)
-               if load_extractor:
-                       self.extractor.load_defaults()
-
-               # Create SmartSignature and MagicParser class instances. These are mostly for internal use.
-               self.smart = SmartSignature(self.filter, ignore_smart_signatures=ignore_smart_keywords)
-               self.parser = MagicParser(self.filter, self.smart)
-
-       def __del__(self):
-               self.cleanup()
-
-       def __enter__(self):
-               return self
-
-       def __exit__(self, t, v, traceback):
-               self.cleanup()
-
-       def cleanup(self):
-               '''
-               Close magic and cleanup any temporary files generated by the internal instance of MagicParser.
-
-               Returns None.
-               '''
-               try:
-                       self.magic.close()
-               except:
-                       pass
-
-               try:
-                       self.parser.cleanup()
-               except:
-                       pass
-
-       def load_signatures(self, magic_files=[]):
-               '''
-               Load signatures from magic file(s).
-               Called automatically by Binwalk.scan() with all defaults, if not already called manually.
-
-               @magic_files - A list of magic files to use (default: self.magic_files).
-       
-               Returns None.   
-               '''
-               # The magic files specified here override any already set
-               if magic_files and magic_files is not None:
-                       self.magic_files = magic_files
-
-               # Parse the magic file(s) and initialize libmagic
-               self.mfile = self.parser.parse(self.magic_files)
-               self.magic = magic.open(self.flags)
-               self.magic.load(self.mfile)
-
-       def hexdiff(self, file_names, length=0x100, offset=0, block=16, first=False):
-               if not length and len(file_names) > 0:
-                       length = file_size(file_names[0])
-               if not block:
-                       block = 16
-
-               HexDiff(self).display(file_names, offset=offset, size=length, block=block, show_first_only=first)
-
-       def analyze_strings(self, file_names, length=0, offset=0, n=0, block=0, load_plugins=True, whitelist=[], blacklist=[]):
-               '''
-               Performs a strings analysis on the specified file(s).
-
-               @file_names   - A list of files to analyze.
-               @length       - The number of bytes in the file to analyze.
-               @offset       - The starting offset into the file to begin analysis.
-               @n            - The minimum valid string length.
-               @block        - The block size to use when performing entropy analysis.
-               @load_plugins - Set to False to disable plugin callbacks.
-               @whitelist    - A list of whitelisted plugins.
-               @blacklist    - A list of blacklisted plugins.
-               
-               Returns a dictionary compatible with other classes and methods (Entropy, Binwalk, analyze_entropy, etc):
-
-                       {
-                               'file_name' : (offset, [{
-                                                               'description' : 'Strings',
-                                                               'string'      : 'found_string'
-                                                       }]
-                                       )
-                       }
-               '''
-               data = {}
-
-               self.strings = Strings(file_names,
-                                       self,
-                                       length=length, 
-                                       offset=offset,
-                                       n=n,
-                                       block=block,
-                                       algorithm='gzip',               # Use gzip here as it is faster and we don't need the detail provided by shannon
-                                       load_plugins=load_plugins,
-                                       whitelist=whitelist,
-                                       blacklist=blacklist)
-
-               data = self.strings.strings()
-               
-               del self.strings
-               self.strings = None
-
-               return data
-
-       def analyze_entropy(self, files, offset=0, length=0, block=0, plot=True, legend=True, save=False, algorithm=None, load_plugins=True, whitelist=[], blacklist=[], compcheck=False):
-                '''
-               Performs an entropy analysis on the specified file(s).
-
-               @files        - A dictionary containing file names and results data, as returned by Binwalk.scan.
-               @offset       - The offset into the data to begin analysis.
-               @length       - The number of bytes to analyze.
-               @block        - The size of the data blocks to analyze.
-               @plot         - Set to False to disable plotting.
-               @legend       - Set to False to exclude the legend and custom offset markers from the plot.
-               @save         - Set to True to save plots to disk instead of displaying them.
-               @algorithm    - Set to 'gzip' to use the gzip entropy "algorithm".
-               @load_plugins - Set to False to disable plugin callbacks.
-               @whitelist    - A list of whitelisted plugins.
-               @blacklist    - A list of blacklisted plugins.
-               @compcheck    - Set to True to perform heuristic compression detection.
-
-               Returns a dictionary of:
-                        
-                       {
-                               'file_name' : ([list, of, offsets], [list, of, entropy], average_entropy)
-                       }
-               '''
-               data = {}
-
-               self.entropy = Entropy(files,
-                                       self,
-                                       offset,
-                                       length,
-                                       block,
-                                       plot,
-                                       legend,
-                                       save,
-                                       algorithm=algorithm,
-                                       load_plugins=plugins,
-                                       whitelist=whitelist,
-                                       blacklist=blacklist,
-                                       compcheck=compcheck)
-               
-               data = self.entropy.analyze()
-               
-               del self.entropy
-               self.entropy = None
-
-               return data
-
-       def scan(self, target_files, offset=0, length=0, show_invalid_results=False, callback=None, start_callback=None, end_callback=None, base_dir=None, matryoshka=1, plugins_whitelist=[], plugins_blacklist=[]):
-               '''
-               Performs a binwalk scan on a file or list of files.
-
-               @target_files         - File or list of files to scan.
-               @offset               - Starting offset at which to start the scan.
-                @length               - Number of bytes to scan. Specify -1 for streams.
-                @show_invalid_results - Set to True to display invalid results.
-                @callback             - Callback function to be invoked when matches are found.
-               @start_callback       - Callback function to be invoked prior to scanning each file.
-               @end_callback         - Callback function to be invoked after scanning each file.
-               @base_dir             - Base directory for output files.
-               @matryoshka           - Number of levels to traverse into the rabbit hole.
-               @plugins_whitelist    - A list of plugin names to load. If not empty, only these plugins will be loaded.
-               @plugins_blacklist    - A list of plugin names to not load.
-
-               Returns a dictionary of :
-
-                       {
-                               'target file name' : [
-                                                       (0, [{description : "LZMA compressed data..."}]),
-                                                       (112, [{description : "gzip compressed data..."}])
-                               ]
-                       }
-               '''
-               # Prefix all directory names with an underscore. This prevents accidental deletion of the original file(s)
-               # when the user is typing too fast and is trying to deleted the extraction directory.
-               prefix = '_'
-               dir_extension = 'extracted'
-               i = 0
-               total_results = {}
-               self.matryoshka = matryoshka
-
-               # For backwards compatibility
-               if not isinstance(target_files, type([])):
-                       target_files = [target_files]
-
-               if base_dir is None:
-                       base_dir = ''
-
-               # Instantiate the Plugins class and load all plugins, if not disabled
-               self.plugins = Plugins(self, whitelist=plugins_whitelist, blacklist=plugins_blacklist)
-               if self.load_plugins:
-                       self.plugins._load_plugins()
-
-               # Load the default signatures if self.load_signatures has not already been invoked
-               if self.magic is None:
-                       self.load_signatures()
-
-               while i < self.matryoshka:
-                       new_target_files = []
-
-                       # Scan each target file
-                       for target_file in target_files:
-                               ignore_files = []
-
-                               # On the first scan, add the base_dir value to dir_prefix. Subsequent target_file values will have this value prepended already.
-                               if i == 0:
-                                       dir_prefix = os.path.join(base_dir, prefix + os.path.basename(target_file))
-                               else:
-                                       dir_prefix = os.path.join(os.path.dirname(target_file), prefix + os.path.basename(target_file))
-
-                               output_dir = unique_file_name(dir_prefix, dir_extension)
-
-                               # Set the output directory for extracted files to go to
-                               self.extractor.output_directory(output_dir)
-
-                               if start_callback is not None:
-                                       start_callback(target_file)
-       
-                               results = self.single_scan(target_file, 
-                                                       offset=offset, 
-                                                       length=length, 
-                                                       show_invalid_results=show_invalid_results,
-                                                       callback=callback)
-       
-                               if end_callback is not None:
-                                       end_callback(target_file)
-
-                               # Get a list of extracted file names; don't scan them again.
-                               for (index, results_list) in results:
-                                       for result in results_list:
-                                               if result['extract']:
-                                                       ignore_files.append(result['extract'])
-
-                               # Find all newly created files and add them to new_target_files / new_target_directories
-                               for (dir_path, sub_dirs, files) in os.walk(output_dir):
-                                       for fname in files:
-                                               fname = os.path.join(dir_path, fname)
-                                               if fname not in ignore_files:
-                                                       new_target_files.append(fname)
-
-                                       # Don't worry about sub-directories
-                                       break
-
-                               total_results[target_file] = results
-
-                       target_files = new_target_files
-                       i += 1
-
-               # Be sure to delete the Plugins instance so that there isn't a lingering reference to
-               # this Binwalk class instance (lingering handles to this Binwalk instance cause the
-               # __del__ deconstructor to not be called).
-               if self.plugins is not None:
-                       del self.plugins
-                       self.plugins = None
-
-               return total_results
-
-       def single_scan(self, target_file='', fd=None, offset=0, length=0, show_invalid_results=False, callback=None, plugins_whitelist=[], plugins_blacklist=[]):
-               '''
-               Performs a binwalk scan on one target file or file descriptor.
-
-               @target_file          - File to scan.
-               @fd                   - File descriptor to scan.
-               @offset               - Starting offset at which to start the scan.
-               @length               - Number of bytes to scan. Specify -1 for streams.
-               @show_invalid_results - Set to True to display invalid results.
-               @callback             - Callback function to be invoked when matches are found.
-               @plugins_whitelist    - A list of plugin names to load. If not empty, only these plugins will be loaded.
-               @plugins_blacklist    - A list of plugin names to not load.
-
-               The callback function is passed two arguments: a list of result dictionaries containing the scan results
-               (one result per dict), and the offset at which those results were identified. Example callback function:
-
-                       def my_callback(offset, results):
-                               print "Found %d results at offset %d:" % (len(results), offset)
-                               for result in results:
-                                       print "\t%s" % result['description']
-
-                       binwalk.Binwalk(callback=my_callback).scan("firmware.bin")
-
-               Upon completion, the scan method returns a sorted list of tuples containing a list of results dictionaries
-               and the offsets at which those results were identified:
-
-                       scan_results = [
-                                       (0, [{description : "LZMA compressed data..."}]),
-                                       (112, [{description : "gzip compressed data..."}])
-                       ]
-
-               See SmartSignature.parse for a more detailed description of the results dictionary structure.
-               '''
-               scan_results = {}
-               fsize = 0
-               jump_offset = 0
-               i_opened_fd = False
-               i_loaded_plugins = False
-               plugret = PLUGIN_CONTINUE
-               plugret_start = PLUGIN_CONTINUE
-               self.total_read = 0
-               self.total_scanned = 0
-               self.scan_length = length
-               self.filter.show_invalid_results = show_invalid_results
-               self.start_offset = offset
-
-               # Check to make sure either a target file or a file descriptor was supplied
-               if not target_file and fd is None:
-                       raise Exception("Must supply Binwalk.single_scan with a valid file path or file object")
-
-               # Need the total size of the target file, even if we aren't scanning the whole thing
-               if target_file:
-                       fsize = file_size(target_file)
-                       
-               # Open the target file and seek to the specified start offset
-               if fd is None:
-                       fd = open(target_file)
-                       i_opened_fd = True
-       
-               # Seek to the starting offset. This is invalid for some file-like objects such as stdin,
-               # so if an exception is thrown try reading offset bytes from the file object.   
-               try:    
-                       fd.seek(offset)
-               except:
-                       fd.read(offset)
-               
-               # If no length was specified, make the length the size of the target file minus the starting offset
-               if self.scan_length == 0:
-                       self.scan_length = fsize - offset
-
-               # If the Plugins class has not already been instantitated, do that now.
-               if self.plugins is None:
-                       self.plugins = Plugins(self, blacklist=plugins_blacklist, whitelist=plugins_whitelist)
-                       i_loaded_plugins = True
-               
-                       if self.load_plugins:
-                               self.plugins._load_plugins()
-
-               # Invoke any pre-scan plugins
-               plugret_start = self.plugins._pre_scan_callbacks(fd)
-               
-               # Load the default signatures if self.load_signatures has not already been invoked
-               if self.magic is None:
-                       self.load_signatures()
-
-               # Main loop, scan through all the data
-               while not ((plugret | plugret_start) & PLUGIN_TERMINATE):
-                       i = 0
-
-                       # Read in the next block of data from the target file and make sure it's valid
-                       (data, dlen) = self._read_block(fd)
-                       if data is None or dlen == 0:
-                               break
-
-                       # The total number of bytes scanned could be bigger than the total number
-                       # of bytes read from the file if the previous signature result specified a 
-                       # jump offset that was beyond the end of the then current data block.
-                       #
-                       # If this is the case, we need to index into this data block appropriately in order to 
-                       # resume the scan from the appropriate offset.
-                       #
-                       # Don't update dlen though, as it is the literal offset into the data block that we
-                       # are to scan up to in this loop iteration. It is also appended to self.total_scanned,
-                       # which is what we want (even if we have been told to skip part of the block, the skipped
-                       # part is still considered part of the total bytes scanned).
-                       if jump_offset > 0:
-                               total_check = self.total_scanned + dlen
-
-                               # Is the jump offset beyond the total amount of data that we've currently read in (i.e., in a future data block)?
-                               if jump_offset >= total_check:
-                                       i = -1
-                                       
-                                       # Try to seek to the jump offset; this won't work if fd == sys.stdin
-                                       try:
-                                               fd.seek(jump_offset)
-                                               self.total_read = jump_offset
-                                               self.total_scanned = jump_offset - dlen
-                                       except:
-                                               pass
-
-                               # Is the jump offset inside this block of data?
-                               elif jump_offset > self.total_scanned and jump_offset < total_check:
-                                       # Index into this block appropriately; jump_offset is the file offset that
-                                       # we need to jump to, and self.total_scanned is the file offset that starts
-                                       # the beginning of the current block
-                                       i = jump_offset - self.total_scanned
-
-                               # We're done with jump_offset, zero it out for the next round
-                               jump_offset = 0
-
-                       # Scan through each block of data looking for signatures
-                       if i >= 0 and i < dlen:
-
-                               # Scan this data block for a list of offsets which are candidates for possible valid signatures
-                               for candidate in self.parser.find_signature_candidates(data[i:dlen]):
-
-                                       # If a signature specified a jump offset beyond this candidate signature offset, ignore it
-                                       if (i + candidate + self.total_scanned) < jump_offset:
-                                               continue
-
-                                       # Reset these values on each loop       
-                                       smart = {}
-                                       results = []
-                                       results_offset = -1
-
-                                       # Pass the data to libmagic, and split out multiple results into a list
-                                       for magic_result in self.parser.split(self.magic.buffer(data[i+candidate:i+candidate+self.MAX_SIGNATURE_SIZE])):
-
-                                               i_set_results_offset = False
-
-                                               # Some file names are not NULL byte terminated, but rather their length is
-                                               # specified in a size field. To ensure these are not marked as invalid due to
-                                               # non-printable characters existing in the file name, parse the filename(s) and
-                                               # trim them to the specified filename length, if one was specified.
-                                               magic_result = self.smart._parse_raw_strings(magic_result)
-
-                                               # Make sure this is a valid result before further processing
-                                               if not self.filter.invalid(magic_result):
-                                                       # The smart filter parser returns a dictionary of keyword values and the signature description.
-                                                       smart = self.smart.parse(magic_result)
-       
-                                                       # Validate the jump value and check if the response description should be displayed
-                                                       if smart['jump'] > -1 and self._should_display(smart):
-                                                               # If multiple results are returned and one of them has smart['jump'] set to a non-zero value,
-                                                               # the calculated results offset will be wrong since i will have been incremented. Only set the
-                                                               # results_offset value when the first match is encountered.
-                                                               if results_offset < 0:
-                                                                       results_offset = offset + i + candidate + smart['adjust'] + self.total_scanned
-                                                                       i_set_results_offset = True
-
-                                                               # Double check to make sure the smart['adjust'] value is sane. 
-                                                               # If it makes results_offset negative, then it is not sane.
-                                                               if results_offset >= 0:
-                                                                       smart['offset'] = results_offset
-
-                                                                       # Invoke any scan plugins 
-                                                                       if not (plugret_start & PLUGIN_STOP_PLUGINS):
-                                                                               plugret = self.plugins._scan_callbacks(smart)
-                                                                               results_offset = smart['offset']
-                                                                               if (plugret & PLUGIN_TERMINATE):
-                                                                                       break
-
-                                                                       # Extract the result, if it matches one of the extract rules and is not a delayed extract.
-                                                                       if self.extractor.enabled and not (self.extractor.delayed and smart['delay']) and not ((plugret | plugret_start) & PLUGIN_NO_EXTRACT):
-                                                                               # If the signature did not specify a size, extract to the end of the file.
-                                                                               if not smart['size']:
-                                                                                       smart['size'] = fsize-results_offset
-                                                                               
-                                                                               smart['extract'] = self.extractor.extract(      results_offset, 
-                                                                                                                               smart['description'], 
-                                                                                                                               target_file, 
-                                                                                                                               smart['size'], 
-                                                                                                                               name=smart['name'])
-
-                                                                       if not ((plugret | plugret_start) & PLUGIN_NO_DISPLAY):
-                                                                               # This appears to be a valid result, so append it to the results list.
-                                                                               results.append(smart)
-                                                                       elif i_set_results_offset:
-                                                                               results_offset = -1
-
-                                       # Did we find any valid results?
-                                       if results_offset >= 0:
-                                               scan_results[results_offset] = results
-                                       
-                                               if callback is not None:
-                                                       callback(results_offset, results)
-                       
-                                               # If a relative jump offset was specified, update the absolute jump_offset variable
-                                               if smart.has_key('jump') and smart['jump'] > 0:
-                                                       jump_offset = results_offset + smart['jump']
-
-                       # Track the total number of bytes scanned
-                       self.total_scanned += dlen
-                       # The starting offset only affects the reported offset for results
-                       # in the first block of data. Zero it out after the first block has
-                       # been processed.
-                       offset = 0
-
-               # Sort the results before returning them
-               scan_items = scan_results.items()
-               scan_items.sort()
-
-               # Do delayed extraction, if specified.
-               if self.extractor.enabled and self.extractor.delayed:
-                       scan_items = self.extractor.delayed_extract(scan_items, target_file, fsize)
-
-               # Invoke any post-scan plugins
-               #if not (plugret_start & PLUGIN_STOP_PLUGINS):
-               self.plugins._post_scan_callbacks(fd)
-
-               # Be sure to delete the Plugins instance so that there isn't a lingering reference to
-               # this Binwalk class instance (lingering handles to this Binwalk instance cause the
-               # __del__ deconstructor to not be called).
-               if i_loaded_plugins:
-                       del self.plugins
-                       self.plugins = None
-
-               if i_opened_fd:
-                       fd.close()
-
-               return scan_items
-
-       def concatenate_results(self, results, new):
-               '''
-               Concatenate multiple Binwalk.scan results into one dictionary.
-
-               @results - Binwalk results to append new results to.
-               @new     - New data to append to results.
-
-               Returns None.
-               '''
-               for (new_file_name, new_data) in new.iteritems():
-                       if not results.has_key(new_file_name):
-                               results[new_file_name] = new_data
-                       else:
-                               for i in range(0, len(new_data)):
-                                       found_offset = False
-                                       (new_offset, new_results_list) = new_data[i]
-
-                                       for j in range(0, len(results[new_file_name])):
-                                               (offset, results_list) = results[new_file_name][j]
-                                               if offset == new_offset:
-                                                       results_list += new_results_list
-                                                       results[new_file_name][j] = (offset, results_list)
-                                                       found_offset = True
-                                                       break
-                                       
-                                       if not found_offset:
-                                               results[new_file_name] += new_data
-
-       def _should_display(self, result):
-               '''
-               Determines if a result string should be displayed to the user or not.
-               
-               @result - Result dictionary, as returned by self.smart.parse.
-
-               Returns True if the string should be displayed.
-               Returns False if the string should not be displayed.
-               '''
-               if result['invalid'] == True or (self.year and result['year'] > self.year) or (self.epoch and result['epoch'] > self.epoch):
-                       return False
-               
-               desc = result['description']
-               return (desc and desc is not None and not self.filter.invalid(desc) and self.filter.filter(desc) != self.filter.FILTER_EXCLUDE)
-
-       def _read_block(self, fd):
-               '''
-               Reads in a block of data from the target file.
-
-               @fd - File object for the target file.
-
-               Returns a tuple of (file block data, block data length).
-               '''
-               dlen = 0
-               data = None
-               # Read in READ_BLOCK_SIZE plus MAX_SIGNATURE_SIZE bytes, but return a max dlen value
-               # of READ_BLOCK_SIZE. This ensures that there is a MAX_SIGNATURE_SIZE buffer at the
-               # end of the returned data in case a signature is found at or near data[dlen].
-               rlen = self.READ_BLOCK_SIZE + self.MAX_SIGNATURE_SIZE
-
-               # Check to make sure we only read up to scan_length bytes (streams have a scan length of -1)
-               if self.scan_length == -1 or self.total_read < self.scan_length:
-               
-                       # Read in the next rlen bytes, plus any extra data from the previous read (only neeced for streams)
-                       data = self.last_extra_data_section + fd.read(rlen - len(self.last_extra_data_section))
-                       
-                       if data and data is not None:
-                               # Get the actual length of the read in data
-                               dlen = len(data)
-
-                               # If we've read in more data than the scan length, truncate the dlen value
-                               if self.scan_length != -1 and (self.total_read + dlen) >= self.scan_length:
-                                       dlen = self.scan_length - self.total_read
-                               # If dlen is the expected rlen size, it should be set to READ_BLOCK_SIZE
-                               elif dlen == rlen:
-                                       dlen = self.READ_BLOCK_SIZE
-
-                               # Increment self.total_read to reflect the amount of data that has been read
-                               # for processing (actual read size is larger of course, due to the MAX_SIGNATURE_SIZE
-                               # buffer of data at the end of each block).
-                               self.total_read += dlen
-
-                               # Seek to the self.total_read offset so the next read can pick up where this one left off.
-                               # If fd is a stream, this seek will fail; keep a copy of the extra buffer data so that it
-                               # can be added to the data buffer the next time this method is invoked.
-                               try:
-                                       fd.seek(self.start_offset + self.total_read)
-                               except:
-                                       self.last_extra_data_section = data[dlen:]
-
-               return (data, dlen)
-
diff --git a/binwalk/common.py b/binwalk/common.py
deleted file mode 100644 (file)
index 5ad52f6..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-# Common functions.
-import os
-import re
-
-def file_size(filename):
-       '''
-       Obtains the size of a given file.
-
-       @filename - Path to the file.
-
-       Returns the size of the file.
-       '''
-       # Using open/lseek works on both regular files and block devices
-       fd = os.open(filename, os.O_RDONLY)
-       try:
-               return os.lseek(fd, 0, os.SEEK_END)
-       except Exception, e:
-               raise Exception("file_size failed to obtain the size of '%s': %s" % (filename, str(e)))
-       finally:
-               os.close(fd)
-
-def str2int(string):
-       '''
-       Attempts to convert string to a base 10 integer; if that fails, then base 16.
-
-       @string - String to convert to an integer.
-
-       Returns the integer value on success.
-       Throws an exception if the string cannot be converted into either a base 10 or base 16 integer value.
-       '''
-       try:
-               return int(string)
-       except:
-               return int(string, 16)
-
-def strip_quoted_strings(string):
-       '''
-       Strips out data in between double quotes.
-       
-       @string - String to strip.
-
-       Returns a sanitized string.
-       '''
-       # This regex removes all quoted data from string.
-       # Note that this removes everything in between the first and last double quote.
-       # This is intentional, as printed (and quoted) strings from a target file may contain 
-       # double quotes, and this function should ignore those. However, it also means that any 
-       # data between two quoted strings (ex: '"quote 1" you won't see me "quote 2"') will also be stripped.
-       return re.sub(r'\"(.*)\"', "", string)
-
-def get_quoted_strings(string):
-       '''
-       Returns a string comprised of all data in between double quotes.
-
-       @string - String to get quoted data from.
-
-       Returns a string of quoted data on success.
-       Returns a blank string if no quoted data is present.
-       '''
-       try:
-               # This regex grabs all quoted data from string.
-               # Note that this gets everything in between the first and last double quote.
-               # This is intentional, as printed (and quoted) strings from a target file may contain 
-               # double quotes, and this function should ignore those. However, it also means that any 
-               # data between two quoted strings (ex: '"quote 1" non-quoted data "quote 2"') will also be included.
-               return re.findall(r'\"(.*)\"', string)[0]
-       except:
-               return ''
-
-def unique_file_name(base_name, extension=''):
-       '''
-       Creates a unique file name based on the specified base name.
-
-       @base_name - The base name to use for the unique file name.
-       @extension - The file extension to use for the unique file name.
-
-       Returns a unique file string.
-       '''
-       idcount = 0
-       
-       if extension and not extension.startswith('.'):
-               extension = '.%s' % extension
-
-       fname = base_name + extension
-
-       while os.path.exists(fname):
-               fname = "%s-%d%s" % (base_name, idcount, extension)
-               idcount += 1
-
-       return fname
-
diff --git a/binwalk/compression.py b/binwalk/compression.py
deleted file mode 100644 (file)
index d559c06..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env python
-# Routines to perform Monte Carlo Pi approximation and Chi Squared tests. 
-# Used for fingerprinting unknown areas of high entropy (e.g., is this block of high entropy data compressed or encrypted?).
-# Inspired by people who actually know what they're doing: http://www.fourmilab.ch/random/
-
-import math
-
-class MonteCarloPi(object):
-       '''
-       Performs a Monte Carlo Pi approximation.
-       Currently unused.
-       '''
-
-       def __init__(self):
-               '''
-               Class constructor.
-               
-               Returns None.
-               '''
-               self.reset()
-
-       def reset(self):
-               '''
-               Reset state to the beginning.
-               '''
-               self.pi = 0
-               self.error = 0
-               self.m = 0
-               self.n = 0
-
-       def update(self, data):
-               '''
-               Update the pi approximation with new data.
-
-               @data - A string of bytes to update (length must be >= 6).
-
-               Returns None.
-               '''
-               c = 0
-               dlen = len(data)
-
-               while (c+6) < dlen:
-                       # Treat 3 bytes as an x coordinate, the next 3 bytes as a y coordinate.
-                       # Our box is 1x1, so divide by 2^24 to put the x y values inside the box.
-                       x = ((ord(data[c]) << 16) + (ord(data[c+1]) << 8) + ord(data[c+2])) / 16777216.0
-                       c += 3
-                       y = ((ord(data[c]) << 16) + (ord(data[c+1]) << 8) + ord(data[c+2])) / 16777216.0
-                       c += 3
-       
-                       # Does the x,y point lie inside the circle inscribed within our box, with diameter == 1?
-                       if ((x**2) + (y**2)) <= 1:
-                               self.m += 1
-                       self.n += 1
-       
-       def montecarlo(self):
-               '''
-               Approximates the value of Pi based on the provided data.
-               
-               Returns a tuple of (approximated value of pi, percent deviation).
-               '''
-               if self.n:
-                       self.pi = (float(self.m) / float(self.n) * 4.0)
-
-               if self.pi:
-                       self.error = math.fabs(1.0 - (math.pi / self.pi)) * 100.0
-                       return (self.pi, self.error)
-               else:
-                       return (0.0, 0.0)
-
-class ChiSquare(object):
-       '''
-       Performs a Chi Squared test against the provided data.
-       '''
-
-       IDEAL = 256.0
-
-       def __init__(self):
-               '''
-               Class constructor.
-
-               Returns None.
-               '''
-               self.bytes = {}
-               self.freedom = self.IDEAL - 1 
-               
-               # Initialize the self.bytes dictionary with keys for all possible byte values (0 - 255)
-               for i in range(0, int(self.IDEAL)):
-                       self.bytes[chr(i)] = 0
-               
-               self.reset()
-
-       def reset(self):
-               self.xc2 = 0.0
-               self.byte_count = 0
-
-               for key in self.bytes.keys():
-                       self.bytes[key] = 0             
-
-       def update(self, data):
-               '''
-               Updates the current byte counts with new data.
-
-               @data - String of bytes to update.
-
-               Returns None.
-               '''
-               # Count the number of occurances of each byte value
-               for i in data:
-                       self.bytes[i] += 1
-
-               self.byte_count += len(data)
-
-       def chisq(self):
-               '''
-               Calculate the Chi Square critical value.
-
-               Returns the critical value.
-               '''
-               expected = self.byte_count / self.IDEAL
-
-               if expected:
-                       for byte in self.bytes.values():
-                               self.xc2 += ((byte - expected) ** 2 ) / expected
-
-               return self.xc2
-
-class CompressionEntropyAnalyzer(object):
-       '''
-       Class wrapper around ChiSquare.
-       Performs analysis and attempts to interpret the results.
-       '''
-
-       BLOCK_SIZE = 32
-       CHI_CUTOFF = 512
-
-       DESCRIPTION = "Statistical Compression Analysis"
-
-       def __init__(self, fname, start, length, binwalk=None, fp=None):
-               '''
-               Class constructor.
-
-               @fname    - The file to scan.
-               @start    - The start offset to begin analysis at.
-               @length   - The number of bytes to analyze.
-               @callback - Callback function compatible with Binwalk.display.
-
-               Returns None.
-               '''
-               if fname:
-                       self.fp = open(fname, 'rb')
-               else:
-                       self.fp = fp
-
-               self.start = start
-               self.length = length
-               self.binwalk = binwalk
-
-       def analyze(self):
-               '''
-               Perform analysis and interpretation.
-
-               Returns a descriptive string containing the results and attempted interpretation.
-               '''
-               i = 0
-               num_error = 0
-               analyzer_results = []
-
-               if self.binwalk:
-                       self.binwalk.display.header(file_name=self.fp.name, description=self.DESCRIPTION)
-
-               chi = ChiSquare()
-
-               self.fp.seek(self.start)
-               while i < self.length:
-                       rsize = self.length - i
-                       if rsize > self.BLOCK_SIZE:
-                               rsize = self.BLOCK_SIZE
-
-                       d = self.fp.read(rsize)
-                       if len(d) != rsize:
-                               break
-
-                       chi.reset()
-                       chi.update(d)
-
-                       if chi.chisq() >= self.CHI_CUTOFF:
-                               num_error += 1
-
-                       i += rsize
-
-               if num_error > 0:
-                       verdict = 'Moderate entropy data, best guess: compressed'
-               else:
-                       verdict = 'High entropy data, best guess: encrypted'
-
-               result = [{'offset' : self.start, 'description' : '%s, size: %d, %d low entropy blocks' % (verdict, self.length, num_error)}]
-
-               if self.binwalk:
-                       self.binwalk.display.results(self.start, result)
-                       self.binwalk.display.footer()
-
-               return result
-
diff --git a/binwalk/config.py b/binwalk/config.py
deleted file mode 100644 (file)
index ad7a15d..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-import os
-
-class Config:
-       '''
-       Binwalk configuration class, used for accessing user and system file paths.
-       
-       After instatiating the class, file paths can be accessed via the self.paths dictionary.
-       System file paths are listed under the 'system' key, user file paths under the 'user' key.
-
-       For example, to get the path to both the user and system binwalk magic files:
-
-               from binwalk import Config
-
-               conf = Config()
-               user_binwalk_file = conf.paths['user'][conf.BINWALK_MAGIC_FILE]
-               system_binwalk_file = conf.paths['system'][conf.BINWALK_MAGIC_FILE]
-
-       There is also an instance of this class available via the Binwalk.config object:
-
-               import binwalk
-
-               bw = binwalk.Binwalk()
-
-               user_binwalk_file = bw.config.paths['user'][conf.BINWALK_MAGIC_FILE]
-               system_binwalk_file = bw.config.paths['system'][conf.BINWALK_MAGIC_FILE]
-
-       Valid file names under both the 'user' and 'system' keys are as follows:
-
-               o BINWALK_MAGIC_FILE  - Path to the default binwalk magic file.
-               o BINCAST_MAGIC_FILE  - Path to the bincast magic file (used when -C is specified with the command line binwalk script).
-               o BINARCH_MAGIC_FILE  - Path to the binarch magic file (used when -A is specified with the command line binwalk script).
-               o EXTRACT_FILE        - Path to the extract configuration file (used when -e is specified with the command line binwalk script).
-               o PLUGINS             - Path to the plugins directory.
-       '''
-       # Release version
-       VERSION = "1.2.2-1"
-
-       # Sub directories
-       BINWALK_USER_DIR = ".binwalk"
-       BINWALK_MAGIC_DIR = "magic"
-       BINWALK_CONFIG_DIR = "config"
-       BINWALK_PLUGINS_DIR = "plugins"
-
-       # File names
-       PLUGINS = "plugins"
-       EXTRACT_FILE = "extract.conf"
-       BINWALK_MAGIC_FILE = "binwalk"
-       BINCAST_MAGIC_FILE = "bincast"
-       BINARCH_MAGIC_FILE = "binarch"
-       ZLIB_MAGIC_FILE = "zlib"
-
-       def __init__(self):
-               '''
-               Class constructor. Enumerates file paths and populates self.paths.
-               '''
-               # Path to the user binwalk directory
-               self.user_dir = self._get_user_dir()
-               # Path to the system wide binwalk directory
-               self.system_dir = self._get_system_dir()
-
-               # Dictionary of all absolute user/system file paths
-               self.paths = {
-                       'user'          : {},
-                       'system'        : {},
-               }
-
-               # Build the paths to all user-specific files
-               self.paths['user'][self.BINWALK_MAGIC_FILE] = self._user_path(self.BINWALK_MAGIC_DIR, self.BINWALK_MAGIC_FILE)
-               self.paths['user'][self.BINCAST_MAGIC_FILE] = self._user_path(self.BINWALK_MAGIC_DIR, self.BINCAST_MAGIC_FILE)
-               self.paths['user'][self.BINARCH_MAGIC_FILE] = self._user_path(self.BINWALK_MAGIC_DIR, self.BINARCH_MAGIC_FILE)
-               self.paths['user'][self.EXTRACT_FILE] = self._user_path(self.BINWALK_CONFIG_DIR, self.EXTRACT_FILE)
-               self.paths['user'][self.PLUGINS] = self._user_path(self.BINWALK_PLUGINS_DIR)
-
-               # Build the paths to all system-wide files
-               self.paths['system'][self.BINWALK_MAGIC_FILE] = self._system_path(self.BINWALK_MAGIC_DIR, self.BINWALK_MAGIC_FILE)
-               self.paths['system'][self.BINCAST_MAGIC_FILE] = self._system_path(self.BINWALK_MAGIC_DIR, self.BINCAST_MAGIC_FILE)
-               self.paths['system'][self.BINARCH_MAGIC_FILE] = self._system_path(self.BINWALK_MAGIC_DIR, self.BINARCH_MAGIC_FILE)
-               self.paths['system'][self.ZLIB_MAGIC_FILE] = self._system_path(self.BINWALK_MAGIC_DIR, self.ZLIB_MAGIC_FILE)
-               self.paths['system'][self.EXTRACT_FILE] = self._system_path(self.BINWALK_CONFIG_DIR, self.EXTRACT_FILE)
-               self.paths['system'][self.PLUGINS] = self._system_path(self.BINWALK_PLUGINS_DIR)
-       
-       def _get_system_dir(self):
-               '''
-               Find the directory where the binwalk module is installed on the system.
-               '''
-               try:
-                       root = __file__
-                       if os.path.islink(root):
-                               root = os.path.realpath(root)
-                       return os.path.dirname(os.path.abspath(root))
-               except:
-                       return ''
-
-       def _get_user_dir(self):
-               '''
-               Get the user's home directory.
-               '''
-               try:
-                       # This should work in both Windows and Unix environments
-                       return os.getenv('USERPROFILE') or os.getenv('HOME')
-               except:
-                       return ''
-
-       def _file_path(self, dirname, filename):
-               '''
-               Builds an absolute path and creates the directory and file if they don't already exist.
-
-               @dirname  - Directory path.
-               @filename - File name.
-               
-               Returns a full path of 'dirname/filename'.
-               '''
-               if not os.path.exists(dirname):
-                       try:
-                               os.makedirs(dirname)
-                       except:
-                               pass
-               
-               fpath = os.path.join(dirname, filename)
-
-               if not os.path.exists(fpath):
-                       try:
-                               open(fpath, "w").close()
-                       except:
-                               pass
-
-               return fpath
-
-       def _user_path(self, subdir, basename=''):
-               '''
-               Gets the full path to the 'subdir/basename' file in the user binwalk directory.
-
-               @subdir   - Subdirectory inside the user binwalk directory.
-               @basename - File name inside the subdirectory.
-
-               Returns the full path to the 'subdir/basename' file.
-               '''
-               return self._file_path(os.path.join(self.user_dir, self.BINWALK_USER_DIR, subdir), basename)
-
-       def _system_path(self, subdir, basename=''):
-               '''
-               Gets the full path to the 'subdir/basename' file in the system binwalk directory.
-               
-               @subdir   - Subdirectory inside the system binwalk directory.
-               @basename - File name inside the subdirectory.
-               
-               Returns the full path to the 'subdir/basename' file.
-               '''
-               return self._file_path(os.path.join(self.system_dir, subdir), basename)
-
diff --git a/binwalk/config/extract.conf b/binwalk/config/extract.conf
deleted file mode 100644 (file)
index 02aa722..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#################################################################################################################
-# Default extract rules loaded when --extract is specified.
-# 
-# <case-insensitive unique string from binwalk output text>:<desired file extension>:<command to execute>
-#
-# Note that %e is a place holder for the extracted file name.
-#################################################################################################################
-
-# Assumes these utilities are installed in $PATH.
-^gzip compressed data:gz:gzip -d -f '%e'
-^lzma compressed data:7z:7zr e -y '%e'
-^bzip2 compressed data:bz2:bzip2 -d -f '%e'
-^zip archive data:zip:jar xf '%e' # jar does a better job of unzipping than unzip does...
-^posix tar archive:tar:tar xvf '%e'
-^rar archive data:rar:unrar e '%e'
-^arj archive data.*comment header:arj:arj e '%e'
-^iso 9660:iso:7z x '%e' -oiso-root
-
-# These assume the firmware-mod-kit is installed to /opt/firmware-mod-kit.
-# 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'
-^ascii cpio archive:cpio:/opt/firmware-mod-kit/uncpio.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'
-^wdk file system:wdk:/opt/firmware-mod-kit/src/firmware-tools/unwdk.py '%e'
-^zlib header:zlib:/opt/firmware-mod-kit/src/firmware-tools/unzlib.py '%e'
-^ext2 filesystem:ext2:/opt/firmware-mod-kit/src/mountcp/mountcp '%e' ext2-root
-^romfs filesystem:romfs:/opt/firmware-mod-kit/src/mountcp/mountcp '%e' romfs-root
-
-# These paths are for the depreciated firmware-mod-kit file paths, which included the 'trunk' directory.
-# These will only be run if the above file paths don't exist.
-^squashfs filesystem:squashfs:/opt/firmware-mod-kit/trunk/unsquashfs_all.sh '%e'
-^jffs2 filesystem:jffs2:/opt/firmware-mod-kit/trunk/src/jffs2/unjffs2 '%e' # requires root
-^ascii cpio archive:cpio:/opt/firmware-mod-kit/trunk/uncpio.sh '%e'
-^cramfs filesystem:cramfs:/opt/firmware-mod-kit/trunk/uncramfs_all.sh '%e'
-^bff volume entry:bff:/opt/firmware-mod-kit/trunk/src/bff/bffxtractor.py '%e'
-
-# If FMK isn't installed, try the system's unsquashfs for SquashFS files
-^squashfs filesystem:squashfs:unsquashfs '%e'
-
-# Extract, but don't run anything
-private key:key
-certificate:crt
diff --git a/binwalk/entropy.py b/binwalk/entropy.py
deleted file mode 100644 (file)
index 885518c..0000000
+++ /dev/null
@@ -1,505 +0,0 @@
-import zlib
-import math
-import os.path
-import plugins
-import common
-import compression
-
-class PlotEntropy(object):
-       '''
-       Class to plot entropy data on a graph.
-       '''
-
-       YLIM_MIN = 0
-       YLIM_MAX = 1.5
-
-       XLABEL = 'Offset'
-       YLABEL = 'Entropy'
-
-       LINE_WIDTH = 1.5
-
-       COLORS = ['darkgreen', 'blueviolet', 'saddlebrown', 'deeppink', 'goldenrod', 'olive', 'black']
-
-       FILE_FORMAT = 'svg'
-       
-       def __init__(self, x, y, title='Entropy', average=0, file_results={}, show_legend=True, save=False):
-               '''
-               Plots entropy data.
-
-               @x            - List of graph x-coordinates (i.e., data offsets).
-               @y            - List of graph y-coordinates (i.e., entropy for each offset).
-               @title        - Graph title.
-               @average      - The average entropy.
-               @file_results - Binwalk results, if any.
-               @show_legend  - Set to False to not generate a color-coded legend and plotted x coordinates for the graph.
-               @save         - If set to True, graph will be saved to disk rather than displayed.
-
-               Returns None.
-               '''
-               import matplotlib.pyplot as plt
-               import numpy as np
-
-               i = 0
-               trigger = 0
-               new_ticks = []
-               color_mappings = {}
-
-               plt.clf()
-
-               if file_results:
-                       for (offset, results) in file_results:
-                               label = None
-                               description = results[0]['description'].split(',')[0]
-
-                               if not color_mappings.has_key(description):
-                                       if show_legend:
-                                               label = description
-
-                                       color_mappings[description] = self.COLORS[i]
-                                       i += 1
-                                       if i >= len(self.COLORS):
-                                               i = 0
-                       
-                               plt.axvline(x=offset, label=label, color=color_mappings[description], linewidth=self.LINE_WIDTH)
-                               new_ticks.append(offset)
-
-                       if show_legend:
-                               plt.legend()
-
-                               if new_ticks:
-                                       new_ticks.sort()
-                                       plt.xticks(np.array(new_ticks), new_ticks)
-
-               plt.plot(x, y, linewidth=self.LINE_WIDTH)
-
-               if average:
-                       plt.plot(x, [average] * len(x), linestyle='--', color='r')
-
-               plt.xlabel(self.XLABEL)
-               plt.ylabel(self.YLABEL)
-               plt.title(title)
-               plt.ylim(self.YLIM_MIN, self.YLIM_MAX)
-               if save:
-                       plt.savefig(common.unique_file_name(title, self.FILE_FORMAT))
-               else:
-                       plt.show()
-
-
-class FileEntropy(object):
-       '''
-       Class for analyzing and plotting data entropy for a file.
-       Preferred to use the Entropy class instead of calling FileEntropy directly.
-       '''
-
-       DEFAULT_BLOCK_SIZE = 1024
-       ENTROPY_TRIGGER = 0.9
-       ENTROPY_MAX = 0.95
-
-       def __init__(self, file_name=None, fd=None, binwalk=None, offset=0, length=None, block=DEFAULT_BLOCK_SIZE, plugins=None, file_results=[], compcheck=False):
-               '''
-               Class constructor.
-
-               @file_name    - The path to the file to analyze.
-               @fd           - A file object to analyze data from.
-               @binwalk      - An instance of the Binwalk class.
-               @offset       - The offset into the data to begin analysis.
-               @length       - The number of bytes to analyze.
-               @block        - The size of the data blocks to analyze.
-               @plugins      - Instance of the Plugins class.
-               @file_results - Scan results to overlay on the entropy plot graph.
-               @compcheck    - Set to True to enable entropy compression detection.
-
-               Returns None.
-               '''
-               self.fd = fd
-               self.start = offset
-               self.length = length
-               self.block = block
-               self.binwalk = binwalk
-               self.plugins = plugins
-               self.total_read = 0
-               self.fd_open = False
-               self.file_results = file_results
-               self.do_chisq = compcheck
-
-               if file_name is None and self.fd is None:
-                       raise Exception("Entropy.__init__ requires at least the file_name or fd options")
-
-               if self.fd is None:
-                       self.fd = open(file_name, 'rb')
-                       self.fd_open = True
-
-               if not self.length:
-                       self.length = None
-
-               if not self.start:
-                       self.start = 0
-
-               if not self.block:
-                       self.block = self.DEFAULT_BLOCK_SIZE
-                       
-               # Some file descriptors aren't seekable (stdin, for example)
-               try:
-                       self.fd.seek(self.start)
-               except:
-                       self.fd.read(self.start)
-
-               if self.binwalk:
-                       # Set the total_scanned and scan_length values for plugins and status display messages
-                       self.binwalk.total_scanned = 0
-                       if self.length:
-                               self.binwalk.scan_length = self.length
-                       else:
-                               self.binwalk.scan_length = common.file_size(self.fd.name) - self.start
-
-       def __enter__(self):
-               return self
-
-       def __del__(self):
-               self.cleanup()
-
-       def __exit__(self, t, v, traceback):
-               self.cleanup()
-
-       def cleanup(self):
-               '''
-               Clean up any open file objects.
-               Called internally by __del__ and __exit__.
-
-               Returns None.
-               '''
-               try:
-                       if self.fd_open:
-                               self.fd.close()
-               except:
-                       pass
-
-       def _read_block(self):
-               offset = self.total_read
-
-               if self.length is not None and (self.total_read + self.block) > self.length:
-                       read_size = self.length - self.total_read
-               else:
-                       read_size = self.block
-
-               data = self.fd.read(read_size)
-               dlen = len(data)
-
-               if self.binwalk:
-                       self.binwalk.total_scanned = self.total_read
-
-               self.total_read += dlen
-
-               return (dlen, data, offset+self.start)
-
-       def gzip(self, offset, data, truncate=True):
-               '''
-               Performs an entropy analysis based on zlib compression ratio.
-               This is faster than the shannon entropy analysis, but not as accurate.
-               '''
-               # Entropy is a simple ratio of: <zlib compressed size> / <original size>
-               e = float(float(len(zlib.compress(data, 9))) / float(len(data)))
-
-               if truncate and e > 1.0:
-                       e = 1.0
-
-               return e
-
-       def shannon(self, offset, data):
-               '''
-               Performs a Shannon entropy analysis on a given block of data.
-               '''
-               entropy = 0
-               dlen = len(data)
-
-               if not data:
-                       return 0
-
-               for x in range(256):
-                       p_x = float(data.count(chr(x))) / dlen
-                       if p_x > 0:
-                               entropy += - p_x*math.log(p_x, 2)
-
-               return (entropy / 8)
-
-       def _do_analysis(self, algorithm):
-               '''
-               Performs an entropy analysis using the provided algorithm.
-
-               @algorithm - A function/method to call which returns an entropy value.
-
-               Returns a tuple of ([x-coordinates], [y-coordinates], average_entropy), where:
-
-                       o x-coordinates = A list of offsets analyzed inside the data.
-                       o y-coordinates = A corresponding list of entropy for each offset.
-               '''
-               offsets = []
-               entropy = []
-               average = 0
-               total = 0
-               self.total_read = 0
-               plug_ret = plugins.PLUGIN_CONTINUE
-               plug_pre_ret = plugins.PLUGIN_CONTINUE
-
-               if self.plugins:
-                       plug_pre_ret = self.plugins._pre_scan_callbacks(self.fd)
-
-               while not ((plug_pre_ret | plug_ret) & plugins.PLUGIN_TERMINATE):
-                       (dlen, data, offset) = self._read_block()
-                       if not dlen or not data:
-                               break
-
-                       e = algorithm(offset, data)
-
-                       results = {'description' : '%f' % e, 'offset' : offset}
-
-                       if self.plugins:
-                               plug_ret = self.plugins._scan_callbacks(results)
-                               offset = results['offset']
-                               e = float(results['description'])
-
-                       if not ((plug_pre_ret | plug_ret) & (plugins.PLUGIN_TERMINATE | plugins.PLUGIN_NO_DISPLAY)):
-                               if self.binwalk and not self.do_chisq:
-                                       self.binwalk.display.results(offset, [results])
-
-                               entropy.append(e)
-                               offsets.append(offset)
-                               total += e
-
-               try:
-                       # This results in a divide by zero if one/all plugins returns PLUGIN_TERMINATE or PLUGIN_NO_DISPLAY,
-                       # or if the file being scanned is a zero-size file.
-                       average = float(float(total) / float(len(offsets)))
-               except:
-                       pass
-
-               if self.plugins:
-                       self.plugins._post_scan_callbacks(self.fd)
-       
-               return (offsets, entropy, average)
-
-       def _look_for_compression(self, x, y):
-               '''
-               Analyzes areas of high entropy for signs of compression or encryption and displays the results.
-               '''
-               trigger = self.ENTROPY_TRIGGER
-               pairs = []
-               scan_pairs = []
-               index = -1
-               total = 0
-
-               if not self.file_results:
-                       for j in range(0, len(x)):
-                               if y[j] >= trigger and (j == 0 or y[j-1] < trigger):
-                                       pairs.append([x[j]])
-                                       index = len(pairs) - 1
-                               elif y[j] <= trigger and y[j-1] > trigger and index > -1 and len(pairs[index]) == 1:
-                                       pairs[index].append(x[j])
-
-                       # Generate a list of tuples containing the starting offset to begin analysis plus a length
-                       for pair in pairs:
-                               start = pair[0]
-                               if len(pair) == 2:
-                                       stop = pair[1]
-                               else:
-                                       self.fd.seek(0, 2)
-                                       stop = self.fd.tell()
-
-                               length = stop - start
-                               total += length
-                               scan_pairs.append((start, length))
-
-                       # Update the binwalk scan length and total scanned values so that the percent complete
-                       # isn't stuck at 100% after the initial entropy analysis (which has already finished).
-                       if self.binwalk and total > 0:
-                               self.binwalk.scan_length = total
-                               self.binwalk.total_scanned = 0
-
-                       # Analyze each scan pair and display the results
-                       for (start, length) in scan_pairs:
-                               # Ignore anything less than 4KB in size
-                               if length > (self.DEFAULT_BLOCK_SIZE * 4):
-                                       # Ignore the first and last 1KB of data to prevent header/footer or extra data from skewing results
-                                       result = compression.CompressionEntropyAnalyzer(None, start+self.DEFAULT_BLOCK_SIZE, length-self.DEFAULT_BLOCK_SIZE, fp=self.fd).analyze()
-                                       results = [{'description' : result[0]['description'], 'offset' : start}]
-       
-                                       self.file_results.append((start, results))
-                                       if self.binwalk:
-                                               self.binwalk.display.results(start, results)
-
-                               # Keep the total scanned length updated
-                               if self.binwalk:
-                                       self.binwalk.total_scanned += length
-
-       def analyze(self, algorithm=None):
-               '''
-               Performs an entropy analysis of the data using the specified algorithm.
-
-               @algorithm - A method inside of the Entropy class to invoke for entropy analysis.
-                            Default method: self.shannon.
-                            Other available methods: self.gzip.
-                            May also be a string: 'gzip'.
-
-               Returns the return value of algorithm.
-               '''
-               algo = self.shannon
-
-               if algorithm:
-                       if callable(algorithm):
-                               algo = algorithm
-
-                       try:
-                               if algorithm.lower() == 'gzip':
-                                       algo = self.gzip
-                       except:
-                               pass
-
-               return self._do_analysis(algo)
-       
-       def plot(self, x, y, average=0, show_legend=True, save=False):
-               '''
-               Plots entropy data.
-
-               @x            - List of graph x-coordinates (i.e., data offsets).
-               @y            - List of graph y-coordinates (i.e., entropy for each offset).
-               @average      - The average entropy.
-               @show_legend  - Set to False to not generate a color-coded legend and plotted x coordinates for the graph.
-               @save         - If set to True, graph will be saved to disk rather than displayed.
-
-               Returns None.
-               '''
-               if self.do_chisq:
-                       self._look_for_compression(x, y)
-
-               PlotEntropy(x, y, self.fd.name, average, self.file_results, show_legend, save)
-
-class Entropy(object):
-       '''
-       Class for analyzing and plotting data entropy for multiple files.
-
-       A simple example of performing a binwalk scan and overlaying the binwalk scan results on the
-       resulting entropy analysis graph:
-
-               import sys
-               import binwalk
-
-               bwalk = binwalk.Binwalk()
-               scan_results = bwalk.scan(sys.argv[1])
-
-                with binwalk.entropy.Entropy(scan_results, bwalk) as e:
-                        e.analyze()
-
-               bwalk.cleanup()
-       '''
-
-       DESCRIPTION = "ENTROPY ANALYSIS"
-       ALT_DESCRIPTION = "HEURISTIC ANALYSIS"
-       ENTROPY_SCAN = 'entropy'
-
-       def __init__(self, files, binwalk=None, offset=0, length=0, block=0, plot=True, legend=True, save=False, algorithm=None, load_plugins=True, whitelist=[], blacklist=[], compcheck=False):
-               '''
-               Class constructor.
-
-               @files        - A dictionary containing file names and results data, as returned by Binwalk.scan.
-               @binwalk      - An instance of the Binwalk class.
-               @offset       - The offset into the data to begin analysis.
-               @length       - The number of bytes to analyze.
-               @block        - The size of the data blocks to analyze.
-               @plot         - Set to False to disable plotting.
-               @legend       - Set to False to exclude the legend and custom offset markers from the plot.
-               @save         - Set to True to save plots to disk instead of displaying them.
-               @algorithm    - Set to 'gzip' to use the gzip entropy "algorithm".
-               @load_plugins - Set to False to disable plugin callbacks.
-               @whitelist    - A list of whitelisted plugins.
-               @blacklist    - A list of blacklisted plugins.
-               @compcheck    - Set to True to enable entropy compression detection.
-
-               Returns None.
-               '''
-               self.files = files
-               self.binwalk = binwalk
-               self.offset = offset
-               self.length = length
-               self.block = block
-               self.plot = plot
-               self.legend = legend
-               self.save = save
-               self.algorithm = algorithm
-               self.plugins = None
-               self.load_plugins = load_plugins
-               self.whitelist = whitelist
-               self.blacklist = blacklist
-               self.compcheck = compcheck
-
-               if len(self.files) > 1:
-                       self.save = True
-
-               if self.binwalk:
-                       self.binwalk.scan_type = self.binwalk.ENTROPY
-
-       def __enter__(self):
-               return self
-
-       def __exit__(self, t, v, traceback):
-               return None
-
-       def __del__(self):
-               return None
-
-       def set_entropy_algorithm(self, algorithm):
-               '''
-               Specify a function/method to call for determining data entropy.
-
-               @algorithm - The function/method to call. This will be  passed two arguments:
-                            the file offset of the data block, and a data block (type 'str').
-                            It must return a single floating point entropy value from 0.0 and 1.0, inclusive.
-
-               Returns None.
-               '''
-               self.algorithm = algorithm
-
-       def analyze(self):
-               '''
-               Perform an entropy analysis on the target files.
-
-               Returns a dictionary of:
-                       
-                       {
-                               'file_name' : ([list, of, offsets], [list, of, entropy], average_entropy)
-                       }
-               '''
-               results = {}
-
-               if self.binwalk and self.load_plugins:
-                       self.plugins = plugins.Plugins(self.binwalk, whitelist=self.whitelist, blacklist=self.blacklist)
-
-               for (file_name, overlay) in self.files.iteritems():
-
-                       if self.plugins:
-                               self.plugins._load_plugins()
-
-                       if self.binwalk:
-                               if self.compcheck:
-                                       desc = self.ALT_DESCRIPTION
-                               else:
-                                       desc = self.DESCRIPTION
-
-                               self.binwalk.display.header(file_name=file_name, description=desc)
-
-                       with FileEntropy(file_name=file_name, binwalk=self.binwalk, offset=self.offset, length=self.length, block=self.block, plugins=self.plugins, file_results=overlay, compcheck=self.compcheck) as e:
-                               (x, y, average) = e.analyze(self.algorithm)
-                               
-                               if self.plot or self.save:
-                                       e.plot(x, y, average, self.legend, self.save)
-                               
-                               results[file_name] = (x, y, average)
-
-                       if self.binwalk:
-                               self.binwalk.display.footer()
-
-               if self.plugins:
-                       del self.plugins
-                       self.plugins = None
-
-               return results
-
diff --git a/binwalk/extractor.py b/binwalk/extractor.py
deleted file mode 100644 (file)
index 02dc4ec..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-import os
-import re
-import sys
-import shlex
-import tempfile
-import subprocess
-from config import *
-from common import file_size, unique_file_name
-
-class Extractor:
-       '''
-       Extractor class, responsible for extracting files from the target file and executing external applications, if requested.
-       An instance of this class is accessible via the Binwalk.extractor object.
-
-       Example usage:
-
-               import binwalk
-               
-               bw = binwalk.Binwalk()
-
-               # Create extraction rules for scan results containing the string 'gzip compressed data' and 'filesystem'.
-               # The former will be saved to disk with a file extension of 'gz' and the command 'gunzip <file name on disk>' will be executed (note the %e placeholder).
-               # The latter will be saved to disk with a file extension of 'fs' and no command will be executed.
-               # These rules will be ignored if there were previous rules with the same match string.
-               bw.extractor.add_rule(['gzip compressed data:gz:gunzip %e', 'filesystem:fs'])
-
-               # Load the extraction rules from the default extract.conf file(s).
-               bw.extractor.load_defaults()
-
-               # Run the binwalk scan.
-               bw.scan('firmware.bin')
-               
-       '''
-       # Extract rules are delimited with a colon.
-       # <case insensitive matching string>:<file extension>[:<command to run>]
-       RULE_DELIM = ':'
-
-       # Comments in the extract.conf files start with a pound
-       COMMENT_DELIM ='#'
-
-       # Place holder for the extracted file name in the command 
-       FILE_NAME_PLACEHOLDER = '%e'
-
-       # Max size of data to read/write at one time when extracting data
-       MAX_READ_SIZE = 10 * 1024 * 1024
-
-       def __init__(self, verbose=False):
-               '''
-               Class constructor.
-       
-               @verbose - Set to True to display the output from any executed external applications.
-
-               Returns None.
-               '''
-               self.config = Config()
-               self.enabled = False
-               self.delayed = False
-               self.verbose = verbose
-               self.extract_rules = []
-               self.remove_after_execute = False
-               self.extract_path = os.getcwd()
-
-       def add_rule(self, txtrule=None, regex=None, extension=None, cmd=None):
-               '''
-               Adds a set of rules to the extraction rule list.
-
-               @txtrule   - Rule string, or list of rule strings, in the format <regular expression>:<file extension>[:<command to run>]
-               @regex     - If rule string is not specified, this is the regular expression string to use.
-               @extension - If rule string is not specified, this is the file extension to use.
-               @cmd       - If rule string is not specified, this is the command to run.
-                            Alternatively a callable object may be specified, which will be passed one argument: the path to the file to extract.
-
-               Returns None.
-               '''
-               rules = []
-               match = False
-               r = {
-                       'extension'     : '',
-                       'cmd'           : '',
-                       'regex'         : None
-               }
-
-               if not txtrule and regex and extension:
-                       txtrule = '%s:%s' % (regex, extension)
-                       if cmd:
-                               txtrule += ':%s' % cmd
-
-               if not isinstance(txtrule, type([])):
-                       rules = [txtrule]
-               else:
-                       rules = txtrule
-               
-               for rule in rules:
-                       r['cmd'] = ''
-                       r['extension'] = ''
-
-                       try:
-                               values = self._parse_rule(rule)
-                               match = values[0]
-                               r['regex'] = re.compile(values[0])
-                               r['extension'] = values[1]
-                               r['cmd'] = values[2]
-                       except:
-                               pass
-
-                       if not match and regex and extension:
-                               match = regex
-                               r['regex'] = re.compile(regex)
-                               r['extension'] = extension
-                               r['cmd'] = cmd
-
-                       # Verify that the match string and file extension were retrieved.
-                       if match and r['extension']:
-                               self.extract_rules.append(r.copy())
-                               # Once any rule is added, set self.enabled to True
-                               self.enabled = True
-
-       def remove_rule(self, text):
-               '''
-               Remove all rules that match a specified text.
-
-               @text - The text to match against.
-
-               Returns the number of rules removed.
-               '''
-               rm = []
-
-               for i in range(0, len(self.extract_rules)):
-                       if self.extract_rules[i]['regex'].match(text):
-                               rm.append(i)
-               
-               for i in rm:
-                       self.extract_rules.pop(i)
-
-               return len(rm)
-
-       def clear_rules(self):
-               '''
-               Deletes all extraction rules.
-
-               Returns None.
-               '''
-               self.extract_rules = []
-               self.enabled = False
-
-       def get_rules(self):
-               '''
-               Returns a list of all extraction rules.
-               '''
-               return self.extract_rules
-
-       def enable_delayed_extract(self, tf=None):
-               '''
-               Enables / disables the delayed extraction feature.
-               This feature ensures that certian supported file types will not contain extra data at the end of the
-               file when they are extracted, but also means that these files will not be extracted until the end of the scan.
-
-               @tf - Set to True to enable, False to disable. 
-
-               Returns the current delayed extraction setting.
-               '''
-               if tf is not None:
-                       self.delayed = tf
-               return self.delayed
-
-       def load_from_file(self, fname):
-               '''
-               Loads extraction rules from the specified file.
-
-               @fname - Path to the extraction rule file.
-               
-               Returns None.
-               '''
-               try:
-                       # Process each line from the extract file, ignoring comments
-                       for rule in open(fname).readlines():
-                               self.add_rule(rule.split(self.COMMENT_DELIM, 1)[0])
-               except Exception, e:
-                       raise Exception("Extractor.load_from_file failed to load file '%s': %s" % (fname, str(e)))
-
-       def load_defaults(self):
-               '''
-               Loads default extraction rules from the user and system extract.conf files.
-
-               Returns None.
-               '''
-               # Load the user extract file first to ensure its rules take precedence.
-               extract_files = [
-                       self.config.paths['user'][self.config.EXTRACT_FILE],
-                       self.config.paths['system'][self.config.EXTRACT_FILE],
-               ]
-
-               for extract_file in extract_files:
-                       try:
-                               self.load_from_file(extract_file)
-                       except Exception, e:
-                               if self.verbose:
-                                       raise Exception("Extractor.load_defaults failed to load file '%s': %s" % (extract_file, str(e)))
-
-       def output_directory(self, path):
-               '''
-               Set the output directory for extracted files.
-
-               @path - The extraction path.
-
-               Returns None.
-               '''
-               self.extract_path = path
-
-       def cleanup_extracted_files(self, tf=None):
-               '''
-               Set the action to take after a file is extracted.
-
-               @tf - If set to True, extracted files will be cleaned up after running a command against them.
-                     If set to False, extracted files will not be cleaned up after running a command against them.
-                     If set to None or not specified, the current setting will not be changed.
-
-               Returns the current cleanup status (True/False).
-               '''
-               if tf is not None:
-                       self.remove_after_execute = tf
-
-               return self.remove_after_execute
-       
-       def extract(self, offset, description, file_name, size, name=None):
-               '''
-               Extract an embedded file from the target file, if it matches an extract rule.
-               Called automatically by Binwalk.scan().
-
-               @offset      - Offset inside the target file to begin the extraction.
-               @description - Description of the embedded file to extract, as returned by libmagic.
-               @file_name   - Path to the target file.
-               @size        - Number of bytes to extract.
-               @name        - Name to save the file as.
-
-               Returns the name of the extracted file (blank string if nothing was extracted).
-               '''
-               fname = ''
-               cleanup_extracted_fname = True
-               original_dir = os.getcwd()
-
-               if not os.path.exists(self.extract_path):
-                       os.mkdir(self.extract_path)
-
-               file_path = os.path.realpath(file_name)
-               
-               if os.path.isfile(file_path):
-                       os.chdir(self.extract_path)
-                       
-                       rules = self._match(description)
-                               
-                       # Loop through each extraction rule until one succeeds
-                       for i in range(0, len(rules)):
-                               rule = rules[i]
-
-                               # Copy out the data to disk, if we haven't already
-                               fname = self._dd(file_path, offset, size, rule['extension'], output_file_name=name)
-
-                               # If there was a command specified for this rule, try to execute it.
-                               # If execution fails, the next rule will be attempted.
-                               if rule['cmd']:
-
-                                       # 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
-                                       # file name already exists before executing the extract command, do not attempt 
-                                       # to clean it up even if its resulting file size is 0.
-                                       if self.remove_after_execute:
-                                               extracted_fname = os.path.splitext(fname)[0]
-                                               if os.path.exists(extracted_fname):
-                                                       cleanup_extracted_fname = False
-       
-                                       # Execute the specified command against the extracted file
-                                       extract_ok = self._execute(rule['cmd'], fname)
-
-                                       # Only clean up files if remove_after_execute was specified                             
-                                       if self.remove_after_execute:
-
-                                               # Remove the original file that we extracted
-                                               try:
-                                                       os.unlink(fname)
-                                               except:
-                                                       pass
-
-                                               # If the command worked, assume it removed the file extension from the extracted file
-
-                                               # If the extracted file name file exists and is empty, remove it
-                                               if cleanup_extracted_fname and os.path.exists(extracted_fname) and file_size(extracted_fname) == 0:
-                                                       try:
-                                                               os.unlink(extracted_fname)
-                                                       except:
-                                                               pass
-                                       
-                                       # If the command executed OK, don't try any more rules
-                                       if extract_ok:
-                                               break
-                                       # Else, remove the extracted file if this isn't the last rule in the list.
-                                       # If it is the last rule, leave the file on disk for the user to examine.
-                                       elif i != len(rules):
-                                               try:
-                                                       os.unlink(fname)
-                                               except:
-                                                       pass
-
-                               # If there was no command to execute, just use the first rule
-                               else:
-                                       break
-
-                       os.chdir(original_dir)
-
-               # If a file was extracted, return the full path to that file    
-               if fname:
-                       fname = os.path.join(self.extract_path, fname)
-
-               return fname
-
-       def delayed_extract(self, results, file_name, size):
-               '''
-               Performs a delayed extraction (see self.enable_delayed_extract).
-               Called internally by Binwalk.Scan().
-
-               @results   - A list of dictionaries of all the scan results.
-               @file_name - The path to the scanned file.
-               @size      - The size of the scanned file.
-
-               Returns an updated results list containing the names of the newly extracted files.
-               '''
-               index = 0
-               info_count = 0
-               nresults = results
-
-               for (offset, infos) in results:
-                       info_count = 0
-
-                       for info in infos:
-                               ninfos = infos
-
-                               if info['delay']:
-                                       end_offset = self._entry_offset(index, results, info['delay'])
-                                       if end_offset == -1:
-                                               extract_size = size
-                                       else:
-                                               extract_size = (end_offset - offset)
-
-                                       ninfos[info_count]['extract'] = self.extract(offset, info['description'], file_name, extract_size, info['name'])
-                                       nresults[index] = (offset, ninfos)
-
-                               info_count += 1
-
-                       index += 1
-               
-               return nresults
-
-       def _entry_offset(self, index, entries, description):
-               '''
-               Gets the offset of the first entry that matches the description.
-
-               @index       - Index into the entries list to begin searching.
-               @entries     - Dictionary of result entries.
-               @description - Case insensitive description.
-
-               Returns the offset, if a matching description is found.
-               Returns -1 if a matching description is not found.
-               '''
-               description = description.lower()
-
-               for (offset, infos) in entries[index:]:
-                       for info in infos:
-                               if info['description'].lower().startswith(description):
-                                       return offset
-               return -1
-
-       def _match(self, description):
-               '''
-               Check to see if the provided description string matches an extract rule.
-               Called internally by self.extract().
-
-               @description - Description string to check.
-
-               Returns the associated rule dictionary if a match is found.
-               Returns None if no match is found.
-               '''
-               rules = []
-               description = description.lower()
-
-               for rule in self.extract_rules:
-                       if rule['regex'].search(description):
-                               rules.append(rule)
-               return rules
-
-       def _parse_rule(self, rule):
-               '''
-               Parses an extraction rule.
-
-               @rule - Rule string.
-
-               Returns an array of ['<case insensitive matching string>', '<file extension>', '<command to run>'].
-               '''
-               return rule.strip().split(self.RULE_DELIM, 2)
-
-       def _dd(self, file_name, offset, size, extension, output_file_name=None):
-               '''
-               Extracts a file embedded inside the target file.
-
-               @file_name        - Path to the target file.
-               @offset           - Offset inside the target file where the embedded file begins.
-               @size             - Number of bytes to extract.
-               @extension        - The file exension to assign to the extracted file on disk.
-               @output_file_name - The requested name of the output file.
-
-               Returns the extracted file name.
-               '''
-               total_size = 0
-
-               if not output_file_name or output_file_name is None:
-                       # Default extracted file name is <hex offset>.<extension>
-                       bname = "%X" % offset
-               else:
-                       # Strip the output file name of invalid/dangerous characters (like file paths)  
-                       bname = os.path.basename(output_file_name)
-               
-               fname = unique_file_name(bname, extension)
-
-               try:
-                       # Open the target file and seek to the offset
-                       fdin = open(file_name, "rb")
-                       fdin.seek(offset)
-                       
-                       # Open the output file
-                       try:
-                               fdout = open(fname, "wb")
-                       except:
-                               # Fall back to the alternate name if the requested name fails
-                               fname = altname
-                               fdout = open(fname, "wb")
-
-                       # Read data from target file in chunks and write it to the extracted file
-                       while total_size < size:
-                               block_size = size - total_size
-                               if block_size > self.MAX_READ_SIZE:
-                                       block_size = self.MAX_READ_SIZE
-                       
-                               fdout.write(fdin.read(block_size))
-                               total_size += block_size
-
-                       # Cleanup
-                       fdout.close()
-                       fdin.close()
-               except Exception, e:
-                       raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e)))
-               
-               return fname
-
-       def _execute(self, cmd, fname):
-               '''
-               Execute a command against the specified file.
-
-               @cmd   - Command to execute.
-               @fname - File to run command against.
-
-               Returns True on success, False on failure.
-               '''
-               tmp = None
-               retval = True
-
-               try:
-                       if callable(cmd):
-                               cmd(fname)
-                       else:
-                               # If not in verbose mode, create a temporary file to redirect stdout and stderr to
-                               if not self.verbose:
-                                       tmp = tempfile.TemporaryFile()
-
-                               # Replace all instances of FILE_NAME_PLACEHOLDER in the command with fname
-                               cmd = cmd.replace(self.FILE_NAME_PLACEHOLDER, fname)
-       
-                               # Execute.
-                               subprocess.call(shlex.split(cmd), stdout=tmp, stderr=tmp)
-               except Exception, e:
-                       # Silently ignore no such file or directory errors. Why? Because these will inevitably be raised when
-                       # making the switch to the new firmware mod kit directory structure. We handle this elsewhere, but it's
-                       # annoying to see this spammed out to the console every time.
-                       if e.errno != 2:
-                               sys.stderr.write("WARNING: Extractor.execute failed to run '%s': %s\n" % (str(cmd), str(e)))
-                       retval = False
-               
-               if tmp is not None:
-                       tmp.close()
-
-               return retval
-       
-
diff --git a/binwalk/filter.py b/binwalk/filter.py
deleted file mode 100644 (file)
index e26288b..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-import re
-import common
-from smartsignature import SmartSignature
-
-class MagicFilter:
-       '''
-       Class to filter libmagic results based on include/exclude rules and false positive detection.
-       An instance of this class is available via the Binwalk.filter object.
-       Note that all filter strings should be in lower case.
-
-       Example code which creates include, exclude, and grep filters before running a binwalk scan:
-
-               import binwalk
-
-               bw = binwalk.Binwalk()
-
-               # Include all signatures whose descriptions contain the string 'filesystem' in the first line of the signature, even if those signatures are normally excluded.
-               # Note that if exclusive=False was specified, this would merely add these signatures to the default signatures.
-               # Since exclusive=True (the default) has been specified, ONLY those matching signatures will be loaded; all others will be ignored.
-               bw.filter.include('filesystem')
-
-               # Exclude all signatures whose descriptions contain the string 'jffs2', even if those signatures are normally included.
-               # In this case, we are now searching for all filesystem signatures, except JFFS2.
-               bw.filter.exclude('jffs2')
-
-               # Add a grep filter. Unlike the include and exclude filters, it does not affect which results are returned by Binwalk.scan(), but it does affect which results
-               # are printed by Binwalk.display.results(). This is particularly useful for cases like the bincast scan, where multiple lines of results are returned per offset,
-               # but you only want certian ones displayed. In this case, only file systems whose description contain the string '2012' will be displayed.
-               bw.filter.grep(filters=['2012'])
-
-               bw.scan('firmware.bin')
-       '''
-
-       # If the result returned by libmagic is "data" or contains the text
-       # 'invalid' or a backslash are known to be invalid/false positives.
-       DATA_RESULT = "data"
-       INVALID_RESULTS = ["invalid", "\\"]
-       INVALID_RESULT = "invalid"
-       NON_PRINTABLE_RESULT = "\\"
-
-       FILTER_INCLUDE = 0
-       FILTER_EXCLUDE = 1
-
-       def __init__(self, show_invalid_results=False):
-               '''
-               Class constructor.
-
-               @show_invalid_results - Set to True to display results marked as invalid.
-
-               Returns None.
-               '''
-               self.filters = []
-               self.grep_filters = []
-               self.show_invalid_results = show_invalid_results
-               self.exclusive_filter = False
-               self.smart = SmartSignature(self)
-
-       def include(self, match, exclusive=True):
-               '''
-               Adds a new filter which explicitly includes results that contain
-               the specified matching text.
-
-               @match     - Regex, or list of regexs, to match.
-               @exclusive - If True, then results that do not explicitly contain
-                            a FILTER_INCLUDE match will be excluded. If False,
-                            signatures that contain the FILTER_INCLUDE match will
-                            be included in the scan, but will not cause non-matching
-                            results to be excluded.
-               
-               Returns None.
-               '''
-               if not isinstance(match, type([])):
-                       matches = [match]
-               else:
-                       matches = match
-
-               for m in matches:
-                       include_filter = {}
-
-                       if m:
-                               if exclusive and not self.exclusive_filter:
-                                       self.exclusive_filter = True
-
-                               include_filter['type'] = self.FILTER_INCLUDE
-                               include_filter['filter'] = m
-                               include_filter['regex'] = re.compile(m)
-                               self.filters.append(include_filter)
-
-       def exclude(self, match):
-               '''
-               Adds a new filter which explicitly excludes results that contain
-               the specified matching text.
-
-               @match - Regex, or list of regexs, to match.
-               
-               Returns None.
-               '''
-               if not isinstance(match, type([])):
-                       matches = [match]
-               else:
-                       matches = match
-
-               for m in matches:
-                       exclude_filter = {}
-
-                       if m:
-                               exclude_filter['type'] = self.FILTER_EXCLUDE
-                               exclude_filter['filter'] = m
-                               exclude_filter['regex'] = re.compile(m)
-                               self.filters.append(exclude_filter)
-
-       def filter(self, data):
-               '''
-               Checks to see if a given string should be excluded from or included in the results.
-               Called internally by Binwalk.scan().
-
-               @data - String to check.
-
-               Returns FILTER_INCLUDE if the string should be included.
-               Returns FILTER_EXCLUDE if the string should be excluded.
-               '''
-               data = data.lower()
-
-               # Loop through the filters to see if any of them are a match. 
-               # If so, return the registered type for the matching filter (FILTER_INCLUDE | FILTER_EXCLUDE). 
-               for f in self.filters:
-                       if f['regex'].search(data):
-                               return f['type']
-
-               # If there was not explicit match and exclusive filtering is enabled, return FILTER_EXCLUDE.
-               if self.exclusive_filter:
-                       return self.FILTER_EXCLUDE
-
-               return self.FILTER_INCLUDE
-
-       def invalid(self, data):
-               '''
-               Checks if the given string contains invalid data.
-               Called internally by Binwalk.scan().
-
-               @data - String to validate.
-
-               Returns True if data is invalid, False if valid.
-               '''
-               # A result of 'data' is never ever valid.
-               if data == self.DATA_RESULT:
-                       return True
-
-               # If showing invalid results, just return False.
-               if self.show_invalid_results:
-                       return False
-
-               # Don't include quoted strings or keyword arguments in this search, as 
-               # strings from the target file may legitimately contain the INVALID_RESULT text.
-               if self.INVALID_RESULT in common.strip_quoted_strings(self.smart._strip_tags(data)):
-                       return True
-
-               # There should be no non-printable characters in any of the data
-               if self.NON_PRINTABLE_RESULT in data:
-                       return True
-
-               return False
-
-       def grep(self, data=None, filters=[]):
-               '''
-               Add or check case-insensitive grep filters against the supplied data string.
-
-               @data    - Data string to check grep filters against. Not required if filters is specified.
-               @filters - Regex, or list of regexs, to add to the grep filters list. Not required if data is specified.
-
-               Returns None if data is not specified.
-               If data is specified, returns True if the data contains a grep filter, or if no grep filters exist.
-               If data is specified, returns False if the data does not contain any grep filters.
-               '''
-               # Add any specified filters to self.grep_filters
-               if filters:
-                       if not isinstance(filters, type([])):
-                               gfilters = [filters]
-                       else:
-                               gfilters = filters
-
-                       for gfilter in gfilters:
-                               # Filters are case insensitive
-                               self.grep_filters.append(re.compile(gfilter))
-
-               # Check the data against all grep filters until one is found
-               if data is not None:
-                       # If no grep filters have been created, always return True
-                       if not self.grep_filters:
-                               return True
-
-                       # Filters are case insensitive
-                       data = data.lower()
-
-                       # If a filter exists in data, return True
-                       for gfilter in self.grep_filters:
-                               if gfilter.search(data):
-                                       return True
-
-                       # Else, return False
-                       return False
-       
-               return None
-
-       def clear(self):
-               '''
-               Clears all include, exclude and grep filters.
-               
-               Retruns None.
-               '''
-               self.filters = []
-               self.grep_filters = []
diff --git a/binwalk/hexdiff.py b/binwalk/hexdiff.py
deleted file mode 100644 (file)
index fdd574c..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import sys
-import string
-import curses
-import platform
-
-class HexDiff(object):
-
-       ALL_SAME = 0
-       ALL_DIFF = 1
-       SOME_DIFF = 2
-
-       DEFAULT_DIFF_SIZE = 0x100
-       DEFAULT_BLOCK_SIZE = 16
-
-       COLORS = {
-               'red'   : '31',
-               'green' : '32',
-               'blue'  : '34',
-       }
-
-       def __init__(self, binwalk=None):
-               self.block_hex = ""
-               self.printed_alt_text = False
-
-               if binwalk:
-                       self._pprint = binwalk.display._pprint
-                       self._show_header = binwalk.display.header
-                       self._footer = binwalk.display.footer
-                       self._display_result = binwalk.display.results
-                       self._grep = binwalk.filter.grep
-               else:
-                       self._pprint = sys.stdout.write
-                       self._show_header = self._print
-                       self._footer = self._simple_footer
-                       self._display_result = self._print
-                       self._grep = None
-
-               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):
-               return c
-
-       def _colorize(self, c, color="red", bold=True):
-               attr = []
-
-               attr.append(self.COLORS[color])
-               if bold:
-                       attr.append('1')
-
-               return "\x1b[%sm%s\x1b[0m" % (';'.join(attr), c)
-
-       def _print_block_hex(self, alt_text="*"):
-               printed = False
-
-               if self._grep is None or self._grep(self.block_hex):
-                       self._pprint(self.block_hex)
-                       self.printed_alt_text = False
-                       printed = True
-               elif not self.printed_alt_text:
-                       self._pprint("%s\n" % alt_text)
-                       self.printed_alt_text = True
-                       printed = True
-
-               self.block_hex = ""
-               return printed
-
-       def _build_block(self, c, highlight=None):
-               if highlight == self.ALL_DIFF:
-                       self.block_hex += self.colorize(c, color="red")
-               elif highlight == self.ALL_SAME:
-                       self.block_hex += self.colorize(c, color="green")
-               elif highlight == self.SOME_DIFF:
-                       self.block_hex += self.colorize(c, color="blue")
-               else:
-                       self.block_hex += c
-
-       def _simple_footer(self):
-               print ""
-
-       def _header(self, files, block):
-               header = "OFFSET    "
-               for i in range(0, len(files)):
-                       f = files[i]
-                       header += "%s" % os.path.basename(f)
-                       if i != len(files)-1:
-                               header += " " * ((block*4) + 10 - len(os.path.basename(f)))
-               self._show_header(header=header)
-
-       def display(self, files, offset=0, size=DEFAULT_DIFF_SIZE, block=DEFAULT_BLOCK_SIZE, show_first_only=False):
-               i = 0
-               data = {}
-               delim = '/'
-
-               if show_first_only:
-                       self._header([files[0]], block)
-               else:
-                       self._header(files, block)
-
-               for f in files:
-                       fp = open(f, 'rb')
-                       fp.seek(offset)
-                       data[f] = fp.read(size)
-                       fp.close()
-
-
-               while i < size:
-                       diff_same = {}
-                       alt_text = "*" + " " * 6
-
-                       self._build_block("%.08X  " % i)
-
-                       # 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):
-                               byte_list = []
-
-                               try:
-                                       c = data[files[0]][j+i]
-                               except:
-                                       c = None
-
-                               for f in files:
-                                       try:
-                                               c = data[f][j+i]
-                                       except Exception, e:
-                                               c = None
-
-                                       if c not in byte_list:
-                                               byte_list.append(c)
-
-                               if len(byte_list) == 1:
-                                       diff_same[j] = self.ALL_SAME
-                               elif len(byte_list) == len(files):
-                                       diff_same[j] = self.ALL_DIFF
-                               else:
-                                       diff_same[j] = self.SOME_DIFF
-
-                       for index in range(0, len(files)):
-                               if show_first_only and index > 0:
-                                       break
-                       
-                               f = files[index]
-
-                               alt_text += " " * (3 + (3 * block) + 3 + block + 3)
-                               alt_text += delim
-
-                               for j in range(0, block):
-                                       try:
-                                               self._build_block("%.2X " % ord(data[f][j+i]), highlight=diff_same[j])
-                                       except:
-                                               self._build_block("   ")
-
-                                       if (j+1) == block:
-                                               self._build_block(" |")
-                                               for k in range(0, block):
-                                                       try:
-                                                               if data[f][k+i] in string.printable and data[f][k+i] not in string.whitespace:
-                                                                       self._build_block(data[f][k+i], highlight=diff_same[k])
-                                                               else:
-                                                                       self._build_block('.', highlight=diff_same[k])
-                                                       except:
-                                                               self._build_block(' ')
-
-                                               if index == len(files)-1 or (show_first_only and index == 0):
-                                                       self._build_block("|\n")
-                                               else:
-                                                       self._build_block('|   %s   ' % delim)
-
-                       if self._print_block_hex(alt_text=alt_text[:-1].strip()):
-                               if delim == '\\':
-                                       delim = '/'
-                               else:
-                                       delim = '\\'
-
-                       i += block
-               
-               self._footer()
-
-if __name__ == "__main__":
-       HexDiff().display(sys.argv[1:])
-
diff --git a/binwalk/magic/binarch b/binwalk/magic/binarch
deleted file mode 100644 (file)
index 6695ef2..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# MIPS prologue
-# addiu $sp, -XX
-# 27 BD FF XX
-0      string  \377\275\47     MIPSEL instructions, function prologue{offset-adjust:-1}
-0       string  \47\275\377    MIPS instructions, function prologue
-
-# MIPS epilogue
-# jr $ra
-0      belong  0x03e00008      MIPS instructions, function epilogue
-0      lelong  0x03e00008      MIPSEL instructions, function epilogue
-
-# PowerPC prologue
-# mflr r0
-0      belong 0x7C0802A6       PowerPC big endian instructions, function prologue
-0      lelong 0x7C0802A6       PowerPC little endian instructions, funciton prologue
-
-# PowerPC epilogue
-# blr
-0      belong 0x4E800020       PowerPC big endian instructions, function epilogue
-0      lelong 0x4E800020       PowerPC little endian instructions, function epilogue
-
-# ARM prologue
-# STMFD SP!, {XX}
-0      beshort 0xE92D          ARMEB instructions, function prologue
-0      leshort 0xE92D          ARM instructions, function prologue{offset-adjust:-2}
-
-# ARM epilogue
-# LDMFD SP!, {XX}
-0      beshort 0xE8BD          ARMEB instructions, function epilogue
-0      leshort 0xE8BD          ARM instructions, function epilogue{offset-adjust:-2}
-
-# Ubicom32 prologue
-# move.4 -4($sp)++, $ra
-0      belong  0x02FF6125      Ubicom32 instructions, function prologue
-
-# Ubicom32 epilogues
-# calli $ra, 0($ra)
-# ret ($sp)4++
-0      belong  0xF0A000A0      Ubicom32 instructions, function epilogue
-0      belong  0x000022E1      Ubicom32 instructions, function epilogue
-
-# AVR8 prologue
-# push r28
-# push r29
-0      belong  0x93CF93DF      AVR8 instructions, function prologue
-0      belong  0x93DF93CF      AVR8 instructions, function prologue
-
-# AVR32 prologue
-# pushm   r7,lr
-# mov r7,sp
-0      string  \xEB\xCD\x40\x80\x1A\x97        AVR32 instructions, function prologue
-
-# SPARC eiplogue
-# ret
-# restore XX
-0      string  \x81\xC7\xE0\x08\x81\xE8        SPARC instructions, function epilogue
-
-# x86 epilogue
-# push ebp
-# move ebp, esp
-0      string  \x55\x89\xE5    Intel x86 instructions, function epilogue
-
diff --git a/binwalk/magic/bincast b/binwalk/magic/bincast
deleted file mode 100644 (file)
index 9b7811d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-0      belong x        Hex:                 0x%.8X
-#0     string x        String:              %s
-0      lequad x        Little Endian Quad:  %lld
-0      bequad x        Big Endian Quad:     %lld
-0      lelong x        Little Endian Long:  %d
-0      belong x        Big Endian Long:     %d
-0      leshort x       Little Endian Short: %d
-0      beshort x       Big Endian Short:    %d
-0      ledate x        Little Endian Date:  %s
-0      bedate x        Big Endian Date:     %s
diff --git a/binwalk/magic/binwalk b/binwalk/magic/binwalk
deleted file mode 100644 (file)
index 2e97bd9..0000000
+++ /dev/null
@@ -1,4722 +0,0 @@
-# ----------------------------Archive Formats--------------------------------------
-
-# POSIX tar archives
-0      string          ustar\000               POSIX tar archive{offset-adjust:-257}
-0      string          ustar\040\040\000       POSIX tar archive (GNU){offset-adjust:-257}
-
-# JAR archiver (.j), this is the successor to ARJ, not Java's JAR (which is essentially ZIP)
-0       string  \x1aJar\x1b JAR (ARJ Software, Inc.) archive data{offset-adjust:-14}
-0       string  JARCS JAR (ARJ Software, Inc.) archive data
-
-# ZIP compression (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
-0       string          PK\003\004      Zip
->6     leshort         &0x01           encrypted
->0     byte            x               archive data,
->4      byte            0x00            v0.0
->4      byte            0x09            at least v0.9 to extract,
->4      byte            0x0a            at least v1.0 to extract,
->4      byte            0x0b            at least v1.1 to extract,
->0x161  string          WINZIP          WinZIP self-extracting,
->4      byte            0x14
->>30    ubelong         !0x6d696d65     at least v2.0 to extract,
->18    lelong          !0
->>18   lelong          <0              invalid
->>18   lelong          x               compressed size: %d,
->>18   lelong          x               {jump-to-offset:%d}
->22    lelong          !0
->>22   lelong          <0              invalid
->>22   lelong          x               uncompressed size: %d,{extract-delay:End of Zip archive}
->30    string          x               {file-name:{raw-replace}}name: {raw-replace}
->26    leshort         x               {raw-string-length:%d}
->30    string          x               {raw-string:%s
->61    string          x               \b%s
->92    string          x               \b%s
->123   string          x               \b%s
->154   string          x               \b%s}
-
-# ZIP footer
-0      string          PK\x05\x06      End of Zip archive
-#>10   leshort         x               number of records: %d,
-#>12   leshort         x               size of central directory: %d
-#>20   leshort         x               {offset-adjust:22+%d}
->20    leshort         >0
->>20   leshort         x               \b, comment: {raw-replace}
->>20   leshort         x               {raw-string-length:%d}
->>22   string          x               {raw-string:%s}
-
-# ARJ archiver (jason@jarthur.Claremont.EDU)
-0       leshort         0xea60          ARJ archive data,
->2     leshort         x               header size: %d,
->5     byte            <1              invalid
->5     byte            >16             invalid
->5      byte            x               version %d,
->6     byte            <1              invalid
->6     byte            >16             invalid
->6     byte            x               minimum version to extract: %d,
->8     byte            <0              invalid flags,
->8      byte            &0x04           multi-volume,
->8      byte            &0x10           slash-switched,
->8      byte            &0x20           backup,
->9     byte            <0              invalid compression method,
->9     byte            >4              invalid compression method,
->9     byte            0               compression method: stored,
->9     byte            1               compression method: compressed most,
->9     byte            2               compression method: compressed,
->9     byte            3               compression method: compressed faster,
->9     byte            4               compression method: compressed fastest,
->10    byte            <0              invalid file type
->10    byte            >4              invalid file type
->10    byte            0               file type: binary,
->10    byte            1               file type: 7-bit text,
->10    byte            2               file type: comment header,
->10    byte            3               file type: directory,
->10    byte            4               file type: volume label,
->34    byte            !0
->>34   string          x               {file-name:%s}
->>34    string          x               original name: "%s",
->0xC   ledate          x               original file date: %s,
->0x10  lelong          <0              invalid
->0x10  lelong          x               compressed file size: %d,
->0x14  lelong          <0              invalid
->0x14  lelong          x               uncompressed file size: %d,
->7      byte            0               os: MS-DOS 
->7      byte            1               os: PRIMOS
->7      byte            2               os: Unix
->7      byte            3               os: Amiga
->7      byte            4               os: Macintosh
->7      byte            5               os: OS/2
->7      byte            6               os: Apple ][ GS
->7      byte            7               os: Atari ST
->7      byte            8               os: NeXT
->7      byte            9               os: VAX/VMS
->7     byte            >9              invalid os
->7     byte            <0              invalid os
-
-# RAR archiver (Greg Roelofs, newt@uchicago.edu)
-0      string          Rar!            RAR archive data
-
-# HPACK archiver (Peter Gutmann, pgut1@cs.aukuni.ac.nz)
-0      string          HPAK            HPACK archive data
-
-# JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net
-0      string          \351,\001JAM    JAM archive
-
-# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu)
-0      string          -lzs-           LHa 2.x? archive data [lzs] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh\40-         LHa 2.x? archive data [lh ] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lhd-           LHa 2.x? archive data [lhd] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh2-           LHa 2.x? archive data [lh2] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh3-           LHa 2.x? archive data [lh3] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh4-           LHa (2.x) archive data [lh4] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh5-           LHa (2.x) archive data [lh5] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh6-           LHa (2.x) archive data [lh6] [NSRL|LHA2]{offset-adjust:-2}
-0      string          -lh7-           LHa (2.x) archive data [lh7] [NSRL|LHA2]{offset-adjust:-2}
-
-
-# cpio archives
-#
-# The SVR4 "cpio(4)" hints that there are additional formats, but they
-# are defined as "short"s; I think all the new formats are
-# character-header formats and thus are strings, not numbers.
-#0       string          070707          ASCII cpio archive (pre-SVR4 or odc)
-
-0       string          070701          ASCII cpio archive (SVR4 with no CRC),
->110   byte            0               invalid
-#>110  byte            !0x2F
-#>>110 string          !TRAILER!!!     invalid
->110   string          x               file name: "%s"
->54    string          x               file size: "0x%.8s"
->54    string          x               {jump-to-offset:0x%.8s+112}
-
-0       string          070702          ASCII cpio archive (SVR4 with CRC)
->110   byte            0               invalid
-#>110  byte            !0x2F
-#>>110 string          !TRAILER!!!     invalid
->110   string          x               file name: "%s"
->54    string          x               file size: "0x%.8s"
->54    string          x               {jump-to-offset:0x%.8s+112}
-
-
-# HP Printer Job Language
-# The header found on Win95 HP plot files is the "Silliest Thing possible" 
-# (TM)
-# Every driver puts the language at some random position, with random case
-# (LANGUAGE and Language)
-# For example the LaserJet 5L driver puts the "PJL ENTER LANGUAGE" in line 10
-# From: Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
-# 
-0       string          \033%-12345X@PJL        HP Printer Job Language data
->&0     string          >\0                     "%s"
->>&0    string          >\0                     "%s"
->>>&0   string          >\0                     "%s"
->>>>&0  string          >\0                     "%s"
-
-#------------------------------------------------------------------------------
-#
-# RPM: file(1) magic for Red Hat Packages   Erik Troan (ewt@redhat.com)
-#
-0      belong          0xedabeedb      RPM
->4     byte            x               v%d
->6     beshort         0               bin
->6     beshort         1               src
->8     beshort         1               i386
->8     beshort         2               Alpha
->8     beshort         3               Sparc
->8     beshort         4               MIPS
->8     beshort         5               PowerPC
->8     beshort         6               68000
->8     beshort         7               SGI
->8     beshort         8               RS6000
->8     beshort         9               IA64
->8     beshort         10              Sparc64
->8     beshort         11              MIPSel
->8     beshort         12              ARM
->10    string          x               "%s"
-
-# IBM AIX Backup File Format header and entry signatures
-0      lelong  0xea6b0009      BFF volume header,
->4     leshort x               checksum: 0x%.4X,
->6     leshort <0              invalid
->6     leshort 0               invalid
->6     leshort x               volume number: %d,
->8     ledate  x               current date: %s,
->12    ledate  x               starting date: %s,
->20    string  x               disk name: "%s",
->36    string  x               file system name: "%s",
->52    string  x               user name: "%s"
-
-0      leshort 0xea6b          BFF volume entry,{offset-adjust:-2}
->22    lelong  <0              invalid
->22    lelong  0               directory,
->22    lelong  >0
->>22   lelong  x               file size: %d,
->>54   lelong  <0              invalid
->>54   lelong  0               invalid
->>54   lelong  x               compressed size: %d,
->58    lelong  !0              invalid
->62    byte    0               invalid
->62    byte    !0x2e
->>62   byte    !0x2f           invalid
->62    string  x               file name: "%s
->92    string  x               \b%s"
-
-0      leshort 0xea6c          BFF volume entry, compressed,{offset-adjust:-2}
->22    lelong  <0              invalid
->22    lelong  0               directory,
->22    lelong  >0
->>22   lelong  x               file size: %d,
->>54   lelong  <0              invalid
->>54   lelong  0               invalid
->>54   lelong  x               compressed size: %d,
->58    lelong  !0              invalid
->62    byte    0               invalid
->62    byte    !0x2e
->>62   byte    !0x2f           invalid
->62    string  x               file name: "%s
->92    string  x               \b%s"
-
-0      leshort 0xea6d          BFF volume entry, AIXv3,{offset-adjust:-2}
->22    lelong  <0              invalid
->22    lelong  0               directory,
->22    lelong  >0
->>22   lelong  x               file size: %d,
->>54   lelong  <0              invalid
->>54   lelong  0               invalid
->>54   lelong  x               compressed size: %d,
->58    lelong  !0              invalid
->62    byte    0               invalid
->62    byte    !0x2e
->>62   byte    !0x2f           invalid
->62    string  x               file name: "%s
->92    string  x               \b%s"
-
-
-#---------------------------Bootloaders--------------------------------
-
-# CFE bootloader
-0      string  CFE1CFE1        CFE boot loader
->40    string  CFE1CFE1        invalid
-
-# U-Boot boot loader
-0      string  U-Boot          U-Boot boot loader reference{one-of-many}
-0      string  U-BOOT          U-Boot boot loader reference{one-of-many}
-0      string  u-boot          U-Boot boot loader reference{one-of-many}
-
-#------------------Compression Formats-----------------------------
-
-# AFX compressed files (Wolfram Kleff)
-0      string          -afx-           AFX compressed file data{offset-adjust:-2}
-
-# bzip2
-0      string BZh91AY&SY       bzip2 compressed data, block size = 900k
-0      string BZh81AY&SY       bzip2 compressed data, block size = 800k
-0      string BZh71AY&SY       bzip2 compressed data, block size = 700k
-0      string BZh61AY&SY       bzip2 compressed data, block size = 600k
-0      string BZh51AY&SY       bzip2 compressed data, block size = 500k
-0      string BZh41AY&SY       bzip2 compressed data, block size = 400k
-0      string BZh31AY&SY       bzip2 compressed data, block size = 300k
-0      string BZh21AY&SY       bzip2 compressed data, block size = 200k
-0      string BZh11AY&SY       bzip2 compressed data, block size = 100k
-
-# lzop from <markus.oberhumer@jk.uni-linz.ac.at>
-0      string          \x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a    lzop compressed data
->9     beshort         <0x0940
->>9    byte&0xf0       =0x00           - version 0.
->>9    beshort&0x0fff  x               \b%03x,
->>13   byte            1               LZO1X-1,
->>13   byte            2               LZO1X-1(15),
->>13   byte            3               LZO1X-999,
-## >>22        bedate          >0              last modified: %s,
->>14   byte            =0x00           os: MS-DOS
->>14   byte            =0x01           os: Amiga
->>14   byte            =0x02           os: VMS
->>14   byte            =0x03           os: Unix
->>14   byte            =0x05           os: Atari
->>14   byte            =0x06           os: OS/2
->>14   byte            =0x07           os: MacOS
->>14   byte            =0x0A           os: Tops/20
->>14   byte            =0x0B           os: WinNT
->>14   byte            =0x0E           os: Win32
->9     beshort         >0x0939
->>9    byte&0xf0       =0x00           - version 0.
->>9    byte&0xf0       =0x10           - version 1.
->>9    byte&0xf0       =0x20           - version 2.
->>9    beshort&0x0fff  x               \b%03x,
->>15   byte            1               LZO1X-1,
->>15   byte            2               LZO1X-1(15),
->>15   byte            3               LZO1X-999,
-## >>25        bedate          >0              last modified: %s,
->>17   byte            =0x00           os: MS-DOS
->>17   byte            =0x01           os: Amiga
->>17   byte            =0x02           os: VMS
->>17   byte            =0x03           os: Unix
->>17   byte            =0x05           os: Atari
->>17   byte            =0x06           os: OS/2
->>17   byte            =0x07           os: MacOS
->>17   byte            =0x0A           os: Tops/20
->>17   byte            =0x0B           os: WinNT
->>17   byte            =0x0E           os: Win32
-
-# lzip  
-0       string          LZIP            lzip compressed data
->4      byte            x               \b, version: %d
-
-# LZO
-0      string          \211LZO\000\015\012\032\012     LZO compressed data
-
-# 7-zip archiver, from Thomas Klausner (wiz@danbala.tuwien.ac.at)
-# http://www.7-zip.org or DOC/7zFormat.txt 
-#
-0       string          7z\274\257\047\034      7-zip archive data,
->6     byte            <0                      invalid
->6     byte            0                       invalid
->6     byte            >20                     invalid
->6      byte            x                       version %d
->7      byte            x                       \b.%d
-
-# standard unix compress
-#0       beshort               0x1f9d          compress'd data
-#>2      byte&0x80       >0              block compressed
-#>2    byte&0x1f       !16             invalid
-#>2      byte&0x1f       x               %d bits
-
-# http://tukaani.org/xz/xz-file-format.txt
-0      string          \xFD\x37\x7a\x58\x5a\x00        xz compressed data
-
-# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
-#   Edited by Chris Chittleborough <cchittleborough@yahoo.com.au>, March 2002
-#       * Original filename is only at offset 10 if "extra field" absent
-#       * Produce shorter output - notably, only report compression methods
-#         other than 8 ("deflate", the only method defined in RFC 1952).
-#0       string          \037\213\x08    gzip compressed data
-0      string          \x1f\x8b\x08    gzip compressed data
->3      byte            &0x01           \b, ASCII
->3      byte            &0x02           \b, has CRC
->3      byte            &0x04           \b, extra field
->3      byte&0xC        =0x08
->>10   string          x               \b{file-name:%s}
->>10    string          x               \b, was "%s"
->3      byte            &0x10           \b, has comment
->9      byte            =0x00           \b, from FAT filesystem (MS-DOS, OS/2, NT)
->9      byte            =0x01           \b, from Amiga
->9      byte            =0x02           \b, from VMS
->9      byte            =0x03           \b, from Unix
->9      byte            =0x04           \b, from VM/CMS
->9      byte            =0x05           \b, from Atari
->9      byte            =0x06           \b, from HPFS filesystem (OS/2, NT)
->9      byte            =0x07           \b, from MacOS
->9      byte            =0x08           \b, from Z-System
->9      byte            =0x09           \b, from CP/M
->9      byte            =0x0A           \b, from TOPS/20
->9      byte            =0x0B           \b, from NTFS filesystem (NT)
->9      byte            =0x0C           \b, from QDOS
->9      byte            =0x0D           \b, from Acorn RISCOS
-#>9    byte            =0xFF           \b, from ZyNOS
-#>9    byte            >0x0D           \b, invalid
-#>>9   byte            x               source: 0x%.2X
-#>9    byte            <0              \b, invalid
-#>>9   byte            x               source: 0x%.2X
->3      byte            &0x20           \b, encrypted (invalid)
-# Dates before 1992 are invalid, unless of course you're DD-WRT in which
-# case you don't know how to set a date in your gzip files. Brilliant.
->4     lelong          =0              \b, NULL date:
->4     lelong          <0              \b, invalid date:
->4     lelong          >0              
->>4    lelong          <694224000      \b, invalid date:
->>4    lelong          =694224000      \b, invalid date:
->>4    lelong          >694224000      \b, last modified:
->4      ledate          x               %s
->4     lelong          x               \b{epoch:%d}
->8      byte            2               \b, max compression
->8      byte            4               \b, max speed
-
-# Zlib signatures
-# Useless until they can be further improved.
-#0     beshort         0x789C          zlib compressed data
-#0     beshort         0x78DA          zlib compressed data
-#0     beshort         0x7801          zlib compressed data
-
-# Supplementary magic data for the file(1) command to support
-# rzip(1).  The format is described in magic(5).
-#
-# Copyright (C) 2003 by Andrew Tridgell.  You may do whatever you want with
-# this file.
-#
-0       string          RZIP            rzip compressed data
->4      byte            x               - version %d
->5      byte            x               \b.%d
->6      belong          x               (%d bytes)
-
-# New LZMA format signature
-0      string          \xFFLZMA\x00    LZMA compressed data (new),
->6     byte&0x10       0               single-block stream
->6     byte&0x10       0x10            multi-block stream
-
-# See lzma file for LZMA signatures
-# Type: OpenSSL certificates/key files
-# From: Nicolas Collignon <tsointsoin@gmail.com>
-
-0       string  -----BEGIN\x20CERTIFICATE-----      PEM certificate
-0       string  -----BEGIN\x20CERTIFICATE\x20REQ    PEM certificate request
-0       string  -----BEGIN\x20RSA\x20PRIVATE        PEM RSA private key
-0       string  -----BEGIN\x20DSA\x20PRIVATE        PEM DSA private key
-
-# Type: OpenSSH key files
-# From: Nicolas Collignon <tsointsoin@gmail.com>
-
-0       string  SSH\x20PRIVATE\x20KEY  OpenSSH RSA1 private key,
->28     string  >\0                    version "%s"
-
-0       string  ssh-dss\x20               OpenSSH DSA public key
-0       string  ssh-rsa\x20               OpenSSH RSA public key
-
-# Type: Certificates/key files in DER format
-# From: Gert Hulselmans <hulselmansgert@gmail.com>
-0      string  \x30\x82                Private key in DER format (PKCS#8),
->4     string  !\x02\x01\x00           invalid,
->>2    beshort x                       header length: 4, sequence length: %d
-
-0      string  \x30\x82                Certificate in DER format (x509 v3),
->4     string  !\x30\x82               invalid,
->>2    beshort x                       header length: 4, sequence length: %d
-
-# GnuPG
-# The format is very similar to pgp
-0      string          \001gpg                 GPG key trust database
->4     byte            x                       version %d
-
-# Not a very useful signature
-#0       beshort         0x9901                  GPG key public ring
-
-# This magic is not particularly good, as the keyrings don't have true
-# magic. Nevertheless, it covers many keyrings.
-
-#------------------------------------------------------------------------------
-# Mavroyanopoulos Nikos <nmav@hellug.gr>
-# mcrypt:   file(1) magic for mcrypt 2.2.x;
-0      string          \0m\3           mcrypt 2.5 encrypted data,
->4     byte            0               invalid
->4     string          >\0             algorithm: "%s",
->>&1   leshort         <1              invalid
->>&1   leshort         >0              keysize: %d bytes,
->>>&0  byte            0               invalid
->>>&0  string          >\0             mode: "%s",
-
-0      string          \0m\2           mcrypt 2.2 encrypted data,
->3     byte            0               algorithm: blowfish-448,
->3     byte            1               algorithm: DES,
->3     byte            2               algorithm: 3DES,
->3     byte            3               algorithm: 3-WAY,
->3     byte            4               algorithm: GOST,
->3     byte            6               algorithm: SAFER-SK64,
->3     byte            7               algorithm: SAFER-SK128,
->3     byte            8               algorithm: CAST-128,
->3     byte            9               algorithm: xTEA,
->3     byte            10              algorithm: TWOFISH-128,
->3     byte            11              algorithm: RC2,
->3     byte            12              algorithm: TWOFISH-192,
->3     byte            13              algorithm: TWOFISH-256,
->3     byte            14              algorithm: blowfish-128,
->3     byte            15              algorithm: blowfish-192,
->3     byte            16              algorithm: blowfish-256,
->3     byte            100             algorithm: RC6,
->3     byte            101             algorithm: IDEA,
->3     byte            <0              invalid algorithm
->3     byte            >101            invalid algorithm,
->3     byte            >16
->>3    byte            <100            invalid algorithm,
->4     byte            0               mode: CBC,
->4     byte            1               mode: ECB,
->4     byte            2               mode: CFB,
->4     byte            3               mode: OFB,
->4     byte            4               mode: nOFB,
->4     byte            <0              invalid mode,
->4     byte            >4              invalid mode,
->5     byte            0               keymode: 8bit
->5     byte            1               keymode: 4bit
->5     byte            2               keymode: SHA-1 hash
->5     byte            3               keymode: MD5 hash
->5     byte            <0              invalid keymode
->5     byte            >3              invalid keymode
-
-#------------------------------------------------------------------------------
-# pgp:  file(1) magic for Pretty Good Privacy
-#
-#0       beshort         0x9900                  PGP key public ring
-#0       beshort         0x9501                  PGP key security ring
-#0       beshort         0x9500                  PGP key security ring
-#0     beshort         0xa600                  PGP encrypted data
-0       string          -----BEGIN\040PGP       PGP armored data,
->15     string          PUBLIC\040KEY\040BLOCK- public key block
->15     string          MESSAGE-                message
->15     string          SIGNED\040MESSAGE-      signed message
->15     string          PGP\040SIGNATURE-       signature
-
-0      string          Salted__                OpenSSL encryption, salted,
->8     belong          x                       salt: 0x%X
->12    belong          x                       \b%X
-
-#------------------Standard file formats------------------------------------
-
-#------------------------------------------------------------------------------
-# elf:  file(1) magic for ELF executables
-#
-# We have to check the byte order flag to see what byte order all the
-# other stuff in the header is in.
-#
-# What're the correct byte orders for the nCUBE and the Fujitsu VPP500?
-#
-# updated by Daniel Quinlan (quinlan@yggdrasil.com)
-0      string          \177ELF         ELF
->4     byte            0               invalid class
->4     byte            1               32-bit
-# only for MIPS - in the future, the ABI field of e_flags should be used.
->>18   leshort         8
->>>36  lelong          &0x20           N32
->>18   leshort         10
->>>36  lelong          &0x20           N32
->>18   beshort         8
->>>36  belong          &0x20           N32
->>18   beshort         10
->>>36  belong          &0x20           N32
->4     byte            2               64-bit
->5     byte            0               invalid byte order
->5     byte            1               LSB
-# The official e_machine number for MIPS is now #8, regardless of endianness.
-# The second number (#10) will be deprecated later. For now, we still
-# say something if #10 is encountered, but only gory details for #8.
->>18    leshort                8
-# only for 32-bit
->>>4   byte            1
->>>>36  lelong&0xf0000000      0x00000000      MIPS-I
->>>>36  lelong&0xf0000000      0x10000000      MIPS-II
->>>>36  lelong&0xf0000000      0x20000000      MIPS-III
->>>>36  lelong&0xf0000000      0x30000000      MIPS-IV
->>>>36  lelong&0xf0000000      0x40000000      MIPS-V
->>>>36  lelong&0xf0000000      0x60000000      MIPS32
->>>>36  lelong&0xf0000000      0x70000000      MIPS64
->>>>36  lelong&0xf0000000      0x80000000      MIPS32 rel2
->>>>36  lelong&0xf0000000      0x90000000      MIPS64 rel2
-# only for 64-bit
->>>4   byte            2
->>>>48  lelong&0xf0000000      0x00000000      MIPS-I
->>>>48  lelong&0xf0000000      0x10000000      MIPS-II
->>>>48  lelong&0xf0000000      0x20000000      MIPS-III
->>>>48  lelong&0xf0000000      0x30000000      MIPS-IV
->>>>48  lelong&0xf0000000      0x40000000      MIPS-V
->>>>48  lelong&0xf0000000      0x60000000      MIPS32
->>>>48  lelong&0xf0000000      0x70000000      MIPS64 
->>>>48  lelong&0xf0000000      0x80000000      MIPS32 rel2
->>>>48  lelong&0xf0000000      0x90000000      MIPS64 rel2
->>16   leshort         0               no file type,
->>16   leshort         1               relocatable,
->>16   leshort         2               executable,
->>16   leshort         3               shared object,
-# Core handling from Peter Tobias <tobias@server.et-inf.fho-emden.de>
-# corrections by Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de>
->>16   leshort         4               core file
-# Core file detection is not reliable.
-#>>>(0x38+0xcc) string >\0             of '%s'
-#>>>(0x38+0x10) lelong >0              (signal %d),
->>16   leshort         &0xff00         processor-specific,
->>18   leshort         0               no machine,
->>18   leshort         1               AT&T WE32100 - invalid byte order,
->>18   leshort         2               SPARC - invalid byte order,
->>18   leshort         3               Intel 80386,
->>18   leshort         4               Motorola
->>>36  lelong          &0x01000000     68000 - invalid byte order,
->>>36  lelong          &0x00810000     CPU32 - invalid byte order,
->>>36  lelong          0               68020 - invalid byte order,
->>18   leshort         5               Motorola 88000 - invalid byte order,
->>18   leshort         6               Intel 80486,
->>18   leshort         7               Intel 80860,
->>18   leshort         8               MIPS,
->>18   leshort         9               Amdahl - invalid byte order,
->>18   leshort         10              MIPS (deprecated),
->>18   leshort         11              RS6000 - invalid byte order,
->>18   leshort         15              PA-RISC - invalid byte order,
->>>50  leshort         0x0214          2.0
->>>48  leshort         &0x0008         (LP64),
->>18   leshort         16              nCUBE,
->>18   leshort         17              Fujitsu VPP500,
->>18   leshort         18              SPARC32PLUS,
->>18   leshort         20              PowerPC,
->>18   leshort         22              IBM S/390,
->>18   leshort         36              NEC V800,
->>18   leshort         37              Fujitsu FR20,
->>18   leshort         38              TRW RH-32,
->>18   leshort         39              Motorola RCE,
->>18   leshort         40              ARM,
->>18   leshort         41              Alpha,
->>18   leshort         0xa390          IBM S/390 (obsolete),
->>18   leshort         42              Hitachi SH,
->>18   leshort         43              SPARC V9 - invalid byte order,
->>18   leshort         44              Siemens Tricore Embedded Processor,
->>18   leshort         45              Argonaut RISC Core, Argonaut Technologies Inc.,
->>18   leshort         46              Hitachi H8/300,
->>18   leshort         47              Hitachi H8/300H,
->>18   leshort         48              Hitachi H8S,
->>18   leshort         49              Hitachi H8/500,
->>18   leshort         50              IA-64 (Intel 64 bit architecture)
->>18   leshort         51              Stanford MIPS-X,
->>18   leshort         52              Motorola Coldfire,
->>18   leshort         53              Motorola M68HC12,
->>18   leshort         62              AMD x86-64,
->>18   leshort         75              Digital VAX,
->>18   leshort         97              NatSemi 32k,
->>18   leshort         0x9026          Alpha (unofficial),
->>20   lelong          0               invalid version
->>20   lelong          1               version 1
->>36   lelong          1               MathCoPro/FPU/MAU Required
->5     byte            2               MSB
-# only for MIPS - see comment in little-endian section above.
->>18    beshort                8
-# only for 32-bit
->>>4   byte            1
->>>>36  belong&0xf0000000      0x00000000      MIPS-I
->>>>36  belong&0xf0000000      0x10000000      MIPS-II
->>>>36  belong&0xf0000000      0x20000000      MIPS-III
->>>>36  belong&0xf0000000      0x30000000      MIPS-IV
->>>>36  belong&0xf0000000      0x40000000      MIPS-V
->>>>36  belong&0xf0000000      0x60000000      MIPS32
->>>>36  belong&0xf0000000      0x70000000      MIPS64
->>>>36  belong&0xf0000000      0x80000000      MIPS32 rel2
->>>>36  belong&0xf0000000      0x90000000      MIPS64 rel2
-# only for 64-bit
->>>4   byte            2
->>>>48 belong&0xf0000000       0x00000000      MIPS-I
->>>>48 belong&0xf0000000       0x10000000      MIPS-II
->>>>48 belong&0xf0000000       0x20000000      MIPS-III
->>>>48 belong&0xf0000000       0x30000000      MIPS-IV
->>>>48 belong&0xf0000000       0x40000000      MIPS-V
->>>>48 belong&0xf0000000       0x60000000      MIPS32
->>>>48 belong&0xf0000000       0x70000000      MIPS64 
->>>>48 belong&0xf0000000       0x80000000      MIPS32 rel2
->>>>48 belong&0xf0000000       0x90000000      MIPS64 rel2
->>16   beshort         0               no file type,
->>16   beshort         1               relocatable,
->>16   beshort         2               executable,
->>16   beshort         3               shared object,
->>16   beshort         4               core file,
-#>>>(0x38+0xcc) string >\0             of '%s'
-#>>>(0x38+0x10) belong >0              (signal %d),
->>16   beshort         &0xff00         processor-specific,
->>18   beshort         0               no machine,
->>18   beshort         1               AT&T WE32100,
->>18   beshort         2               SPARC,
->>18   beshort         3               Intel 80386 - invalid byte order,
->>18   beshort         4               Motorola
->>>36  belong          &0x01000000     68000,
->>>36  belong          &0x00810000     CPU32,
->>>36  belong          0               68020,
->>18   beshort         5               Motorola 88000,
->>18   beshort         6               Intel 80486 - invalid byte order,
->>18   beshort         7               Intel 80860,
->>18   beshort         8               MIPS,
->>18   beshort         9               Amdahl,
->>18   beshort         10              MIPS (deprecated),
->>18   beshort         11              RS6000,
->>18   beshort         15              PA-RISC
->>>50  beshort         0x0214          2.0
->>>48  beshort         &0x0008         (LP64)
->>18   beshort         16              nCUBE,
->>18   beshort         17              Fujitsu VPP500,
->>18   beshort         18              SPARC32PLUS,
->>>36  belong&0xffff00 &0x000100       V8+ Required,
->>>36  belong&0xffff00 &0x000200       Sun UltraSPARC1 Extensions Required,
->>>36  belong&0xffff00 &0x000400       HaL R1 Extensions Required,
->>>36  belong&0xffff00 &0x000800       Sun UltraSPARC3 Extensions Required,
->>18   beshort         20              PowerPC or cisco 4500,
->>18   beshort         21              cisco 7500,
->>18   beshort         22              IBM S/390,
->>18   beshort         24              cisco SVIP,
->>18   beshort         25              cisco 7200,
->>18   beshort         36              NEC V800 or cisco 12000,
->>18   beshort         37              Fujitsu FR20,
->>18   beshort         38              TRW RH-32,
->>18   beshort         39              Motorola RCE,
->>18   beshort         40              ARM,
->>18   beshort         41              Alpha,
->>18   beshort         42              Hitachi SH,
->>18   beshort         43              SPARC V9,
->>18   beshort         44              Siemens Tricore Embedded Processor,
->>18   beshort         45              Argonaut RISC Core, Argonaut Technologies Inc.,
->>18   beshort         46              Hitachi H8/300,
->>18   beshort         47              Hitachi H8/300H,
->>18   beshort         48              Hitachi H8S,
->>18   beshort         49              Hitachi H8/500,
->>18   beshort         50              Intel Merced Processor,
->>18   beshort         51              Stanford MIPS-X,
->>18   beshort         52              Motorola Coldfire,
->>18   beshort         53              Motorola M68HC12,
->>18   beshort         73              Cray NV1,
->>18   beshort         75              Digital VAX,
->>18   beshort         97              NatSemi 32k,
->>18   beshort         0x9026          Alpha (unofficial),
->>18   beshort         0xa390          IBM S/390 (obsolete),
->>18    beshort         0xde3d          Ubicom32,
->>20   belong          0               invalid version
->>20   belong          1               version 1
->>36   belong          1               MathCoPro/FPU/MAU Required
-# Up to now only 0, 1 and 2 are defined; I've seen a file with 0x83, it seemed
-# like proper ELF, but extracting the string had bad results.
->4      byte            <0x80
->>8    string          >\0             ("%s")
->8     string          \0
->>7    byte            0               (SYSV)
->>7    byte            1               (HP-UX)
->>7    byte            2               (NetBSD)
->>7    byte            3               (GNU/Linux)
->>7    byte            4               (GNU/Hurd)
->>7    byte            5               (86Open)
->>7    byte            6               (Solaris)
->>7    byte            7               (Monterey)
->>7    byte            8               (IRIX)
->>7    byte            9               (FreeBSD)
->>7    byte            10              (Tru64)
->>7    byte            11              (Novell Modesto)
->>7    byte            12              (OpenBSD)
->>7    byte            97              (ARM)
->>7    byte            255             (embedded)
-
-# XXX - according to Microsoft's spec, at an offset of 0x3c in a
-# PE-format executable is the offset in the file of the PE header;
-# unfortunately, that's a little-endian offset, and there's no way
-# to specify an indirect offset with a specified byte order.
-# So, for now, we assume the standard MS-DOS stub, which puts the
-# PE header at 0x80 = 128.
-#
-# Required OS version and subsystem version were 4.0 on some NT 3.51
-# executables built with Visual C++ 4.0, so it's not clear that
-# they're interesting.  The user version was 0.0, but there's
-# probably some linker directive to set it.  The linker version was
-# 3.0, except for one ".exe" which had it as 4.20 (same damn linker!).
-#
-# many of the compressed formats were extraced from IDARC 1.23 source code
-#
-
-# Not a very useful signature...
-#0       string  MZ    Microsoft
-#>0x18  leshort <0x40 MS-DOS executable
-
-0      string          MZ\0\0\0\0\0\0\0\0\0\0
->12    string          PE\0\0  Microsoft PE
->0x18   leshort        <0x40   MS-DOS executable
->>&18   leshort&0x2000  >0      (DLL)
->>&88   leshort         0       (unknown subsystem)
->>&88   leshort         1       (native)
->>&88   leshort         2       (GUI)
->>&88   leshort         3       (console)
->>&88   leshort         7       (POSIX)
->>&0    leshort         0x0     unknown processor
->>&0    leshort         0x14c   Intel 80386
->>&0    leshort         0x166   MIPS R4000
->>&0    leshort         0x184   Alpha
->>&0    leshort         0x268   Motorola 68000
->>&0    leshort         0x1f0   PowerPC
->>&0    leshort         0x290   PA-RISC
->>&18   leshort&0x0100  >0      32-bit
->>&18   leshort&0x1000  >0      system file
->>&228  lelong          >0      \b, Mono/.Net assembly
->>&0xf4 search/0x140 \x0\x40\x1\x0
->>>(&0.l+(4)) string MSCF \b, WinHKI CAB self-extracting archive
->30             string  Copyright\x201989-1990\x20PKWARE\x20Inc.      Self-extracting PKZIP archive
-# Is next line correct? One might expect "Corp." not "Copr." If it is right, add a note to that effect.
->30             string  PKLITE\x20Copr.   Self-extracting PKZIP archive
-
->0x18  leshort >0x3f
->>(0x3c.l) string PE\0\0 PE
->>>(0x3c.l+25) byte             1 \b32 executable
->>>(0x3c.l+25) byte             2 \b32+ executable
-# hooray, there's a DOS extender using the PE format, with a valid PE
-# executable inside (which just prints a message and exits if run in win)
->>>(0x3c.l+92)  leshort         <10
->>>>(8.s*16) string 32STUB for MS-DOS, 32rtm DOS extender
->>>>(8.s*16) string !32STUB for MS Windows
->>>>>(0x3c.l+22)        leshort&0x2000  >0      (DLL)
->>>>>(0x3c.l+92)        leshort         0       (unknown subsystem)
->>>>>(0x3c.l+92)        leshort         1       (native)
->>>>>(0x3c.l+92)        leshort         2       (GUI)
->>>>>(0x3c.l+92)        leshort         3       (console)
->>>>>(0x3c.l+92)        leshort         7       (POSIX)
->>>(0x3c.l+92)  leshort         10      (EFI application)
->>>(0x3c.l+92)  leshort         11      (EFI boot service driver)
->>>(0x3c.l+92)  leshort         12      (EFI runtime driver)
->>>(0x3c.l+92)  leshort         13      (XBOX)
->>>(0x3c.l+4)   leshort         0x0     unknown processor
->>>(0x3c.l+4)   leshort         0x14c   Intel 80386
->>>(0x3c.l+4)   leshort         0x166   MIPS R4000
->>>(0x3c.l+4)   leshort         0x184   Alpha
->>>(0x3c.l+4)   leshort         0x268   Motorola 68000
->>>(0x3c.l+4)   leshort         0x1f0   PowerPC
->>>(0x3c.l+4)   leshort         0x290   PA-RISC
->>>(0x3c.l+4)   leshort         0x200   Intel Itanium
->>>(0x3c.l+22)  leshort&0x0100  >0      32-bit
->>>(0x3c.l+22)  leshort&0x1000  >0      system file
->>>(0x3c.l+232) lelong  >0      Mono/.Net assembly
->>>>(0x3c.l+0xf8)       string          UPX0 \b, UPX compressed
->>>>(0x3c.l+0xf8)       search/0x140    PEC2 \b, PECompact2 compressed
->>>>(0x3c.l+0xf8)       search/0x140    UPX2
->>>>>(&0x10.l+(-4))     string          PK\3\4 \b, ZIP self-extracting archive (Info-Zip)
->>>>(0x3c.l+0xf8)       search/0x140    .idata
->>>>>(&0xe.l+(-4))      string          PK\3\4 \b, ZIP self-extracting archive (Info-Zip)
->>>>>(&0xe.l+(-4))      string          ZZ0 \b, ZZip self-extracting archive
->>>>>(&0xe.l+(-4))      string          ZZ1 \b, ZZip self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .rsrc
->>>>>(&0x0f.l+(-4))     string          a\\\4\5 \b, WinHKI self-extracting archive
->>>>>(&0x0f.l+(-4))     string          Rar! \b, RAR self-extracting archive
->>>>>(&0x0f.l+(-4))     search/0x3000   MSCF \b, InstallShield self-extracting archive
->>>>>(&0x0f.l+(-4))     search/32       Nullsoft \b, Nullsoft Installer self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .data
->>>>>(&0x0f.l)          string          WEXTRACT \b, MS CAB-Installer self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .petite\0 \b, Petite compressed
->>>>>(0x3c.l+0xf7)      byte            x
->>>>>>(&0x104.l+(-4))   string          =!sfx! \b, ACE self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .WISE \b, WISE installer self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .dz\0\0\0 \b, Dzip self-extracting archive
->>>>(0x3c.l+0xf8)       search/0x140    .reloc
->>>>>(&0xe.l+(-4))      search/0x180    PK\3\4 \b, ZIP self-extracting archive (WinZip)
-
->>>>&(0x3c.l+0xf8)      search/0x100    _winzip_ \b, ZIP self-extracting archive (WinZip)
->>>>&(0x3c.l+0xf8)      search/0x100    SharedD \b, Microsoft Installer self-extracting archive
->>>>0x30                string          Inno \b, InnoSetup self-extracting archive
-
->>(0x3c.l) string !PE\0\0 MS-DOS executable
-
->>(0x3c.l)              string          NE \b, NE
->>>(0x3c.l+0x36)        byte            0 (unknown OS)
->>>(0x3c.l+0x36)        byte            1 for OS/2 1.x
->>>(0x3c.l+0x36)        byte            2 for MS Windows 3.x
->>>(0x3c.l+0x36)        byte            3 for MS-DOS
->>>(0x3c.l+0x36)        byte            >3 (unknown OS)
->>>(0x3c.l+0x36)        byte            0x81 for MS-DOS, Phar Lap DOS extender
->>>(0x3c.l+0x0c)        leshort&0x8003  0x8002 (DLL)
->>>(0x3c.l+0x0c)        leshort&0x8003  0x8001 (driver)
->>>&(&0x24.s-1)         string          ARJSFX \b, ARJ self-extracting archive
->>>(0x3c.l+0x70)        search/0x80     WinZip(R)\x20Self-Extractor \b, ZIP self-extracting archive (WinZip)
-
->>(0x3c.l)              string          LX\0\0 \b, LX
->>>(0x3c.l+0x0a)        leshort         <1 (unknown OS)
->>>(0x3c.l+0x0a)        leshort         1 for OS/2
->>>(0x3c.l+0x0a)        leshort         2 for MS Windows
->>>(0x3c.l+0x0a)        leshort         3 for DOS
->>>(0x3c.l+0x0a)        leshort         >3 (unknown OS)
->>>(0x3c.l+0x10)        lelong&0x28000  =0x8000 (DLL)
->>>(0x3c.l+0x10)        lelong&0x20000  >0 (device driver)
->>>(0x3c.l+0x10)        lelong&0x300    0x300 (GUI)
->>>(0x3c.l+0x10)        lelong&0x28300  <0x300 (console)
->>>(0x3c.l+0x08)        leshort         1 i80286
->>>(0x3c.l+0x08)        leshort         2 i80386
->>>(0x3c.l+0x08)        leshort         3 i80486
->>>(8.s*16)             string          emx \b, emx
->>>>&1                  string          x "%s"
->>>&(&0x54.l-3)         string          arjsfx \b, ARJ self-extracting archive
-
-
-
-#------------------------------------------------------------------------------
-# bFLT: file(1) magic for BFLT uclinux binary files
-#
-# From Philippe De Muyter <phdm@macqel.be>
-# 
-# Additional fields added by Craig Heffner
-#
-0       string          bFLT            BFLT executable
->4     belong          <1              invalid
->4     belong          >4              invalid
->4      belong          x               version %ld, 
->4      belong          4
->8     belong          x               code offset: 0x%.8X, 
->12    belong          x               data segment starts at: 0x%.8X, 
->16    belong          x               bss segment starts at: 0x%.8X, 
->20    belong          x               bss segment ends at: 0x%.8X, 
->24    belong          x               stack size: %d bytes, 
->28    belong          x               relocation records start at: 0x%.8X, 
->32    belong          x               number of reolcation records: %d, 
->>36    belong&0x1      0x1             ram
->>36    belong&0x2      0x2             gotpic
->>36    belong&0x4      0x4             gzip
->>36    belong&0x8      0x8             gzdata
-
-
-# Windows CE package files
-0       string          MSCE\0\0\0\0    Microsoft WinCE installer
->20     lelong          0               \b, architecture-independent
->20     lelong          103             \b, Hitachi SH3
->20     lelong          104             \b, Hitachi SH4
->20     lelong          0xA11           \b, StrongARM
->20     lelong          4000            \b, MIPS R4000
->20     lelong          10003           \b, Hitachi SH3
->20     lelong          10004           \b, Hitachi SH3E
->20     lelong          10005           \b, Hitachi SH4
->20     lelong          70001           \b, ARM 7TDMI
->52     leshort         1               \b, 1 file
->52     leshort         >1              \b, %u files
->56     leshort         1               \b, 1 registry entry
->56     leshort         >1              \b, %u registry entries
-
-#------------------------------------------------------------------------------
-# Microsoft Xbox executables .xbe (Esa Hyytiä <ehyytia@cc.hut.fi>)
-0       string          XBEH            XBE, Microsoft Xbox executable
-# probabilistic checks whether signed or not
->0x0004 ulelong =0x0
->>&2    ulelong =0x0
->>>&2   ulelong =0x0  \b, not signed
->0x0004 ulelong >0
->>&2    ulelong >0
->>>&2   ulelong >0    \b, signed
-# expect base address of 0x10000
->0x0104               ulelong =0x10000
->>(0x0118-0x0FF60)    ulelong&0x80000007  0x80000007 \b, all regions
->>(0x0118-0x0FF60)    ulelong&0x80000007  !0x80000007
->>>(0x0118-0x0FF60)   ulelong >0           (regions:
->>>>(0x0118-0x0FF60)  ulelong &0x00000001  NA
->>>>(0x0118-0x0FF60)  ulelong &0x00000002  Japan
->>>>(0x0118-0x0FF60)  ulelong &0x00000004  Rest_of_World
->>>>(0x0118-0x0FF60)  ulelong &0x80000000  Manufacturer
->>>(0x0118-0x0FF60)   ulelong >0           \b)
-
-#------------------------------------------------------------------------------
-# motorola:  file(1) magic for Motorola 68K and 88K binaries
-#
-# 68K
-#
-# These signatures are useless without further sanity checking. Disable them until 
-# that can be implemented.
-#0       beshort         0x0208          mc68k COFF
-#>18     beshort         ^00000020       object
-#>18     beshort         &00000020       executable
-#>12     belong          >0              not stripped
-#>168    string          .lowmem         Apple toolbox
-#>20     beshort         0407            (impure)
-#>20     beshort         0410            (pure)
-#>20     beshort         0413            (demand paged)
-#>20     beshort         0421            (standalone)
-#0       beshort         0x0209          mc68k executable (shared)
-#>12     belong          >0              not stripped
-#0       beshort         0x020A          mc68k executable (shared demand paged)
-#>12     belong          >0              not stripped
-
-
-#------------------------------------------------------------------------------
-# Sony Playstation executables (Adam Sjoegren <asjo@diku.dk>) :
-0       string  PS-X\x20EXE       Sony Playstation executable
-#  Area:
->113    string  x               ("%s")
-
-#------------------------------------------------------------------------------
-# cisco:  file(1) magic for cisco Systems routers
-#
-# Most cisco file-formats are covered by the generic elf code
-0      string                  \x85\x01\x14    Cisco IOS microcode
->7      string                 >\0             
->>7    string                  x               for "%s"
-0      string                  \x85\x01\xcb    Cisco IOS experimental microcode
->7      string                 >\0             
->>7    string                  x               for "%s"
-
-# EST flat binary format (which isn't, but anyway)
-# From: Mark Brown <broonie@sirena.org.uk>
-0      string  ESTFBINR        EST flat binary
-
-# These are not the binaries themselves, but string references to them
-# are a strong indication that they exist elsewhere...
-#0     string  /bin/busybox    Busybox string reference: "%s"{one-of-many}
-#0     string /bin/sh          Shell string reference: "%s"{one-of-many}
-
-#--------------------File Systems---------------------
-
-# Minix filesystems - Juan Cespedes <cespedes@debian.org>
-# These signatures are useless until they can be improved.
-#0x410   leshort         0x137f          Minix filesystem
-#>0x402  beshort         !0              \b, %d zones
-#>0x1e   string          minix           \b, bootable
-#0x410   leshort         0x138f          Minix filesystem, 30 char names
-#0x410   leshort         0x2468          Minix filesystem, version 2
-#0x410   leshort         0x2478          Minix filesystem, version 2, 30 char names
-#0x410 leshort         0x4d5a          Minix filesystem, version 3
-#0x410 leshort         0x4d6a          Minix filesystem, version 3, 30 char names
-
-#0x410   beshort         0x137f          Minix filesystem (big endian)
-#>0x402  beshort         !0              \b, %d zones
-#>0x1e   string          minix           \b, bootable
-#0x410   beshort         0x138f          Minix filesystem (big endian), 30 char names
-#0x410   beshort         0x2468          Minix filesystem (big endian), version 2
-#0x410   beshort         0x2478          Minix filesystem (big endian), version 2, 30 char names
-#0x410 beshort         0x4d5a          Minix filesystem (big endian), version 3
-#0x410 beshort         0x4d6a          Minix filesystem (big endian), version 3, 30 char names
-
-# YAFFS
-0      string  \x03\x00\x00\x00\x01\x00\x00\x00\xFF\xFF        YAFFS filesystem
-
-# EFS2 file system - jojo@utulsa.edu
-0      lelong 0x53000000       EFS2 Qualcomm filesystem super block, little endian,
->8     string !EFSSuper        invalid,
->4     leshort &1              NAND
->4     leshort ^1              NOR
->4     leshort x               version 0x%x,
->24    lelong  x               %d blocks,
->16    lelong  x               0x%x pages per block,
->20    lelong  x               0x%x bytes per page
-
-0      belong 0x53000000       EFS2 Qualcomm filesystem super block, big endian,
->8     string !SSFErepu               invalid,
->4     beshort &1              NAND
->4     beshort ^1              NOR
->4     beshort x               version 0x%x,
->24    belong  x               %d blocks,
->16    belong  x               0x%x pages per block,
->20    belong  x               0x%x bytes per page
-
-# TROC file system
-0      string  TROC            TROC filesystem,
->4     lelong  x               %d file entries
-
-# PFS file system
-0      string  PFS/            PFS filesystem,
->4     string  x               version "%s",
->14    leshort x               %d files
-
-# MPFS file system
-0      string  MPFS            MPFS (Microchip) filesystem,
->4     byte    x               version %d.
->5     byte    x               \b%d,
->6     leshort x               %d file entries
-
-# cramfs filesystem - russell@coker.com.au
-0       lelong  0x28cd3d45      CramFS filesystem, little endian
->4     lelong  <0              invalid
->4     lelong  >1073741824     invalid
->4      lelong  x              size %lu
->8      lelong  &1             version #2
->8      lelong  &2             sorted_dirs
->8      lelong  &4             hole_support
->32     lelong  x              CRC 0x%x,
->36     lelong  x              edition %lu,
->40    lelong  <0              invalid
->40     lelong  x              %lu blocks,
->44    lelong  <0              invalid
->44     lelong  x              %lu files
->4      lelong  x              {jump-to-offset:%lu}
->4      lelong  x              {file-size:%lu}
-
-0       belong  0x28cd3d45      CramFS filesystem, big endian
->4     belong  <0              invalid
->4     lelong  >536870912000   invalid
->4      belong  x              size %lu
->8      belong  &1             version #2
->8      belong  &2             sorted_dirs
->8      belong  &4             hole_support
->32     belong  x              CRC 0x%x,
->36     belong  x              edition %lu,
->40    belong  <0              invalid
->40     belong  x              %lu blocks,
->44    belong  <0              invalid
->44     belong  x              %lu files
->4      belong  x              {jump-to-offset:%lu}
->4      belong  x              {file-size:%lu}
-
-
-
-# JFFS2 file system
-# If used with binwalk's smart signature feature (on by default, -S to disable)
-# this signature can potentially lead to missing some JFFS2 file systems if there
-# are multiple JFFS2 file systems in a target file and there are no other identified
-# files in between the JFFS2 file systems. This is an unlikely scenario however, and
-# the below signatures are much improved in terms of readability and accuracy in the
-# vast majority of real world scenarios.
-0              leshort 0x1985  JFFS2 filesystem, little endian
->2             leshort !0xE001
->>2            leshort !0xE002
->>>2           leshort !0x2003
->>>>2          leshort !0x2004
->>>>>2         leshort !0x2006
->>>>>>2                leshort !0xE008
->>>>>>>2       leshort !0xE009 \b, invalid
->(4.l)         leshort !0x1985         
->>(4.l+1)      leshort !0x1985 
->>>(4.l+2)     leshort !0x1985 
->>>>(4.l+3)    leshort !0x1985
->>>>>(4.l)      leshort !0xFFFF
->>>>>>(4.l+1)   leshort !0xFFFF
->>>>>>>(4.l+2)  leshort !0xFFFF
->>>>>>>>(4.l+3) leshort !0xFFFF \b, invalid
->4             lelong  0       invalid
->4             lelong  <0      invalid
->4             lelong  x       {one-of-many}{jump-to-offset:%d}
-
-0              beshort 0x1985  JFFS2 filesystem, big endian
->2             beshort !0xE001
->>2            beshort !0xE002
->>>2           beshort !0x2003
->>>>2          beshort !0x2004
->>>>>2         beshort !0x2006
->>>>>>2                beshort !0xE008
->>>>>>>2       beshort !0xE009 \b, invalid
->(4.L)         beshort !0x1985  
->>(4.L+1)      beshort !0x1985  
->>>(4.L+2)     beshort !0x1985
->>>>(4.L+3)    beshort !0x1985 
->>>>>(4.L)     beshort !0xFFFF
->>>>>>(4.L+1)  beshort !0xFFFF
->>>>>>>(4.L+2) beshort !0xFFFF
->>>>>>>>(4.L+3)        beshort !0xFFFF \b, invalid
->4             belong  0       invalid
->4             belong  <0      invalid
->4             belong  x       {one-of-many}{jump-to-offset:%d}
-
-
-# Squashfs, big endian
-0       string  sqsh    Squashfs filesystem, big endian,
->28     beshort >10     invalid
->28     beshort <1      invalid
->30    beshort >10     invalid
->28     beshort x       version %d.
->30     beshort x       \b%d,
->28     beshort >3      compression:
->>20    beshort 1       \bgzip,
->>20    beshort 2       \blzma,
->>20   beshort 3       \bgzip (non-standard type definition),
->>20   beshort 4       \blzma (non-standard type definition),
->>20    beshort 0       \binvalid,
->>20    beshort >4      \binvalid,
->28     beshort <3
->>8     belong  x       size: %d bytes,
->28     beshort 3
->>63    bequad x        size: %lld bytes,
->28     beshort >3
->>40    bequad  x       size: %lld bytes,
->4      belong  x       %d inodes,
->28     beshort >3
->>12    belong          blocksize: %d bytes,
->28     beshort <2
->>32    beshort x       blocksize: %d bytes,
->28     beshort 2
->>51    belong  x       blocksize: %d bytes,
->28     beshort 3
->>51    belong  x       blocksize: %d bytes,
->28     beshort >3
->>12    belong  x       blocksize: %d bytes,
->28     beshort <4
->>39    bedate  x       created: %s
->28     beshort >3
->>8     bedate x        created: %s
->28    beshort <3
->>8    belong  x       {jump-to-offset:%d}
->28    beshort 3       
->>63   bequad  x       {jump-to-offset:%lld}
->28    beshort >3
->>40   bequad  x       {jump-to-offset:%lld}
-
-# Squashfs, little endian
-0       string  hsqs    Squashfs filesystem, little endian,
->28     leshort >10     invalid
->28     leshort <1      invalid
->30    leshort >10     invalid
->28     leshort x       version %d.
->30     leshort x       \b%d,
->28    leshort >3      compression:
->>20   leshort 1       \bgzip,
->>20   leshort 2       \blzma,
->>20   leshort 3       \bgzip (non-standard type definition),
->>20   leshort 4       \blzma (non-standard type definition),
->>20   leshort 0       \binvalid,
->>20   leshort >4      \binvalid,
->28     leshort <3
->>8     lelong  x       size: %d bytes,
->>8     lelong  x       {file-size:%d}
->28     leshort 3
->>63    lequad x        size: %lld bytes,
->>63    lequad x        {file-size:%lld}
->28    leshort >3      
->>40   lequad  x       size: %lld bytes,
->>40   lequad  x       {file-size:%lld}
->4      lelong  x       %d inodes,
->28    leshort >3
->>12   lelong          blocksize: %d bytes,
->28     leshort <2
->>32    leshort x       blocksize: %d bytes,
->28     leshort 2
->>51    lelong  x       blocksize: %d bytes,
->28    leshort 3
->>51   lelong  x       blocksize: %d bytes,
->28    leshort >3      
->>12   lelong  x       blocksize: %d bytes,
->28    leshort <4
->>39    ledate  x      created: %s
->28    leshort >3
->>8    ledate x        created: %s
->28     leshort <3
->>8     lelong  x       {jump-to-offset:%d}
->28     leshort 3
->>63    lequad x        {jump-to-offset:%lld}
->28     leshort >3
->>40    lequad  x       {jump-to-offset:%lld}
-
-# Squashfs with LZMA compression
-0       string  sqlz    Squashfs filesystem, big endian, lzma compression, 
->28     beshort >10     invalid
->28     beshort <1      invalid
->30    beshort >10     invalid
->28     beshort x       version %d.
->30     beshort x       \b%d,
->28     beshort >3      compression:
->>20    beshort 1       \bgzip,
->>20    beshort 2       \blzma,
->>20   beshort 3       \bgzip (non-standard type definition),
->>20   beshort 4       \blzma (non-standard type definition),
->>20    beshort 0       \binvalid,
->>20    beshort >4      \binvalid,
->28     beshort <3
->>8     belong  x       size: %d bytes,
->>8     belong  x       {file-size:%d}
->28     beshort 3
->>63    bequad x        size: %lld bytes,
->>63    bequad x        {file-size:%lld}
->28     beshort >3
->>40    bequad  x       size: %lld bytes,
->>40    bequad  x       {file-size:%lld}
->4      belong  x       %d inodes,
->28     beshort >3
->>12    belong          blocksize: %d bytes,
->28     beshort <2
->>32    beshort x       blocksize: %d bytes,
->28     beshort 2
->>51    belong  x       blocksize: %d bytes,
->28     beshort 3
->>51    belong  x       blocksize: %d bytes,
->28     beshort >3
->>12    belong  x       blocksize: %d bytes,
->28     beshort <4
->>39    bedate  x       created: %s
->28     beshort >3
->>8     bedate x        created: %s
->28     beshort <3
->>8     belong  x       {jump-to-offset:%d}
->28     beshort 3
->>63    bequad  x       {jump-to-offset:%lld}
->28     beshort >3
->>40    bequad  x       {jump-to-offset:%lld}
-
-# Squashfs 3.3 LZMA signature
-0       string  qshs    Squashfs filesystem, big endian, lzma signature,
->28     beshort >10     invalid
->28     beshort <1      invalid
->30    beshort >10     invalid
->28     beshort x       version %d.
->30     beshort x       \b%d,
->28     beshort >3      compression:
->>20    beshort 1       \bgzip,
->>20    beshort 2       \blzma,
->>20   beshort 3       \bgzip (non-standard type definition),
->>20   beshort 4       \blzma (non-standard type definition),
->>20    beshort 0       \binvalid,
->>20    beshort >4      \binvalid,
->28     beshort <3
->>8     belong  x       size: %d bytes,
->>8     belong  x       {file-size:%d}
->28     beshort 3
->>63    bequad x        size: %lld bytes,
->>63    bequad x        {file-size:%lld}
->28     beshort >3
->>40    bequad  x       size: %lld bytes,
->>40    bequad  x       {file-size:%lld}
->4      belong  x       %d inodes,
->28     beshort >3
->>12    belong          blocksize: %d bytes,
->28     beshort <2
->>32    beshort x       blocksize: %d bytes,
->28     beshort 2
->>51    belong  x       blocksize: %d bytes,
->28     beshort 3
->>51    belong  x       blocksize: %d bytes,
->28     beshort >3
->>12    belong  x       blocksize: %d bytes,
->28     beshort <4
->>39    bedate  x       created: %s
->28     beshort >3
->>8     bedate x        created: %s
->28     beshort <3
->>8     belong  x       {jump-to-offset:%d}
->28     beshort 3
->>63    bequad  x       {jump-to-offset:%lld}
->28     beshort >3
->>40    bequad  x       {jump-to-offset:%lld}
-
-# Squashfs for DD-WRT
-0       string  tqsh    Squashfs filesystem, big endian, DD-WRT signature,
->28     beshort >10     invalid
->28     beshort <1      invalid
->30    beshort >10     invalid
->28     beshort x       version %d.
->30     beshort x       \b%d,
->28     beshort >3      compression:
->>20    beshort 1       \bgzip,
->>20    beshort 2       \blzma,
->>20   beshort 3       \bgzip (non-standard type definition),
->>20   beshort 4       \blzma (non-standard type definition),
->>20    beshort 0       \binvalid,
->>20    beshort >4      \binvalid,
->28     beshort <3
->>8     belong  x       size: %d bytes,
->>8     belong  x       {file-size:%d}
->28     beshort 3
->>63    bequad x        size: %lld bytes,
->>63    bequad x        {file-size:%lld}
->28     beshort >3
->>40    bequad  x       size: %lld bytes,
->>40    bequad  x       {file-size:%lld}
->4      belong  x       %d inodes,
->28     beshort >3
->>12    belong          blocksize: %d bytes,
->28     beshort <2
->>32    beshort x       blocksize: %d bytes,
->28     beshort 2
->>51    belong  x       blocksize: %d bytes,
->28     beshort 3
->>51    belong  x       blocksize: %d bytes,
->28     beshort >3
->>12    belong  x       blocksize: %d bytes,
->28     beshort <4
->>39    bedate  x       created: %s
->28     beshort >3
->>8     bedate x        created: %s
->28     beshort <3
->>8     belong  x       {jump-to-offset:%d}
->28     beshort 3
->>63    bequad  x       {jump-to-offset:%lld}
->28     beshort >3
->>40    bequad  x       {jump-to-offset:%lld}
-
-# Squashfs for DD-WRT
-0       string  hsqt    Squashfs filesystem, little endian, DD-WRT signature,
->28     leshort >10     invalid
->28     leshort <1      invalid
->30    leshort >10     invalid
->28     leshort x       version %d.
->30     leshort x       \b%d,
->28     leshort >3      compression:
->>20    leshort 1       \bgzip,
->>20    leshort 2       \blzma,
->>20   leshort 3       \bgzip (non-standard type definition),
->>20   leshort 4       \blzma (non-standard type definition),
->>20    leshort 0       \binvalid,
->>20    leshort >4      \binvalid,
->28     leshort <3
->>8     lelong  x       size: %d bytes,
->>8     lelong  x       {file-size:%d}
->28     leshort 3
->>63    lequad x        size: %lld bytes,
->>63    lequad x        {file-size:%lld}
->28     leshort >3
->>40    lequad  x       size: %lld bytes,
->>40    lequad  x       {file-size:%lld}
->4      lelong  x       %d inodes,
->28     leshort >3
->>12    lelong          blocksize: %d bytes,
->28     leshort <2
->>32    leshort x       blocksize: %d bytes,
->28     leshort 2
->>51    lelong  x       blocksize: %d bytes,
->28     leshort 3
->>51    lelong  x       blocksize: %d bytes,
->28     leshort >3
->>12    lelong  x       blocksize: %d bytes,
->28     leshort <4
->>39    ledate  x       created: %s
->28     leshort >3
->>8     ledate x        created: %s
->28     leshort <3
->>8     lelong  x       {jump-to-offset:%d}
->28     leshort 3
->>63    lequad x        {jump-to-offset:%lld}
->28     leshort >3
->>40    lequad  x       {jump-to-offset:%lld}
-
-# Non-standard Squashfs signature found on some D-Link routers
-0       string  shsq    Squashfs filesystem, little endian, non-standard signature, 
->28     leshort >10     invalid
->28     leshort <1      invalid
->30    leshort >10     invalid
->28     leshort x       version %d.
->30     leshort x       \b%d,
->28     leshort >3      compression:
->>20    leshort 1       \bgzip,
->>20    leshort 2       \blzma,
->>20   leshort 3       \bgzip (non-standard type definition),
->>20   leshort 4       \blzma (non-standard type definition),
->>20    leshort 0       \binvalid,
->>20    leshort >4      \binvalid,
->28     leshort <3
->>8     lelong  x       size: %d bytes,
->>8     lelong  x       {file-size:%d}
->28     leshort 3
->>63    lequad x        size: %lld bytes,
->>63    lequad x        {file-size:%lld}
->28     leshort >3
->>40    lequad  x       size: %lld bytes,
->>40    lequad  x       {file-size:%lld}
->4      lelong  x       %d inodes,
->28     leshort >3
->>12    lelong          blocksize: %d bytes,
->28     leshort <2
->>32    leshort x       blocksize: %d bytes,
->28     leshort 2
->>51    lelong  x       blocksize: %d bytes,
->28     leshort 3
->>51    lelong  x       blocksize: %d bytes,
->28     leshort >3
->>12    lelong  x       blocksize: %d bytes,
->28     leshort <4
->>39    ledate  x       created: %s
->28     leshort >3
->>8     ledate x        created: %s
->28     leshort <3
->>8     lelong  x       {jump-to-offset:%d}
->28     leshort 3
->>63    lequad x        {jump-to-offset:%lld}
->28     leshort >3
->>40    lequad  x       {jump-to-offset:%lld}
-
-# ext2/ext3 filesystems - Andreas Dilger <adilger@dilger.ca>
-# ext4 filesystem - Eric Sandeen <sandeen@sandeen.net>
-# volume label and UUID Russell Coker
-# http://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/
-0   leshort         0xEF53             Linux EXT filesystem,{offset-adjust:-0x438}
->2     leshort         >4              invalid state
->2     leshort         3               invalid state
->2     leshort         <0              invalid state
->4     leshort         >3              invalid error behavior
->4     leshort         <0              invalid error behavior
->4     lelong          >1              invalid major revision
->4  lelong             <0              invalid major revision
->4  lelong          x               rev %d
->6  leshort         x               \b.%d
-# No journal?  ext2
->36  lelong          ^0x0000004      ext2 filesystem data
->>2 leshort         ^0x0000001      (mounted or unclean)
-# Has a journal?  ext3 or ext4
->36  lelong          &0x0000004
-#  and small INCOMPAT?
->>40 lelong          <0x0000040
-#   and small RO_COMPAT?
->>>44 lelong         <0x0000008      ext3 filesystem data
-#   else large RO_COMPAT?
->>>44 lelong         >0x0000007      ext4 filesystem data
-#  else large INCOMPAT?
->>40 lelong          >0x000003f      ext4 filesystem data
->48  belong          x               \b, UUID=%08x
->52  beshort         x               \b-%04x
->54  beshort         x               \b-%04x
->56  beshort         x               \b-%04x
->58  belong          x               \b-%08x
->60  beshort         x               \b%04x
->64  string          >0              \b, volume name "%s"
-
-
-#romfs filesystems - Juan Cespedes <cespedes@debian.org>
-0       string -rom1fs-\0              romfs filesystem, version 1
->8     belong  >10000000               invalid
->8      belong  x                       size: %d bytes,
->16    string  x                       {file-name:%s}
->16     string  x                       named "%s"
->8     belong  x                       {file-size:%d}
->8     belong  x                       {jump-to-offset:%d}
-
-# Wind River MemFS file system, found in some VxWorks devices
-0      string  owowowowowowowowowowowowowowow          Wind River management filesystem,
->30    string  !ow                                     invalid,
->32    belong  1                                       compressed,
->32    belong  2                                       plain text,
->36    belong  x                                       %d files
-
-# netboot image - Juan Cespedes <cespedes@debian.org>
-0      lelong                  0x1b031336L     Netboot image,
->4     lelong&0xFFFFFF00       0
->>4    lelong&0x100            0x000           mode 2
->>4    lelong&0x100            0x100           mode 3
->4     lelong&0xFFFFFF00       !0              unknown mode (invalid)
-
-0      string                  WDK\x202.0\x00  WDK file system, version 2.0{offset-adjust:-18}
-
-0      string          CD001                                           ISO{offset-adjust:-32769}
->6144  string          !NSR0                                           9660 CD-ROM filesystem data,
->6144  string          NSR0                                            UDF filesystem data,
->6148  string          1                                               version 1.0,
->6148  string          2                                               version 2.0,
->6148  string          3                                               version 3.0
->6148  byte            >0x33                                           invalid version,
->6148  byte            <0x31                                           invalid version,
->38    string          >\0                                             volume name: "%s",
->2047  string          \000CD001\001EL\x20TORITO\x20SPECIFICATION      bootable
-
-
-#--------------------------Firmware Formats---------------------------
-
-# uImage file     
-# From: Craig Heffner, U-Boot image.h header definitions file
-0      belong  0x27051956      uImage header, header size: 64 bytes,
->4     belong  x               header CRC: 0x%X,
->8     bedate  x               created: %s,
->12    belong  x               image size: %d bytes,
->16    belong  x               Data Address: 0x%X,
->20    belong  x               Entry Point: 0x%X,
->24    belong  x               data CRC: 0x%X,
-#>28   byte    x               OS type: %d,
->28    byte    0               OS: invalid OS,
->28    byte    1               OS: OpenBSD,
->28    byte    2               OS: NetBSD,
->28    byte    3               OS: FreeBSD,
->28    byte    4               OS: 4.4BSD,
->28    byte    5               OS: Linux,
->28    byte    6               OS: SVR4,
->28    byte    7               OS: Esix,
->28    byte    8               OS: Solaris,
->28    byte    9               OS: Irix,
->28    byte    10              OS: SCO,
->28    byte    11              OS: Dell,
->28    byte    12              OS: NCR,
->28    byte    13              OS: LynxOS,
->28    byte    14              OS: VxWorks,
->28    byte    15              OS: pSOS,
->28    byte    16              OS: QNX,
->28    byte    17              OS: Firmware,
->28    byte    18              OS: RTEMS,
->28    byte    19              OS: ARTOS,
->28    byte    20              OS: Unity OS,
-#>29   byte    x               CPU arch: %d,
->29    byte    0               CPU: invalid OS,
->29    byte    1               CPU: Alpha,
->29    byte    2               CPU: ARM,
->29    byte    3               CPU: Intel x86,
->29    byte    4               CPU: IA64,
->29    byte    5               CPU: MIPS,
->29    byte    6               CPU: MIPS 64 bit,
->29    byte    7               CPU: PowerPC,
->29    byte    8               CPU: IBM S390,
->29    byte    9               CPU: SuperH,
->29    byte    10              CPU: Sparc,
->29    byte    11              CPU: Sparc 64 bit,
->29    byte    12              CPU: M68K,
->29    byte    13              CPU: Nios-32,
->29    byte    14              CPU: MicroBlaze,
->29    byte    15              CPU: Nios-II,
->29    byte    16              CPU: Blackfin,
->29    byte    17              CPU: AVR,
->29    byte    18              CPU: STMicroelectronics ST200,
-#>30   byte    x               image type: %d,
->30    byte    0               image type: invalid Image,
->30    byte    1               image type: Standalone Program,
->30    byte    2               image type: OS Kernel Image,
->30    byte    3               image type: RAMDisk Image,
->30    byte    4               image type: Multi-File Image,
->30    byte    5               image type: Firmware Image,
->30    byte    6               image type: Script file,
->30    byte    7               image type: Filesystem Image,
->30    byte    8               image type: Binary Flat Device Tree Blob
-#>31   byte    x               compression type: %d,
->31    byte    0               compression type: none,
->31    byte    1               compression type: gzip,
->31    byte    2               compression type: bzip2,
->31    byte    3               compression type: lzma,
->32    string  x               image name: "%s"
-
-#IMG0 header, found in VxWorks-based Mercury router firmware
-0      string          IMG0            IMG0 (VxWorks) header,
->4     belong          x               size: %d
-
-#Mediatek bootloader signature
-#From xp-dev.com
-0      string          BOOTLOADER!     Mediatek bootloader
-
-#CSYS header formats
-0      string          CSYS\x00        CSYS header, little endian, 
->8     lelong          x               size: %d
-
-0      string          CSYS\x80        CSYS header, big endian,
->8     belong          x               size: %d
-
-# wrgg firmware image
-0      string          wrgg02          WRGG firmware header,
->6     string          x               name: "%s",
->48    string          x               root device: "%s"
-
-# trx image file
-0      string          HDR0            TRX firmware header, little endian, header size: 28 bytes,
->4     lelong          <1              invalid
->4     lelong          x               image size: %d bytes,
->8     lelong          x               CRC32: 0x%X
->12    leshort         x               flags: 0x%X,
->14    leshort         x               version: %d
-
-0      string          0RDH            TRX firmware header, big endian, header size: 28 bytes,
->4     belong          <1              invalid
->4     belong          x               image size: %d bytes,
->8     belong          x               CRC32: 0x%X
->12    beshort         x               flags: 0x%X,
->14    beshort         x               version: %d
-
-
-# Ubicom firmware image
-0      belong  0xFA320080              Ubicom firmware header,
->12    belong  x                       checksum: 0x%X,
->24    belong  <0                      invalid
->24    belong  x                       image size: %d
-
-# The ROME bootloader is used by several RealTek-based products.
-# Unfortunately, the magic bytes are specific to each product, so
-# separate signatures must be created for each one.
-
-# Netgear KWGR614 ROME image
-0      string          G614            Realtek firmware header (ROME bootloader),
->4     beshort         0xd92f          image type: KFS,
->4     beshort         0xb162          image type: RDIR,
->4     beshort         0xea43          image type: BOOT,
->4     beshort         0x8dc9          image type: RUN,
->4     beshort         0x2a05          image type: CCFG,
->4     beshort         0x6ce8          image type: DCFG,
->4     beshort         0xc371          image type: LOG,
->6     byte            x               header version: %d,
-#month
->10    byte            x               created: %d/
-#day   
->12    byte            x               \b%d/
-#year
->8     beshort         x               \b%d,
->16    belong          x               image size: %d bytes,
->22    byte            x               body checksum: 0x%X,
->23    byte            x               header checksum: 0x%X
-
-# Linksys WRT54GX ROME image
-0      belong          0x59a0e842      Realtek firmware header (ROME bootloader)
->4      beshort         0xd92f          image type: KFS,
->4      beshort         0xb162          image type: RDIR,
->4      beshort         0xea43          image type: BOOT,
->4      beshort         0x8dc9          image type: RUN,
->4      beshort         0x2a05          image type: CCFG,
->4      beshort         0x6ce8          image type: DCFG,
->4      beshort         0xc371          image type: LOG,
->6      byte            x               header version: %d,
-#month
->10     byte            x               created: %d/
-#day    
->12     byte            x               \b%d/
-#year
->8      beshort         x               \b%d,
->16     belong          x               image size: %d bytes,
->22     byte            x               body checksum: 0x%X,
->23     byte            x               header checksum: 0x%X
-
-# PackImg tag, somtimes used as a delimiter between the kernel and rootfs in firmware images.
-0      string          --PaCkImGs--    PackImg section delimiter tag,
-# If the size in both big and little endian is greater than 512MB, consider this a false positive
->16    lelong          >0x20000000
->>16   belong          >0x20000000     invalid
->16    lelong          <0
->>16   belong          <0              invalid
->16    lelong          >0
->>16   lelong          x               little endian size: %d bytes;
->16    belong          >0              
->>16   belong          x               big endian size: %d bytes
-
-
-#------------------------------------------------------------------------------
-# Broadcom header format
-#
-0       string          BCRM            Broadcom header,
->4     lelong          <0              invalid
->4      lelong          x               number of sections: %d,
->>8     lelong          18              first section type: flash
->>8     lelong          19              first section type: disk
->>8     lelong          21              first section type: tag
-
-
-# Berkeley Lab Checkpoint Restart (BLCR) checkpoint context files
-# http://ftg.lbl.gov/checkpoint
-0       string  Ck0\0\0R\0\0\0  BLCR
->16     lelong  1       x86
->16     lelong  3       alpha
->16     lelong  5       x86-64
->16     lelong  7       ARM
->8      lelong  x       context data (little endian, version %d)
-
-0       string  \0\0\0C\0\0\0R  BLCR
->16     belong  2       SPARC
->16     belong  4       ppc
->16     belong  6       ppc64
->16     belong  7       ARMEB
->16     belong  8       SPARC64
->8      belong  x       context data (big endian, version %d)
-
-# Aculab VoIP firmware
-# From: Mark Brown <broonie@sirena.org.uk>
-0       string  VoIP\x20Startup\x20and      Aculab VoIP firmware
->35     string  x       format "%s"
-
-#------------------------------------------------------------------------------
-# HP LaserJet 1000 series downloadable firmware file
-0       string  \xbe\xefABCDEFGH        HP LaserJet 1000 series downloadable firmware
-
-# From Albert Cahalan <acahalan@gmail.com>
-# really le32 operation,destination,payloadsize (but quite predictable)
-# 01 00 00 00 00 00 00 c0 00 02 00 00
-0       string          \1\0\0\0\0\0\0\300\0\2\0\0      Marvell Libertas firmware
-
-#---------------------------------------------------------------------------
-# The following entries have been tested by Duncan Laurie <duncan@sun.com> (a
-# lead Sun/Cobalt developer) who agrees that they are good and worthy of
-# inclusion.
-
-# Boot ROM images for Sun/Cobalt Linux server appliances
-0       string  Cobalt\x20Networks\x20Inc.\nFirmware\x20v     Paged COBALT boot rom
->38     string x        V%.4s
-
-# New format for Sun/Cobalt boot ROMs is annoying, it stores the version code
-# at the very end where file(1) can't get it.
-0       string CRfs     COBALT boot rom data (Flat boot rom or file system)
-
-#
-# Motorola S-Records, from Gerd Truschinski <gt@freebsd.first.gmd.de>
-# Useless until forther improvements can be made to the signature.
-#0   string      S0          Motorola S-Record; binary data in text format
-
-# --------------------------------
-# Microsoft Xbox data file formats
-0       string          XIP0            XIP, Microsoft Xbox data
-0       string          XTF0            XTF, Microsoft Xbox data
-
-#Windows CE
-0      string          CECE            Windows CE RTOS{offset-adjust:-64}
-
-# --------------------------------
-# ZynOS ROM header format
-# From openwrt zynos.h.
-0      string          SIG             ZynOS header, header size: 48 bytes,{offset-adjust:-6}
-#>0    belong          x               load address 0x%X,
->3     byte            <0x7F           rom image type:
->>3    byte            <1              invalid,
->>3    byte            >7              invalid,
->>3    byte            1               ROMIMG,
->>3    byte            2               ROMBOOT,
->>3    byte            3               BOOTEXT,
->>3    byte            4               ROMBIN,
->>3    byte            5               ROMDIR,
->>3    byte            6               6,
->>3    byte            7               ROMMAP,
->3     byte            >0x7F           ram image type:
->>3    byte            >0x82           invalid,
->>3    byte            0x80            RAM,
->>3    byte            0x81            RAMCODE,
->>3    byte            0x82            RAMBOOT,
->4     belong          >0x40000000     invalid
->4     belong          <0              invalid
->4     belong          0               invalid
->4     belong          x               uncompressed size: %d,
->8     belong          >0x40000000     invalid
->8     belong          <0              invalid
->8     belong          0               invalid
->8     belong          x               compressed size: %d,
->14    beshort         x               uncompressed checksum: 0x%X,
->16    beshort         x               compressed checksum: 0x%X,
->12    byte            x               flags: 0x%X,
->12    byte            &0x40           uncompressed checksum is valid,
->12    byte            &0x80           the binary is compressed,
->>12   byte            &0x20           compressed checksum is valid,
->35    belong          x               memory map table address: 0x%X
-
-# Firmware header used by some VxWorks-based Cisco products
-0      string          CI032.00        Cisco VxWorks firmware header,
->8     lelong          >1024           invalid
->8     lelong          <0              invalid
->8     lelong          x               header size: %d bytes,
->32    lelong          >1024           invalid
->32    lelong          <0              invalid
->32    lelong          x               number of files: %d,
->48    lelong          <0              invalid
->48    lelong          x               image size: %d,
->64    string          x               firmware version: "%s"
-
-# Firmware header used by some TV's
-0      string          FNIB            ZBOOT firmware header, header size: 32 bytes,
->8     lelong          x               load address: 0x%.8X,
->12    lelong          x               start address: 0x%.8X,
->16    lelong          x               checksum: 0x%.8X,
->20    lelong          x               version: 0x%.8X,
->24    lelong          <1              invalid
->24    lelong          x               image size: %d bytes
-
-# Firmware header used by several D-Link routers (and probably others)
-0               string  \x5e\xa3\xa4\x17       DLOB firmware header,
->(7.b+12)       string  !\x5e\xa3\xa4\x17       invalid,
-#>>12           string  x                       %s,
->(7.b+40)       string  x                       boot partition: "%s"
-
-# TP-Link firmware header structure; thanks to Jonathan McGowan for reversing and documenting this format
-0      string          TP-LINK\x20Technologies         TP-Link firmware header,{offset-adjust:-4}
-#>-4   lelong          x                               header version: %d,
->0x94          beshort         x                               firmware version: %d.
->0x96          beshort         x                               \b%d.
->0x98          beshort         x                               \b%d,
->0x18          string          x                               image version: "%s",
-#>0x74  belong          x                              image size: %d bytes,
->0x3C          belong          x                               product ID: 0x%X,
->0x40          belong          x                               product version: %d,
->0x70          belong          x                               kernel load address: 0x%X,
->0x74          belong          x                               kernel entry point: 0x%X,
->0x7C          belong          x                               kernel offset: %d,
->0x80          belong          x                               kernel length: %d,
->0x84          belong          x                               rootfs offset: %d,
->0x88          belong          x                               rootfs length: %d,
->0x8C          belong          x                               bootloader offset: %d,
->0x90          belong          x                               bootloader length: %d
-
-# Header format from: http://skaya.enix.org/wiki/FirmwareFormat
-0      string          \x36\x00\x00\x00                Broadcom 96345 firmware header, header size: 256,
->4     string          !Broadcom
->>4    string          !\x20\x20\x20\x20               invalid
->41    beshort         !0x2020
->>41   beshort         !0x0000
->>>41  string          x                               firmware version: "%.4s",
->45    beshort         !0x0202
->>45   beshort         !0x0000
->>>45  string          x                               board id: "%s",
->236   belong          x                               ~CRC32 header checksum: 0x%X,
->216   belong          x                               ~CRC32 data checksum: 0x%X
-
-# Xerox MFP DLM signatures
-0      string          %%XRXbegin                      Xerox DLM firmware start of header
-0      string          %%OID_ATT_DLM_NAME              Xerox DLM firmware name:
->19    string          x                               "%s"
-0      string          %%OID_ATT_DLM_VERSION           Xerox DLM firmware version:
->22    string          x                               "%s"
-0      string          %%XRXend                        Xerox DLM firmware end of header
-
-# Generic copyright signature
-0      string          Copyright                       Copyright string:
->9     byte            0                               invalid
->9     string          x                               "%s
->40    string          x                               \b%s"
-
-# Sercomm firmware header
-0      string          sErCoMm                         Sercomm firmware signature,
->7     leshort         x                               version control: %d,
->9     leshort         x                               download control: %d,
->11    string          x                               hardware ID: "%s",
->44    leshort         x                               hardware version: 0x%X,
->58    leshort         x                               firmware version: 0x%X,
->60    leshort         x                               starting code segment: 0x%X,
->62    leshort         x                               code size: 0x%X
-
-# NPK firmware header, used by Mikrotik
-0              belong          0x1EF1D0BA              NPK firmware header,
->4             lelong          <0                      invalid
->4             lelong          x                       image size: %d,
->14            string          x                       image name: "%s",
->(48.l+58)     string          x                       description: "%s
->(48.l+121)    string          x                       \b%s"
-
-# Ubiquiti firmware signatures
-0      string          UBNT            Ubiquiti firmware header,
->0x104 belong          x               ~CRC32: 0x%X,
->4     string          x               version: "%s"
-
-0      string          GEOS            Ubiquiti firmware header,
->0x104 belong          x               ~CRC32: 0x%X,
->4     string          x               version: "%s"
-
-# Too many false positives...
-#0     string          OPEN            Ubiquiti firmware header, third party,
-#>0x104        belong          x               ~CRC32: 0x%X,
-#>4    string          x               version: "%s"
-
-0      string          PARTkernel      Ubiquiti firmware kernel partition
-0      string          PARTcramfs      Ubiquiti firmware CramFS partition
-0      string          PARTrootfs      Ubiquiti firmware rootfs partition
-
-# Found in DIR-100 firmware
-0       string         AIH0N           AIH0N firmware header, header size: 48,
->12     belong         x               size: %d,
->8      belong         !0              executable code,
->>8     belong         x               load address: 0x%X,
->32     string         x               version: "%s"
-
-0      belong          0x5EA3A417      SEAMA firmware header, big endian,
->6     beshort         x               meta size: %d,
->8     belong          x               size: %d
-
-0      lelong          0x5EA3A417      SEAMA firmware header, little endian,
->6     leshort         x               meta size: %d,
->8     lelong          x               size: %d
-
-0      belong          0x4D544443      NSP firmware header, big endian,
->16    belong          x               header size: %d,
->20    belong          x               image size: %d,
->4     belong          x               kernel offset: %d,
->12    belong          x               header version: %d,
-
-0      lelong          0x4D544443      NSP firmware header, little endian,
->16    lelong          x               header size: %d,
->20    lelong          x               image size: %d,
->4     lelong          x               kernel offset: %d,
->12    lelong          x               header version: %d,
-
-# http://www.openwiz.org/wiki/Firmware_Layout#Beyonwiz_.wrp_header_structure
-0      string          WizFwPkgl       Beyonwiz firmware header,
->20    string          x               version: "%s"
-
-0      string          BLI223WJ0       Thompson/Alcatel encoded firmware,
->32    byte            x               version: %d.
->33    byte            x               \b%d.
->34    byte            x               \b%d.
->35    byte            x               \b%d,
->44    belong          x               size: %d,
->48    belong          x               crc: 0x%.8X,
->35    byte            x               try decryption tool from:
->35    byte            x               http://download.modem-help.co.uk/mfcs-A/Alcatel/Modems/Misc/
-
-# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com)
-# The second word of TIFF files is the TIFF version number, 42, which has
-# never changed.  The TIFF specification recommends testing for it.
-0       string          MM\x00\x2a      TIFF image data, big-endian
-0       string          II\x2a\x00      TIFF image data, little-endian
-
-# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
-# (Greg Roelofs, newt@uchicago.edu)
-# (Albert Cahalan, acahalan@cs.uml.edu)
-#
-# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ...
-#
-0       string          \x89PNG\x0d\x0a\x1a\x0a         PNG image
->16     belong          x               \b, %ld x
->20     belong          x               %ld,
->24     byte            x               %d-bit
->25     byte            0               grayscale,
->25     byte            2               \b/color RGB,
->25     byte            3               colormap,
->25     byte            4               gray+alpha,
->25     byte            6               \b/color RGBA,
-#>26    byte            0               deflate/32K,
->28     byte            0               non-interlaced
->28     byte            1               interlaced
-
-# GIF
-0       string          GIF8            GIF image data
->4      string          7a              \b, version "8%s",
->4      string          9a              \b, version "8%s",
->6      leshort         >0              %hd x
->8      leshort         >0              %hd
-#>10    byte            &0x80           color mapped,
-#>10    byte&0x07       =0x00           2 colors
-#>10    byte&0x07       =0x01           4 colors
-#>10    byte&0x07       =0x02           8 colors
-#>10    byte&0x07       =0x03           16 colors
-#>10    byte&0x07       =0x04           32 colors
-#>10    byte&0x07       =0x05           64 colors
-#>10    byte&0x07       =0x06           128 colors
-#>10    byte&0x07       =0x07           256 colors
-
-# PC bitmaps (OS/2, Windows BMP files)  (Greg Roelofs, newt@uchicago.edu)
-0       string          BM
->14     leshort         12              PC bitmap, OS/2 1.x format
->>18   lelong          <1              invalid
->>18   lelong          >1000000        invalid
->>18    leshort         x               \b, %d x
->>20   lelong          <1              invalid
->>20   lelong          >1000000        invalid
->>20    leshort         x               %d
->14     leshort         64              PC bitmap, OS/2 2.x format
->>18   lelong          <1              invalid
->>18   lelong          >1000000        invalid
->>18    leshort         x               \b, %d x
->>20   lelong          <1              invalid
->>20   lelong          >1000000        invalid
->>20    leshort         x               %d
->14     leshort         40              PC bitmap, Windows 3.x format
->>18   lelong          <1              invalid
->>18   lelong          >1000000        invalid
->>18    lelong          x               \b, %d x
->>22   lelong &nbs