Commit 96761662 by devttys0

Updated disasm for reliability, updated vxworks symbol table signature

parent 76ff729a
...@@ -7,4 +7,7 @@ from binwalk.modules.extractor import Extractor ...@@ -7,4 +7,7 @@ from binwalk.modules.extractor import Extractor
from binwalk.modules.entropy import Entropy from binwalk.modules.entropy import Entropy
from binwalk.modules.heuristics import HeuristicCompressionAnalyzer from binwalk.modules.heuristics import HeuristicCompressionAnalyzer
from binwalk.modules.compression import RawCompression from binwalk.modules.compression import RawCompression
#from binwalk.modules.codeid import CodeID try:
from binwalk.modules.disasm import Disasm
except ImportError:
pass
...@@ -3,13 +3,19 @@ import binwalk.core.common ...@@ -3,13 +3,19 @@ import binwalk.core.common
import binwalk.core.compat import binwalk.core.compat
from binwalk.core.module import Module, Option, Kwarg from binwalk.core.module import Module, Option, Kwarg
class ArchResult(object):
def __init__(self, **kwargs):
for (k,v) in kwargs.iteritems():
setattr(self, k, v)
class Architecture(object): class Architecture(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):
for (k, v) in kwargs.iteritems(): for (k, v) in kwargs.iteritems():
setattr(self, k, v) setattr(self, k, v)
class CodeID(Module): class Disasm(Module):
THRESHOLD = 10
DEFAULT_MIN_INSN_COUNT = 500 DEFAULT_MIN_INSN_COUNT = 500
TITLE = "Disassembly Scan" TITLE = "Disassembly Scan"
...@@ -17,35 +23,22 @@ class CodeID(Module): ...@@ -17,35 +23,22 @@ class CodeID(Module):
CLI = [ CLI = [
Option(short='Y', Option(short='Y',
long='code', long='disasm',
kwargs={'enabled' : True}, kwargs={'enabled' : True},
description='Attempts to identify the CPU architecture of a file using the capstone disassembler'), description='Identify the CPU architecture of a file using the capstone disassembler'),
Option(short='T', Option(short='T',
long='minsn', long='minsn',
type=int, type=int,
kwargs={'min_insn_count' : 0}, kwargs={'min_insn_count' : 0},
description='Minimum number of consecutive instructions to be considered valid (default: %d)' % DEFAULT_MIN_INSN_COUNT), description='Minimum number of consecutive instructions to be considered valid (default: %d)' % DEFAULT_MIN_INSN_COUNT),
Option(short='V',
long='disasm',
kwargs={'show_disasm' : True},
description='Display the disassembled instructions'),
] ]
KWARGS = [ KWARGS = [
Kwarg(name='enabled', default=False), Kwarg(name='enabled', default=False),
Kwarg(name='show_disasm', default=False),
Kwarg(name='min_insn_count', default=DEFAULT_MIN_INSN_COUNT), Kwarg(name='min_insn_count', default=DEFAULT_MIN_INSN_COUNT),
] ]
ARCHITECTURES = [ ARCHITECTURES = [
Architecture(type=capstone.CS_ARCH_MIPS,
mode=capstone.CS_MODE_32,
endianess=capstone.CS_MODE_BIG_ENDIAN,
description="MIPS executable code, 32-bit, big endian"),
Architecture(type=capstone.CS_ARCH_MIPS,
mode=capstone.CS_MODE_32,
endianess=capstone.CS_MODE_LITTLE_ENDIAN,
description="MIPS executable code, 32-bit, little endian"),
Architecture(type=capstone.CS_ARCH_ARM, Architecture(type=capstone.CS_ARCH_ARM,
mode=capstone.CS_MODE_ARM, mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_BIG_ENDIAN, endianess=capstone.CS_MODE_BIG_ENDIAN,
...@@ -54,19 +47,29 @@ class CodeID(Module): ...@@ -54,19 +47,29 @@ class CodeID(Module):
mode=capstone.CS_MODE_ARM, mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_LITTLE_ENDIAN, endianess=capstone.CS_MODE_LITTLE_ENDIAN,
description="ARM executable code, 32-bit, little endian"), description="ARM executable code, 32-bit, little endian"),
Architecture(type=capstone.CS_ARCH_ARM64,
mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_BIG_ENDIAN,
description="ARM executable code, 64-bit, big endian"),
Architecture(type=capstone.CS_ARCH_ARM64,
mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_LITTLE_ENDIAN,
description="ARM executable code, 64-bit, little endian"),
Architecture(type=capstone.CS_ARCH_PPC, Architecture(type=capstone.CS_ARCH_PPC,
mode=capstone.CS_MODE_BIG_ENDIAN, mode=capstone.CS_MODE_BIG_ENDIAN,
endianess=capstone.CS_MODE_BIG_ENDIAN, endianess=capstone.CS_MODE_BIG_ENDIAN,
description="PPC executable code, 32/64-bit, big endian"), description="PPC executable code, 32/64-bit, big endian"),
#Architecture(type=capstone.CS_ARCH_MIPS, Architecture(type=capstone.CS_ARCH_MIPS,
# mode=capstone.CS_MODE_16, mode=capstone.CS_MODE_64,
# endianess=capstone.CS_MODE_BIG_ENDIAN, endianess=capstone.CS_MODE_BIG_ENDIAN,
# description="MIPS executable code, 16-bit, big endian"), description="MIPS executable code, 32/64-bit, big endian"),
#Architecture(type=capstone.CS_ARCH_MIPS, Architecture(type=capstone.CS_ARCH_MIPS,
# mode=capstone.CS_MODE_16, mode=capstone.CS_MODE_64,
# endianess=capstone.CS_MODE_LITTLE_ENDIAN, endianess=capstone.CS_MODE_LITTLE_ENDIAN,
# description="MIPSEL executable code, 16-bit, little endian"), description="MIPS executable code, 32/64-bit, little endian"),
Architecture(type=capstone.CS_ARCH_ARM, Architecture(type=capstone.CS_ARCH_ARM,
mode=capstone.CS_MODE_THUMB, mode=capstone.CS_MODE_THUMB,
endianess=capstone.CS_MODE_LITTLE_ENDIAN, endianess=capstone.CS_MODE_LITTLE_ENDIAN,
...@@ -75,23 +78,6 @@ class CodeID(Module): ...@@ -75,23 +78,6 @@ class CodeID(Module):
mode=capstone.CS_MODE_THUMB, mode=capstone.CS_MODE_THUMB,
endianess=capstone.CS_MODE_BIG_ENDIAN, endianess=capstone.CS_MODE_BIG_ENDIAN,
description="ARM executable code, 16-bit (Thumb), big endian"), description="ARM executable code, 16-bit (Thumb), big endian"),
Architecture(type=capstone.CS_ARCH_MIPS,
mode=capstone.CS_MODE_64,
endianess=capstone.CS_MODE_BIG_ENDIAN,
description="MIPS executable code, 64-bit, big endian"),
Architecture(type=capstone.CS_ARCH_MIPS,
mode=capstone.CS_MODE_64,
endianess=capstone.CS_MODE_LITTLE_ENDIAN,
description="MIPS executable code, 64-bit, little endian"),
Architecture(type=capstone.CS_ARCH_ARM64,
mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_BIG_ENDIAN,
description="ARM executable code, 64-bit, big endian"),
Architecture(type=capstone.CS_ARCH_ARM64,
mode=capstone.CS_MODE_ARM,
endianess=capstone.CS_MODE_LITTLE_ENDIAN,
description="ARM executable code, 64-bit, little endian"),
] ]
def init(self): def init(self):
...@@ -109,39 +95,62 @@ class CodeID(Module): ...@@ -109,39 +95,62 @@ class CodeID(Module):
total_read = 0 total_read = 0
while True: while True:
result = None
(data, dlen) = fp.read_block() (data, dlen) = fp.read_block()
if not data: if not data:
break break
# If this data block doesn't contain at least two different bytes, skip it # If this data block doesn't contain at least two different bytes, skip it
# to prevent false positives (e.g., "\x00\x00\x00x\00" is a nop in MIPS). # to prevent false positives (e.g., "\x00\x00\x00\x00" is a nop in MIPS).
if len(set(data)) >= 2: if len(set(data)) >= 2:
block_offset = 0 block_offset = 0
while block_offset < dlen:
# Loop through the entire block, or until we're pretty sure we've found some valid code in this block
while (block_offset < dlen) and (result is None or result.count < self.THRESHOLD):
# Don't pass the entire data block into disasm_lite, it's horribly inefficient # Don't pass the entire data block into disasm_lite, it's horribly inefficient
# to pass large strings around in Python. Break it up into smaller code blocks instead. # to pass large strings around in Python. Break it up into smaller code blocks instead.
code_block = binwalk.core.compat.str2bytes(data[block_offset:block_offset+self.disasm_data_size]) code_block = binwalk.core.compat.str2bytes(data[block_offset:block_offset+self.disasm_data_size])
# If this code block doesn't contain at least two different bytes, skip it # If this code block doesn't contain at least two different bytes, skip it
# to prevent false positives (e.g., "\x00\x00\x00x\00" is a nop in MIPS). # to prevent false positives (e.g., "\x00\x00\x00\x00" is a nop in MIPS).
if len(set(code_block)) >= 2: if len(set(code_block)) >= 2:
for (md, description) in self.disassemblers: for (md, description) in self.disassemblers:
insns = [insn for insn in md.disasm_lite(code_block, (total_read+block_offset))] insns = [insn for insn in md.disasm_lite(code_block, (total_read+block_offset))]
binwalk.core.common.debug("0x%.8X %s, at least %d valid instructions" % ((total_read+block_offset), description, len(insns))) binwalk.core.common.debug("0x%.8X %s, at least %d valid instructions" % ((total_read+block_offset),
description,
len(insns)))
# Did we disassemble at least self.min_insn_count instructions?
if len(insns) >= self.min_insn_count: if len(insns) >= self.min_insn_count:
r = self.result(offset=total_read+block_offset, file=fp, description=(description + ", at least %d valid instructions" % len(insns))) # If we've already found the same type of code in this block, simply update the result counter
if r.valid and r.display: if result and result.description == description:
if self.show_disasm: result.count += 1
for (position, size, mnem, opnds) in insns: if result.count >= self.THRESHOLD:
self.result(offset=position, file=fp, description="\t%s %s" % (mnem, opnds)) break
if not self.config.verbose: else:
return result = ArchResult(offset=total_read+block_offset+fp.offset,
description=description,
insns=insns,
count=1)
block_offset += 1 block_offset += 1
if result is not None:
r = self.result(offset=result.offset,
file=fp,
description=(result.description + ", at least %d valid instructions" % len(result.insns)))
if r.valid and r.display:
if self.config.verbose:
for (position, size, mnem, opnds) in result.insns:
self.result(offset=position, file=fp, description="\t\t%s %s" % (mnem, opnds))
if not self.config.keep_going:
return
total_read += dlen total_read += dlen
self.status.completed = total_read
def run(self): def run(self):
for fp in iter(self.next_file, None): for fp in iter(self.next_file, None):
......
...@@ -37,7 +37,7 @@ class General(Module): ...@@ -37,7 +37,7 @@ class General(Module):
Option(long='continue', Option(long='continue',
short='k', short='k',
kwargs={'keep_going' : True}, kwargs={'keep_going' : True},
description='Show all matches for every offset, not just the first'), description="Don't stop at the first match"),
Option(long='swap', Option(long='swap',
short='g', short='g',
type=int, type=int,
......
...@@ -584,7 +584,9 @@ ...@@ -584,7 +584,9 @@
# Signatures to identify the start of a VxWorks symbol table # Signatures to identify the start of a VxWorks symbol table
8 string \x00\x00\x05\x00\x00\x00\x00\x00 VxWorks symbol table, big endian, 8 string \x00\x00\x05\x00\x00\x00\x00\x00 VxWorks symbol table, big endian,
>4 belong 0 invalid
>4 belong x first entry: [type: function, code address: 0x%X, >4 belong x first entry: [type: function, code address: 0x%X,
>0 belong 0 invalid
>0 belong x symbol address: 0x%X]{display-once} >0 belong x symbol address: 0x%X]{display-once}
>24 belong !0x500 >24 belong !0x500
>>24 belong !0x700 >>24 belong !0x700
...@@ -600,7 +602,9 @@ ...@@ -600,7 +602,9 @@
>>>72 belong !0x900 \b, invalid >>>72 belong !0x900 \b, invalid
8 string \x00\x00\x07\x00\x00\x00\x00\x00 VxWorks symbol table, big endian, 8 string \x00\x00\x07\x00\x00\x00\x00\x00 VxWorks symbol table, big endian,
>4 belong 0 invalid
>4 belong x first entry: [type: initialized data, code address: 0x%X, >4 belong x first entry: [type: initialized data, code address: 0x%X,
>0 belong 0 invalid
>0 belong x symbol address: 0x%X]{display-once} >0 belong x symbol address: 0x%X]{display-once}
>24 belong !0x500 >24 belong !0x500
>>24 belong !0x700 >>24 belong !0x700
...@@ -616,7 +620,9 @@ ...@@ -616,7 +620,9 @@
>>>72 belong !0x900 \b, invalid >>>72 belong !0x900 \b, invalid
8 string \x00\x00\x09\x00\x00\x00\x00\x00 VxWorks symbol table, big endian, 8 string \x00\x00\x09\x00\x00\x00\x00\x00 VxWorks symbol table, big endian,
>4 belong 0 invalid
>4 belong x first entry: [type: uninitialized data, code address: 0x%X, >4 belong x first entry: [type: uninitialized data, code address: 0x%X,
>0 belong 0 invalid
>0 belong x symbol address: 0x%X]{display-once} >0 belong x symbol address: 0x%X]{display-once}
>24 belong !0x500 >24 belong !0x500
>>24 belong !0x700 >>24 belong !0x700
...@@ -632,7 +638,9 @@ ...@@ -632,7 +638,9 @@
>>>72 belong !0x900 \b, invalid >>>72 belong !0x900 \b, invalid
8 string \x00\x05\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian, 8 string \x00\x05\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian,
>4 lelong 0 invalid
>4 lelong x first entry: [type: function, code address: 0x%X, >4 lelong x first entry: [type: function, code address: 0x%X,
>0 lelong 0 invalid
>0 lelong x symbol address: 0x%X]{display-once} >0 lelong x symbol address: 0x%X]{display-once}
>24 lelong !0x500 >24 lelong !0x500
>>24 lelong !0x700 >>24 lelong !0x700
...@@ -648,7 +656,9 @@ ...@@ -648,7 +656,9 @@
>>>72 lelong !0x900 \b, invalid >>>72 lelong !0x900 \b, invalid
8 string \x00\x07\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian, 8 string \x00\x07\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian,
>4 lelong 0 invalid
>4 lelong x first entry: [type: initialized data, code address: 0x%X, >4 lelong x first entry: [type: initialized data, code address: 0x%X,
>0 lelong 0 invalid
>0 lelong x symbol address: 0x%X]{display-once} >0 lelong x symbol address: 0x%X]{display-once}
>24 lelong !0x500 >24 lelong !0x500
>>24 lelong !0x700 >>24 lelong !0x700
...@@ -664,7 +674,9 @@ ...@@ -664,7 +674,9 @@
>>>72 lelong !0x900 \b, invalid >>>72 lelong !0x900 \b, invalid
8 string \x00\x09\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian, 8 string \x00\x09\x00\x00\x00\x00\x00\x00 VxWorks symbol table, little endian,
>4 lelong 0 invalid
>4 lelong x first entry: [type: uninitialized data, code address: 0x%X, >4 lelong x first entry: [type: uninitialized data, code address: 0x%X,
>0 lelong 0 invalid
>0 lelong x symbol address: 0x%X]{display-once} >0 lelong x symbol address: 0x%X]{display-once}
>24 lelong !0x500 >24 lelong !0x500
>>24 lelong !0x700 >>24 lelong !0x700
......
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