diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2016-03-18 16:28:45 +0100 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2016-03-21 15:09:22 +0100 |
| commit | 3c1360202b6da4c32f8db350fb4b75060df88dcb (patch) | |
| tree | 759695699885ffe1a11a81a16c4070b9b261b8af | |
| parent | 02935e7796b6fa185feb439315bcf7bb31015af9 (diff) | |
| download | miasm-3c1360202b6da4c32f8db350fb4b75060df88dcb.tar.gz miasm-3c1360202b6da4c32f8db350fb4b75060df88dcb.zip | |
DependencyGraph: emul minimum effects
| -rw-r--r-- | miasm2/analysis/depgraph.py | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py index 44d33f36..aec159aa 100644 --- a/miasm2/analysis/depgraph.py +++ b/miasm2/analysis/depgraph.py @@ -5,7 +5,7 @@ from miasm2.core.graph import DiGraph from miasm2.core.asmbloc import asm_label, expr_is_int_or_label, expr_is_label from miasm2.expression.simplifications import expr_simp from miasm2.ir.symbexec import symbexec -from miasm2.ir.ir import irbloc +from miasm2.ir.ir import irbloc, AssignBlock from miasm2.ir.translators import Translator from miasm2.expression.expression_helper import possible_values @@ -258,6 +258,29 @@ class DependencyResult(DependencyState): len(set(self.relevant_labels))) return self._has_loop + def irblock_slice(self, irb): + """Slice of the dependency nodes on the irblock @irb + @irb: irbloc instance + """ + + assignblks = [] + line2elements = {} + for depnode in self.relevant_nodes: + if depnode.label != irb.label: + continue + line2elements.setdefault(depnode.line_nb, + set()).add(depnode.element) + + for line_nb, elements in sorted(line2elements.iteritems()): + assignblk = AssignBlock() + for element in elements: + if element in irb.irs[line_nb]: + # constants, label, ... are not in destination + assignblk[element] = irb.irs[line_nb][element] + assignblks.append(assignblk) + + return irbloc(irb.label, assignblks) + def emul(self, ctx=None, step=False): """Symbolic execution of relevant nodes according to the history Return the values of inputs nodes' elements @@ -270,21 +293,16 @@ class DependencyResult(DependencyState): ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) - depnodes = self.relevant_nodes - affects = [] + assignblks = [] # Build a single affectation block according to history for label in self.relevant_labels[::-1]: - affected_lines = set(depnode.line_nb for depnode in depnodes - if depnode.label == label) - irs = self._ira.blocs[label].irs - for line_nb in sorted(affected_lines): - affects.append(irs[line_nb]) + assignblks += self.irblock_slice(self._ira.blocs[label]).irs # Eval the block temp_label = asm_label("Temp") symb_exec = symbexec(self._ira, ctx_init) - symb_exec.emulbloc(irbloc(temp_label, affects), step=step) + symb_exec.emulbloc(irbloc(temp_label, assignblks), step=step) # Return only inputs values (others could be wrongs) return {element: symb_exec.symbols[element] @@ -338,27 +356,18 @@ class DependencyResultImplicit(DependencyResult): ctx_init = self._ira.arch.regs.regs_init if ctx is not None: ctx_init.update(ctx) - depnodes = self.relevant_nodes solver = z3.Solver() symb_exec = symbexec(self._ira, ctx_init) - temp_label = asm_label("Temp") history = self.history[::-1] history_size = len(history) translator = Translator.to_language("z3") size = self._ira.IRDst.size for hist_nb, label in enumerate(history): - # Build block with relevant lines only - affected_lines = set(depnode.line_nb for depnode in depnodes - if depnode.label == label) - irs = self._ira.blocs[label].irs - affects = [] - - for line_nb in sorted(affected_lines): - affects.append(irs[line_nb]) + irb = self.irblock_slice(self._ira.blocs[label]) # Emul the block and get back destination - dst = symb_exec.emulbloc(irbloc(temp_label, affects), step=step) + dst = symb_exec.emulbloc(irb, step=step) # Add constraint if hist_nb + 1 < history_size: |