Skip to content

Commit

Permalink
Decode instruction early (#205)
Browse files Browse the repository at this point in the history
* Move PC verification to decode_instruction

* Decode instruction in executor

* Fix unicorn tests

* remove decoded_pc

* use issymbolic()
  • Loading branch information
yan committed May 4, 2017
1 parent 93f9d77 commit 64d1ed5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
34 changes: 21 additions & 13 deletions manticore/core/cpu/abstractcpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,20 @@ def _wrap_operands(self, operands):

def decode_instruction(self, pc):
'''
This will decode an instruction from memory pointed by @pc
This will decode an instruction from memory pointed by `pc` and store
it in self.instruction.
:param int pc: address of the instruction
'''
#No dynamic code!!! #TODO!
#Check if instruction was already decoded
# No dynamic code!!! #TODO!

if issymbolic(pc):
raise SymbolicPCException()

if not self.memory.access_ok(pc,'x'):
raise InvalidPCException(pc)

#Check if instruction was already decoded
self._instruction_cache = {}
if pc in self._instruction_cache:
logger.debug("Intruction cache hit at %x", pc)
Expand Down Expand Up @@ -394,16 +402,16 @@ def decode_instruction(self, pc):
#PC points to symbolic memory
if instruction.size > len(text):
logger.info("Trying to execute instructions from invalid memory")
raise InvalidPCException(self.PC)
raise InvalidPCException(pc)

if not self.memory.access_ok(slice(pc, pc+instruction.size), 'x'):
logger.info("Trying to execute instructions from non-executable memory")
raise InvalidPCException(self.PC)
raise InvalidPCException(pc)

instruction.operands = self._wrap_operands(instruction.operands)

self._instruction_cache[pc] = instruction
return instruction
self.instruction = instruction


#######################################
Expand All @@ -416,15 +424,15 @@ def canonicalize_instruction_name(self, instruction):
pass

def execute(self):
''' Decode, and execute one instruction pointed by register PC'''
if not isinstance(self.PC, (int,long)):
raise SymbolicPCException()
'''
Decode, and execute one instruction pointed by register PC
'''

if not self.memory.access_ok(self.PC,'x'):
raise InvalidPCException(self.PC)
# Decode the instruction if it wasn't explicitly decoded
if self.instruction is None or self.instruction.address != self.PC:
self.decode_instruction(self.PC)

instruction = self.decode_instruction(self.PC)
self.instruction = instruction #FIX
instruction = self.instruction

name = self.canonicalize_instruction_name(instruction)

Expand Down
3 changes: 3 additions & 0 deletions manticore/core/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ def run(self):

# allow us to terminate manticore processes
while not self.isShutdown():
# Make sure current instruction is decoded so that hooks can access it
current_state.cpu.decode_instruction(current_state.cpu.PC)

# Announce that we're about to execute
self.will_execute_pc(current_state)

Expand Down
4 changes: 2 additions & 2 deletions tests/test_unicorn.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def assemble(asm):

def emulate_next(cpu):
'Read the next instruction and emulate it with Unicorn '
instruction = cpu.decode_instruction(cpu.PC)
cpu.decode_instruction(cpu.PC)
emu = UnicornEmulator(cpu)
emu.emulate(instruction)
emu.emulate(cpu.instruction)


def itest(asm):
Expand Down

0 comments on commit 64d1ed5

Please sign in to comment.