Commit 35538acb by devttys0

Improved --disasm efficiency

parent 366a4faa
...@@ -31,7 +31,7 @@ $ sudo apt-get install libqt4-opengl python-opengl python-qt4 python-qt4-gl pyth ...@@ -31,7 +31,7 @@ $ sudo apt-get install libqt4-opengl python-opengl python-qt4 python-qt4-gl pyth
$ sudo pip install pyqtgraph $ sudo pip install pyqtgraph
``` ```
Binwalk's "Fuzzy Hashing" options requires the libfuzzy library: Binwalk's "Fuzzy Hashing" options require the libfuzzy library:
```bash ```bash
$ sudo apt-get install libfuzzy2 $ sudo apt-get install libfuzzy2
...@@ -60,7 +60,7 @@ $ (cd sasquatch && make && sudo make install) ...@@ -60,7 +60,7 @@ $ (cd sasquatch && make && sudo make install)
Bundled Software Bundled Software
================ ================
For convenience, the following libraries are bundled with binwalk and will not conflict with system-wide libraries: For convenience, the following libraries are bundled with binwalk and installed so as not to conflict with system-wide libraries:
libmagic libmagic
......
import capstone import capstone
import binwalk.core.common import binwalk.core.common
import binwalk.core.compat
from binwalk.core.module import Module, Option, Kwarg from binwalk.core.module import Module, Option, Kwarg
class Architecture(object): class Architecture(object):
...@@ -18,17 +19,17 @@ class CodeID(Module): ...@@ -18,17 +19,17 @@ class CodeID(Module):
Option(short='Y', Option(short='Y',
long='disasm', long='disasm',
kwargs={'enabled' : True}, kwargs={'enabled' : True},
description='Identify executable code using the capstone disassembler'), description='Identify the architecture of files containing executable code'),
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 instructions to be considered valid'), description='Minimum number of consecutive instructions to be considered valid (default: %d)' % DEFAULT_MIN_INSN_COUNT),
] ]
KWARGS = [ KWARGS = [
Kwarg(name='enabled', default=False), Kwarg(name='enabled', default=False),
Kwarg(name='min_insn_count', default=0), Kwarg(name='min_insn_count', default=DEFAULT_MIN_INSN_COUNT),
] ]
ARCHITECTURES = [ ARCHITECTURES = [
...@@ -89,9 +90,16 @@ class CodeID(Module): ...@@ -89,9 +90,16 @@ class CodeID(Module):
] ]
def init(self): def init(self):
self.disassemblers = []
if not self.min_insn_count: if not self.min_insn_count:
self.min_insn_count = self.DEFAULT_MIN_INSN_COUNT self.min_insn_count = self.DEFAULT_MIN_INSN_COUNT
self.disasm_data_size = self.min_insn_count * 10
for arch in self.ARCHITECTURES:
self.disassemblers.append((capstone.Cs(arch.type, (arch.mode + arch.endianess)), arch.description))
def scan_file(self, fp): def scan_file(self, fp):
total_read = 0 total_read = 0
...@@ -100,20 +108,28 @@ class CodeID(Module): ...@@ -100,20 +108,28 @@ class CodeID(Module):
if not data: if not data:
break break
offset = 0 # If this data block doesn't contain at least two different bytes, skip it
while offset < dlen: # to prevent false positives (e.g., "\x00\x00\x00x\00" is a nop in MIPS).
for arch in self.ARCHITECTURES: if len(set(data)) >= 2:
md = capstone.Cs(arch.type, (arch.mode + arch.endianess)) block_offset = 0
ninsn = len([insn for insn in md.disasm_lite(data[offset:offset+(self.min_insn_count*10)], 0)]) while block_offset < dlen:
binwalk.core.common.debug("0x%.8X %s, at least %d valid instructions" % ((total_read+offset), arch.description, ninsn)) # 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.
if ninsn >= self.min_insn_count: code_block = binwalk.core.compat.str2bytes(data[block_offset:block_offset+self.disasm_data_size])
description = arch.description + ", at least %d valid instructions" % ninsn
r = self.result(offset=total_read+offset, file=fp, description=description) # If this code block doesn't contain at least two different bytes, skip it
if r.valid and r.display and not self.config.verbose: # to prevent false positives (e.g., "\x00\x00\x00x\00" is a nop in MIPS).
return if len(set(code_block)) >= 2:
for (md, description) in self.disassemblers:
offset += 1 ninsn = len([insn for insn in md.disasm_lite(code_block, 0)])
binwalk.core.common.debug("0x%.8X %s, at least %d valid instructions" % ((total_read+block_offset), description, ninsn))
if ninsn >= self.min_insn_count:
r = self.result(offset=total_read+block_offset, file=fp, description=(description + ", at least %d valid instructions" % ninsn))
if r.valid and r.display and not self.config.verbose:
return
block_offset += 1
total_read += dlen total_read += dlen
......
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