[docs]classHooksMixin(SuccessorsMixin,ProcedureMixin):""" A SimEngine mixin which adds a SimSuccessors handler which will look into the project's hooks and run the hook at the current address. Will respond to the following parameters provided to the step stack: - procedure: A SimProcedure instance to force-run instead of consulting the current hooks - ret_to: An address to force-return-to at the end of the procedure """def_lookup_hook(self,state,procedure):# TODO this is moderately controversial. If the jumpkind was NoHook and the user provided the procedure# argument, which takes precedence?# tentative guess: passed argument takes priorityifprocedureisnotNone:returnprocedure# we have at this point entered the next step - we should check the "previous" jumpkindifstate.historyandstate.history.parentandstate.history.parent.jumpkind=="Ijk_NoHook":returnNoneiftype(state._ip)isnotintandstate._ip.symbolic:# symbolic IP is not supportedreturnNoneaddr=state.addrprocedure=self.project._sim_procedures.get(addr,None)ifprocedureisnotNone:returnprocedureifnotstate.arch.name.startswith("ARM")oraddr&1!=1:returnNoneprocedure=self.project._sim_procedures.get(addr-1,None)ifprocedureisnotNone:returnprocedurereturnNone
[docs]defprocess_successors(self,successors,procedure=None,**kwargs):state=self.stateifprocedureisNone:procedure=self._lookup_hook(state,procedure)ifprocedureisNone:returnsuper().process_successors(successors,procedure=procedure,**kwargs)ifisinstance(procedure.addr,SootAddressDescriptor):l.debug("Running %s (originally at %r)",repr(procedure),procedure.addr)else:l.debug("Running %s (originally at %s)",repr(procedure),procedure.addrifprocedure.addrisNoneelsehex(procedure.addr),)returnself.process_procedure(state,successors,procedure,**kwargs)