Commit 7c3ba831 by devttys0

Fixed bugs in opcode module

parent ff54c6ff
...@@ -300,7 +300,7 @@ class Module(object): ...@@ -300,7 +300,7 @@ class Module(object):
self.results.append(r) self.results.append(r)
# Update the progress status automatically if it is not being done manually by the module # Update the progress status automatically if it is not being done manually by the module
if r.offset and self.AUTO_UPDATE_STATUS: if r.offset and r.file and self.AUTO_UPDATE_STATUS:
self.status.total = r.file.length self.status.total = r.file.length
self.status.completed = r.offset self.status.completed = r.offset
......
...@@ -32,6 +32,7 @@ class Instruction(object): ...@@ -32,6 +32,7 @@ class Instruction(object):
class Disassembler(object): class Disassembler(object):
MIN_INSTRUCTION_COUNT = 6
INSTRUCTION_SIZE = 4 INSTRUCTION_SIZE = 4
OPCODE_INDEX = 0 OPCODE_INDEX = 0
OPCODE_MASK = 0 OPCODE_MASK = 0
...@@ -96,7 +97,6 @@ class ARM(ARMEB): ...@@ -96,7 +97,6 @@ class ARM(ARMEB):
class OpcodeValidator(Module): class OpcodeValidator(Module):
MIN_INS_COUNT = 6
MIN_CONFIDENCE = 0.0 MIN_CONFIDENCE = 0.0
TITLE = 'Opcode' TITLE = 'Opcode'
...@@ -143,11 +143,14 @@ class OpcodeValidator(Module): ...@@ -143,11 +143,14 @@ class OpcodeValidator(Module):
for disassembler in self.search(fp): for disassembler in self.search(fp):
if not self.config.verbose and disassembler.confidence > self.MIN_CONFIDENCE: if not self.config.verbose and disassembler.confidence > self.MIN_CONFIDENCE:
desc = disassembler.__class__.__name__ + " executable code, endianess: " + disassembler.ENDIANESS desc = self.build_description_string(disassembler)
self.result(description=desc, confidence=disassembler.confidence, file=fp, plot=False) self.result(description=desc, confidence=disassembler.confidence, file=fp, plot=False)
self.footer() self.footer()
def build_description_string(self, disassembler):
return disassembler.__class__.__name__ + " executable code, endianess: " + disassembler.ENDIANESS
def is_valid_sequence(self, disassembler, data): def is_valid_sequence(self, disassembler, data):
j = 0 j = 0
retval = True retval = True
...@@ -167,42 +170,50 @@ class OpcodeValidator(Module): ...@@ -167,42 +170,50 @@ class OpcodeValidator(Module):
return retval return retval
def search(self, fp): def search(self, fp):
winners = {}
results = {}
total_hits = {}
offset_range = range(0, 4)
for i in offset_range:
total_hits[i] = 0
for disassembler in self.disassemblers:
results[disassembler] = {}
for i in offset_range:
results[disassembler][i] = 0
while True: while True:
i = 0 offset = 0
(data, dlen) = fp.read_block() (data, dlen) = fp.read_block()
if not data: if not data:
break break
while i < dlen: while i < dlen:
count = 1 for j in offset_range:
offset = i + j
for disassembler in get_keys(self.disassemblers):
if self.honor_instruction_alignment and (i % disassembler.INSTRUCTION_SIZE): for disassembler in self.disassemblers:
continue if self.honor_instruction_alignment and (offset % disassembler.INSTRUCTION_SIZE):
continue
ins = disassembler.disassemble(data[i:i+disassembler.INSTRUCTION_SIZE])
if ins.valid: ins = disassembler.disassemble(data[offset:offset+disassembler.INSTRUCTION_SIZE])
sequence_size = self.MIN_INS_COUNT * disassembler.INSTRUCTION_SIZE if ins.valid:
sequence = data[i:i+sequence_size] sequence_size = disassembler.MIN_INSTRUCTION_COUNT * disassembler.INSTRUCTION_SIZE
if self.is_valid_sequence(disassembler, data[offset:offset+sequence_size]):
if len(sequence) == sequence_size and self.is_valid_sequence(disassembler, sequence): desc = self.build_description_string(disassembler)
self.result(description=disassembler.__class__.__name__ + " instructions, endianess: " + disassembler.ENDIANESS, self.result(description=desc, offset=offset, file=fp, display=self.config.verbose)
offset=(fp.total_read - dlen + i), results[disassembler][j] += 1
file=fp, total_hits[j] += 1
display=self.config.verbose)
i += len(offset_range)
self.disassemblers[disassembler] += 1
count = disassembler.INSTRUCTION_SIZE * self.MIN_INS_COUNT for (disassembler, offset_results) in iterator(results):
break sorted_offsets = sorted(offset_results, key=offset_results.get, reverse=True)
i += count winning_offset = sorted_offsets[0]
if total_hits[winning_offset] > 0 and offset_results[winning_offset] > 0:
total_hits = 0 disassembler.confidence = ((offset_results[winning_offset] / float(total_hits[winning_offset])) * 100)
winners[disassembler] = disassembler.confidence
for (k, v) in iterator(self.disassemblers):
total_hits += v return sorted(winners, key=winners.get, reverse=True)
for (k, v) in iterator(self.disassemblers):
k.confidence = ((v / float(total_hits)) * 100)
return sorted(self.disassemblers, key=self.disassemblers.get, reverse=True)
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