about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/ida/depgraph.py13
-rw-r--r--example/ida/graph_ir.py19
-rw-r--r--miasm2/analysis/depgraph.py33
-rw-r--r--test/analysis/depgraph.py6
4 files changed, 39 insertions, 32 deletions
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 406f7200..1784b4e4 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -132,9 +132,11 @@ for bloc in blocs:
 
 # Simplify affectations
 for irb in ir_arch.blocs.values():
-    for irs in irb.irs:
-        for i, expr in enumerate(irs):
-            irs[i] = m2_expr.ExprAff(expr_simp(expr.dst), expr_simp(expr.src))
+    for assignblk in irb.irs:
+        for dst, src in assignblk.items():
+            del(assignblk[dst])
+            dst, src = expr_simp(dst), expr_simp(src)
+            assignblk[dst] = src
 
 # Get settings
 settings = depGraphSettingsForm(ir_arch)
@@ -183,7 +185,10 @@ def treat_element():
         comments[offset] = comments.get(offset, []) + [node.element]
         SetColor(offset, CIC_ITEM, settings.color)
 
-    print "Possible value: %s" % graph.emul().values()[0]
+    if graph.has_loop:
+        print 'Graph has dependency loop: symbolic execution is inexact'
+    else:
+        print "Possible value: %s" % graph.emul().values()[0]
 
     for offset, elements in comments.iteritems():
         MakeComm(offset, ", ".join(map(str, elements)))
diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py
index 4447cadd..188c8fa6 100644
--- a/example/ida/graph_ir.py
+++ b/example/ida/graph_ir.py
@@ -19,10 +19,11 @@ def color_irbloc(irbloc):
     lbl = '%s' % irbloc.label
     lbl = idaapi.COLSTR(lbl, idaapi.SCOLOR_INSN)
     o.append(lbl)
-    for i, expr in enumerate(irbloc.irs):
-        for e in expr:
-            s = expr2colorstr(ir_arch.arch.regs.all_regs_ids, e)
-            s = idaapi.COLSTR(s, idaapi.SCOLOR_INSN)
+    for assignblk in irbloc.irs:
+        for dst, src in sorted(assignblk.iteritems()):
+            dst_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, dst)
+            src_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, src)
+            s = idaapi.COLSTR("%s = %s" % (dst_f, src_f), idaapi.SCOLOR_INSN)
             o.append('    %s' % s)
         o.append("")
     o.pop()
@@ -119,7 +120,7 @@ print hex(ad)
 ab = mdis.dis_multibloc(ad)
 
 print "generating graph"
-open('asm_flow.dot', 'w').write(ab.graph.dot(label=True))
+open('asm_flow.dot', 'w').write(ab.dot())
 
 
 print "generating IR... %x" % ad
@@ -133,9 +134,11 @@ for b in ab:
 print "IR ok... %x" % ad
 
 for irb in ir_arch.blocs.values():
-    for irs in irb.irs:
-        for i, expr in enumerate(irs):
-            irs[i] = ExprAff(expr_simp(expr.dst), expr_simp(expr.src))
+    for assignblk in irb.irs:
+        for dst, src in assignblk.items():
+            del(assignblk[dst])
+            dst, src = expr_simp(dst), expr_simp(src)
+            assignblk[dst] = src
 
 out = ir_arch.graph.dot()
 open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index 434a1a5a..44d33f36 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -302,7 +302,7 @@ class DependencyResultImplicit(DependencyResult):
     unsat_expr = m2_expr.ExprAff(m2_expr.ExprInt(0, 1),
                                  m2_expr.ExprInt(1, 1))
 
-    def gen_path_constraints(self, translator, expr, expected):
+    def _gen_path_constraints(self, translator, expr, expected):
         """Generate path constraint from @expr. Handle special case with
         generated labels
         """
@@ -366,7 +366,7 @@ class DependencyResultImplicit(DependencyResult):
                 expected = symb_exec.eval_expr(m2_expr.ExprId(next_label,
                                                               size))
                 solver.add(
-                    self.gen_path_constraints(translator, dst, expected))
+                    self._gen_path_constraints(translator, dst, expected))
         # Save the solver
         self._solver = solver
 
@@ -543,23 +543,23 @@ class DependencyGraph(object):
         out.update(set(FollowExpr(False, expr) for expr in nofollow))
         return out
 
-    def _track_exprs(self, state, irs, line_nb):
-        """Track pending expression in an affblock"""
+    def _track_exprs(self, state, assignblk, line_nb):
+        """Track pending expression in an assignblock"""
         future_pending = {}
         node_resolved = set()
-        for expr in irs:
+        for dst, src in assignblk.iteritems():
             # Only track pending
-            if expr.dst not in state.pending:
+            if dst not in state.pending:
                 continue
             # Track IRDst in implicit mode only
-            if expr.dst == self._ira.IRDst and not self._implicit:
+            if dst == self._ira.IRDst and not self._implicit:
                 continue
-            assert expr.dst not in node_resolved
-            node_resolved.add(expr.dst)
-            dependencies = self._follow_apply_cb(expr.src)
+            assert dst not in node_resolved
+            node_resolved.add(dst)
+            dependencies = self._follow_apply_cb(src)
 
-            state.link_element(expr.dst, line_nb)
-            state.link_dependencies(expr.dst, line_nb,
+            state.link_element(dst, line_nb)
+            state.link_dependencies(dst, line_nb,
                                     dependencies, future_pending)
 
         # Update pending nodes
@@ -567,15 +567,14 @@ class DependencyGraph(object):
         state.add_pendings(future_pending)
 
     def _compute_intrablock(self, state):
-        """Resolve the dependencies of nodes in @depdict.pending inside
-        @depdict.label until a fixed point is reached.
-        @depdict: DependencyDict to update"""
+        """Follow dependencies tracked in @state in the current irbloc
+        @state: instance of DependencyState"""
 
         irb = self._ira.blocs[state.label]
         line_nb = len(irb.irs) if state.line_nb is None else state.line_nb
 
-        for cur_line_nb, irs in reversed(list(enumerate(irb.irs[:line_nb]))):
-            self._track_exprs(state, irs, cur_line_nb)
+        for cur_line_nb, assignblk in reversed(list(enumerate(irb.irs[:line_nb]))):
+            self._track_exprs(state, assignblk, cur_line_nb)
 
     def get(self, label, elements, line_nb, heads):
         """Compute the dependencies of @elements at line number @line_nb in
diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py
index d488d995..f1d9151c 100644
--- a/test/analysis/depgraph.py
+++ b/test/analysis/depgraph.py
@@ -134,13 +134,13 @@ def bloc2graph(irgraph, label=False, lines=True):
             label_attr, label_name)
         block_html_lines = []
         if lines and irblock is not None:
-            for exprs in irblock.irs:
-                for expr in exprs:
+            for assignblk in irblock.irs:
+                for dst, src in assignblk.iteritems():
                     if False:
                         out_render = "%.8X</td><td %s> " % (0, td_attr)
                     else:
                         out_render = ""
-                    out_render += escape_chars.sub(fix_chars, str(expr))
+                    out_render += escape_chars.sub(fix_chars, "%s = %s" % (dst, src))
                     block_html_lines.append(out_render)
                 block_html_lines.append(" ")
             block_html_lines.pop()