diff options
| -rw-r--r-- | miasm2/analysis/dse.py | 36 | ||||
| -rw-r--r-- | miasm2/arch/ppc/arch.py | 8 | ||||
| -rw-r--r-- | miasm2/arch/ppc/sem.py | 23 |
3 files changed, 42 insertions, 25 deletions
diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py index d97897d8..38c9aeaf 100644 --- a/miasm2/analysis/dse.py +++ b/miasm2/analysis/dse.py @@ -484,6 +484,7 @@ class DSEPathConstraint(DSEEngine): self._known_solutions = set() # set of solution identifiers self.z3_trans = Translator.to_language("z3") self._produce_solution_strategy = produce_solution + self._previous_addr = None self._history = None if produce_solution == self.PRODUCE_SOLUTION_PATH_COV: self._history = [] # List of addresses in the current path @@ -493,6 +494,10 @@ class DSEPathConstraint(DSEEngine): snap["new_solutions"] = {dst: src.copy for dst, src in self.new_solutions.iteritems()} snap["cur_constraints"] = self.cur_solver.assertions() + if self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV: + snap["_history"] = list(self._history) + elif self._produce_solution_strategy == self.PRODUCE_SOLUTION_BRANCH_COV: + snap["_previous_addr"] = self._previous_addr return snap def restore_snapshot(self, snapshot, keep_known_solutions=True, **kwargs): @@ -507,6 +512,10 @@ class DSEPathConstraint(DSEEngine): self.cur_solver.add(snapshot["cur_constraints"]) if not keep_known_solutions: self._known_solutions.clear() + if self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV: + self._history = list(snapshot["_history"]) + elif self._produce_solution_strategy == self.PRODUCE_SOLUTION_BRANCH_COV: + self._previous_addr = snapshot["_previous_addr"] def _key_for_solution_strategy(self, destination): """Return the associated identifier for the current solution strategy""" @@ -521,8 +530,7 @@ class DSEPathConstraint(DSEEngine): elif self._produce_solution_strategy == self.PRODUCE_SOLUTION_BRANCH_COV: # Decision based on branch coverage # -> produce a solution if the current branch has never been take - cur_addr = ExprInt(self.jitter.pc, self.ir_arch.IRDst.size) - key = (cur_addr, destination) + key = (self._previous_addr, destination) elif self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV: # Decision based on path coverage @@ -553,17 +561,28 @@ class DSEPathConstraint(DSEEngine): self.new_solutions[key] = model self._known_solutions.add(key) - def handle(self, cur_addr): - # Update history if needed + def handle_correct_destination(self, destination, path_constraints): + """[DEV] Called by handle() to update internal structures giving the + correct destination (the concrete execution one). + """ + + # Update structure used by produce_solution() if self._produce_solution_strategy == self.PRODUCE_SOLUTION_PATH_COV: - self._history.append(cur_addr) + self._history.append(destination) + elif self._produce_solution_strategy == self.PRODUCE_SOLUTION_BRANCH_COV: + self._previous_addr = destination + + # Update current solver + for cons in path_constraints: + self.cur_solver.add(self.z3_trans.from_expr(cons)) + def handle(self, cur_addr): symb_pc = self.eval_expr(self.ir_arch.IRDst) possibilities = possible_values(symb_pc) + cur_path_constraint = set() # path_constraint for the concrete path if len(possibilities) == 1: assert next(iter(possibilities)).value == cur_addr else: - cur_path_constraint = set() # path_constraint for the concrete path for possibility in possibilities: path_constraint = set() # Set of ExprAff for the possible path @@ -622,6 +641,5 @@ class DSEPathConstraint(DSEEngine): self.handle_solution(model, possibility.value) self.cur_solver.pop() - # Update current solver - for cons in cur_path_constraint: - self.cur_solver.add(self.z3_trans.from_expr(cons)) + self.handle_correct_destination(cur_addr, cur_path_constraint) + diff --git a/miasm2/arch/ppc/arch.py b/miasm2/arch/ppc/arch.py index d47c2aad..87147f1c 100644 --- a/miasm2/arch/ppc/arch.py +++ b/miasm2/arch/ppc/arch.py @@ -115,7 +115,7 @@ class instruction_ppc(instruction): name = name[:-2] + 'A' if name[-2:] != 'LR' and name[-3:] != 'CTR': - if self.is_conditional_jump(name): + if len(self.args) == 2: address_index = 1 else: address_index = 0 @@ -144,7 +144,7 @@ class instruction_ppc(instruction): return [ LR ] elif 'CTR' in self.name: return [ CTR ] - elif self.is_conditional_jump(self.name): + elif len(self.args) == 2: address_index = 1 else: address_index = 0 @@ -462,9 +462,7 @@ def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True): return mnem def ppc_all_bo_bi(): - yield 20, 0 - - for bo in [0, 2, 4, 8, 10, 12, 16, 18]: + for bo in [0, 2, 4, 8, 10, 12, 16, 18, 20]: for bi in xrange(4): yield bo, bi diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py index 4434efa7..4923e3a8 100644 --- a/miasm2/arch/ppc/sem.py +++ b/miasm2/arch/ppc/sem.py @@ -428,7 +428,7 @@ def mn_do_nand(ir, instr, ra, rs, rb): def mn_do_neg(ir, instr, rd, ra): rvalue = -ra - ret = [ ExprAff(ra, rvalue) ] + ret = [ ExprAff(rd, rvalue) ] has_o = False over_expr = None @@ -684,16 +684,17 @@ def mn_do_xor(ir, instr, ra, rs, rb): return ret, [] -@sbuild.parse -def mn_b(arg1): - PC = arg1 - ir.IRDst = arg1 - -@sbuild.parse -def mn_bl(arg1): - LR = ExprId(ir.get_next_instr(instr), 32) - PC = arg1 - ir.IRDst = arg1 +def mn_b(ir, instr, arg1, arg2 = None): + if arg2 is not None: + arg1 = arg2 + return [ ExprAff(PC, arg1), ExprAff(ir.IRDst, arg1) ], [] + +def mn_bl(ir, instr, arg1, arg2 = None): + if arg2 is not None: + arg1 = arg2 + return [ ExprAff(LR, ExprId(ir.get_next_instr(instr), 32)), + ExprAff(PC, arg1), + ExprAff(ir.IRDst, arg1) ], [] def mn_get_condition(instr): bit = instr.additional_info.bi & 0b11 |