Commit 5249ca89 by devttys0

Added support for string multiplication in signature matches

parent ad6ac3c3
...@@ -86,10 +86,6 @@ class SignatureLine(object): ...@@ -86,10 +86,6 @@ class SignatureLine(object):
# characters to an integer offset. This will fail if the offset is a complex # characters to an integer offset. This will fail if the offset is a complex
# value (e.g., '(4.l+16)'). # value (e.g., '(4.l+16)').
self.offset = parts[0].replace('>', '') self.offset = parts[0].replace('>', '')
# Check if the offset is an indirect offset
self.is_indirect_offset = self.offset.startswith('(')
try: try:
self.offset = int(self.offset, 0) self.offset = int(self.offset, 0)
except ValueError as e: except ValueError as e:
...@@ -157,6 +153,17 @@ class SignatureLine(object): ...@@ -157,6 +153,17 @@ class SignatureLine(object):
self.value = None self.value = None
# String values need to be decoded, as they may contain escape characters (e.g., '\x20') # String values need to be decoded, as they may contain escape characters (e.g., '\x20')
elif self.type == 'string': elif self.type == 'string':
# String types support multiplication to easily match large repeating byte sequences
if '*' in self.value:
try:
p = self.value.split('*')
self.value = p[0]
for n in p[1:]:
self.value *= int(n, 0)
except KeyboardInterrupt as e:
raise e
except Exception as e:
raise ParserException("Failed to expand string '%s' with integer '%s' in line '%s'" % (self.value, n, line))
try: try:
self.value = binwalk.core.compat.string_decode(self.value) self.value = binwalk.core.compat.string_decode(self.value)
except ValueError as e: except ValueError as e:
...@@ -258,6 +265,7 @@ class Signature(object): ...@@ -258,6 +265,7 @@ class Signature(object):
''' '''
Class to hold signature data and generate signature regular expressions. Class to hold signature data and generate signature regular expressions.
''' '''
def __init__(self, id, first_line): def __init__(self, id, first_line):
''' '''
Class constructor. Class constructor.
...@@ -558,31 +566,37 @@ class Magic(object): ...@@ -558,31 +566,37 @@ class Magic(object):
# Some integer values have special operations that need to be performed on them # Some integer values have special operations that need to be performed on them
# before comparison (e.g., "belong&0x0000FFFF"). Complex math expressions are # before comparison (e.g., "belong&0x0000FFFF"). Complex math expressions are
# supported here as well. # supported here as well.
if isinstance(dvalue, int) and line.operator: #if isinstance(dvalue, int) and line.operator:
# If the operator value of this signature line is just an integer value, use it if line.operator:
if isinstance(line.opvalue, int): try:
opval = line.opvalue # If the operator value of this signature line is just an integer value, use it
# Else, evaluate the complex expression if isinstance(line.opvalue, int):
else: opval = line.opvalue
opval = self._do_math(offset, line.opvalue) # Else, evaluate the complex expression
else:
# Perform the specified operation opval = self._do_math(offset, line.opvalue)
if line.operator == '&':
dvalue &= opval # Perform the specified operation
elif line.operator == '|': if line.operator == '&':
dvalue |= opval dvalue &= opval
elif line.operator == '*': elif line.operator == '|':
dvalue *= opval dvalue |= opval
elif line.operator == '+': elif line.operator == '*':
dvalue += opval dvalue *= opval
elif line.operator == '-': elif line.operator == '+':
dvalue -= opval dvalue += opval
elif line.operator == '/': elif line.operator == '-':
dvalue /= opval dvalue -= opval
elif line.operator == '~': elif line.operator == '/':
dvalue = ~opval dvalue /= opval
elif line.operator == '^': elif line.operator == '~':
dvalue ^= opval dvalue = ~opval
elif line.operator == '^':
dvalue ^= opval
except KeyboardInterrupt as e:
raise e
except Exception as e:
raise ParserException("Failed to apply operator " + line.operator + " to " + dvalue + ": " + str(e))
# Does the data (dvalue) match the specified comparison? # Does the data (dvalue) match the specified comparison?
if ((line.value is None) or if ((line.value is None) or
......
...@@ -105,7 +105,41 @@ ...@@ -105,7 +105,41 @@
>4 belong x {jump:%u} >4 belong x {jump:%u}
>4 belong x {size:%u} >4 belong x {size:%u}
# Tentative UbiFS signature; needs more parsing and better validation
# http://lxr.free-electrons.com/source/fs/ubifs/ubifs-media.h
0 lelong 0x06101831 UBIFS filesystem, superblock node,
>20 ubyte !6 {invalid} # Only look for the superblock node
>4 lelong x CRC: 0x%X,
>8 lequad x sqnum: %ld,
>16 lelong x node length: %d,{size:%d}{jump:%d}
>20 ubyte x node type: %d,
>21 ubyte x group type: %d,
>22 lelong !0 invalid padding,{invalid}
>26 byte x key hash: 0x%X,
>27 byte x key format: 0x%X,
>28 lelong x flags: 0x%X,
>32 lelong x minimum I/O unit size: %d,
>36 lelong x logical erase block size: %d,
>40 lelong x number of logical erase blocks: %d,
>44 lelong x maximum number of erase blocks: %d,
>48 lelong x maximum data stored in buds: %d,
>52 lelong x erase block log size: %d,
>56 lelong x LEBs used for lprops table: %d,
>60 lelong x LEBs used for recording orphans: %d,
>64 lelong x journal head count: %d,
>68 lelong x maximum number of links per indexing node: %d,
>72 lelong x number of LEBs in LPT's save table: %d,
>76 lelong x UBIFS on-flash format version: %d,
>80 leshort x default compression type: 0x%X,
>82 leshort !0 invalid padding,{invalid}
>84 lelong x reserve pool UID: %d,
>88 lelong x reserve pool GID: %d,
>92 lequad x reserve pool size: %ld,
>100 lelong x time granularity in nanoseconds: %d,
>104 lequad x UUID: 0x%X
>112 lequad x \b%X,
>120 lelong x UBIFS R/O compatibility version: %d
>124 string !\x00*3968 invalid padding{invalid}
# JFFS2 file system # JFFS2 file system
# If used with binwalk's smart signature feature (on by default, -S to disable) # If used with binwalk's smart signature feature (on by default, -S to disable)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment