about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2011-11-14 22:37:56 +0100
committerserpilliere <devnull@localhost>2011-11-14 22:37:56 +0100
commit4ff4f432d35d3916dee1e68fdf35da3484ce0595 (patch)
treeac6efab1a429bd3aea284448d314e4b9f9b6d5fe
parent3092083d970a1566e31d65670117150f004692fe (diff)
downloadmiasm-4ff4f432d35d3916dee1e68fdf35da3484ce0595.tar.gz
miasm-4ff4f432d35d3916dee1e68fdf35da3484ce0595.zip
fix bounding box graphic bug
-rwxr-xr-xmiasm/graph/graph_qt.py207
1 files changed, 123 insertions, 84 deletions
diff --git a/miasm/graph/graph_qt.py b/miasm/graph/graph_qt.py
index 58af430b..054c2336 100755
--- a/miasm/graph/graph_qt.py
+++ b/miasm/graph/graph_qt.py
@@ -30,6 +30,7 @@ from PyQt4.Qt import QTextCursor
 from PyQt4.Qt import QEvent
 from PyQt4.Qt import Qt
 import re
+from pprint import pprint as pp
 
 app = None
 from grandalf.graphs import *
@@ -47,8 +48,17 @@ class HighlightingRule():
         self.pattern = pattern
         self.format = format
 
+symbols_known = set()
+
+def gen_syntax_rules(symbols = []):
+    global syntax_rules, symbols_known
+
+    new_symbols = set()
+    for s in symbols.s:
+        new_symbols.add(re.escape(str(s)))
+    if new_symbols == symbols_known:
+        return syntax_rules
 
-def gen_syntax_rules():
     highlightingRules = []
     number = QtGui.QTextCharFormat()
     label = QtGui.QTextCharFormat()
@@ -70,6 +80,7 @@ def gen_syntax_rules():
     rule = HighlightingRule( pattern, number )
     highlightingRules.append( rule )
 
+    """
     #label
     brushb = QtGui.QBrush( Qt.blue, Qt.SolidPattern )
     pattern = QtCore.QRegExp( "[0-9a-zA-Z_\.]+:$" )
@@ -77,7 +88,9 @@ def gen_syntax_rules():
     label.setForeground( brushb )
     rule = HighlightingRule( pattern, label )
     highlightingRules.append( rule )
+    """
 
+    """
     #label
     brushb = QtGui.QBrush( Qt.blue, Qt.SolidPattern )
     pattern = QtCore.QRegExp( "[0-9a-zA-Z_\.]+:" )
@@ -85,11 +98,20 @@ def gen_syntax_rules():
     my_id.setForeground( brushb )
     rule = HighlightingRule( pattern, my_id )
     highlightingRules.append( rule )
+    """
+
+    for s in new_symbols:
+        brushb = QtGui.QBrush( Qt.blue, Qt.SolidPattern )
+        pattern = QtCore.QRegExp( s )
+        pattern.setMinimal( False )
+        label.setForeground( brushb )
+        rule = HighlightingRule( pattern, label )
+        highlightingRules.append( rule )
+
 
     return highlightingRules
 
 
-syntax_rules = gen_syntax_rules()
 
 
 def parse_address(ad, symbol_pool = None):
@@ -209,7 +231,6 @@ class history_mngr():
         self.history_index, out = s
         self.history_list = []
         for p in out:
-            print p
             self.history_list.append(history_point(*p))
 
     history_current = property(get_current_hist,
@@ -217,12 +238,13 @@ class history_mngr():
 
 
 class MyHighlighter( QtGui.QSyntaxHighlighter ):
-    def __init__( self, parent ):
+    def __init__( self, parent):
         QtGui.QSyntaxHighlighter.__init__( self, parent )
         self.parent = parent
 
 
         self.highlightingRules = syntax_rules
+        #self.highlightingRules = gen_syntax_rules(symbols)
 
 
 
@@ -272,6 +294,7 @@ def getTextwh_font(txt, zoom, font):
 
 
 def rename_symobl(mainwin, symbol_pool, ad):
+    global syntax_rules
     text, ok = QtGui.QInputDialog.getText(None, "miasm",
                                           'enter symbol:')
     if not ok:
@@ -298,6 +321,8 @@ def rename_symobl(mainwin, symbol_pool, ad):
     app.postEvent(mainwin,
                   e_refresh())
 
+    syntax_rules = gen_syntax_rules(symbol_pool)
+
 class graph_edge(QtGui.QGraphicsItem):
     def __init__(self, min_x, min_y, max_x, max_y, pts, color, end_angle, my_splines):
         QtGui.QGraphicsItem.__init__(self)
@@ -402,7 +427,6 @@ class node_asm_bb(QTextEdit):
         goto_ad.triggered.connect(lambda:app.postEvent(self.mainwin,e_refresh(history_mngr.hist_next, ad)))
 
         edit_name = menu.addAction("change name: "+w)
-        print "xx", self.mainwin
         edit_name.triggered.connect(lambda :rename_symobl(mainwin = self.mainwin, symbol_pool = self.mainwin.symbol_pool, ad = w))
 
 
@@ -715,9 +739,9 @@ class MainWindow(QtGui.QWidget):
         E = []
         for b in all_bloc:
             if self.label:
-                V[b.label] = Vertex(str(b.label.name) +":\n"+"\n".join(["%.8X  "%x.offset + str(x) for x in b.lines]))
+                V[b.label] = Vertex(b)#str(b.label.name) +":\n"+"\n".join(["%.8X  "%x.offset + str(x) for x in b.lines]))
             else:
-                V[b.label] = Vertex(str(b.label.name) +":\n"+"\n".join([str(x) for x in b.lines]))
+                V[b.label] = Vertex(b)#str(b.label.name) +":\n"+"\n".join([str(x) for x in b.lines]))
         for b in all_bloc:
             for c in b.bto:
                 if not isinstance(c.label, asmbloc.asm_label):
@@ -731,8 +755,9 @@ class MainWindow(QtGui.QWidget):
                 else:
                     data = QtCore.Qt.red
                 ###
+                c.color = data
                 if b.label in V and c.label in V:
-                    E.append(Edge(V[b.label], V[c.label], data = data))
+                    E.append(Edge(V[b.label], V[c.label], data = c))
         h = asmbloc.getblocby_offset(all_bloc, ad)
         if h:
             hdr = V[h.label]
@@ -757,32 +782,7 @@ class MainWindow(QtGui.QWidget):
         return hdr, g, V, E
 
 
-    def refresh_nodes(self):
-        self.view.view().current_node = None
-
-        ad = self.history_mngr.history_current.ad
-        all_bloc = self.history_mngr.history_current.all_bloc
-
-        for b in self.scene_blocs:
-            b.widget().destroy()
-            self.scene.removeItem(b)
-        self.scene_blocs = []
-        for e in self.scene_edges:
-            self.scene.removeItem(e)
-        self.scene_edges = []
-        self.scene.clear()
-        w = self.scene.width()
-        h = self.scene.height()
-        self.scene.update(0, 0, w, h)
-
-        if not all_bloc:
-            print 'DIS', hex(ad)
-            all_bloc = self.dis_callback(ad)
-            self.history_mngr.history_current.all_bloc = all_bloc
-            g = asmbloc.bloc2graph(all_bloc)
-            open("graph.txt" , "w").write(g)
-
-
+    def set_blocs_pos(self, ad, all_bloc):
         if isinstance(all_bloc, list):
             hdr, g, V, E = self.graph_from_asmbloc(ad, all_bloc)
         else:
@@ -801,9 +801,12 @@ class MainWindow(QtGui.QWidget):
                 if not data:
                     self.w, self.h = 80,40
                 else:
-                    self.data = self.data.replace('\t', ' '*4)
-                    s = self.data.split('\n')
-                    w, h = getTextwh_font(self.data, 1, mfont)
+                    txt = str(self.data.label.name) +":\n"
+                    txt += "\n".join(["%.8X  "%x.offset + str(x) for x in self.data.lines])
+                    txt = txt.replace('\t', ' '*4)
+                    self.txt = txt
+                    s = self.txt.split('\n')
+                    w, h = getTextwh_font(self.txt, 1, mfont)
                     self.h = h
                     self.w = w
 
@@ -819,8 +822,6 @@ class MainWindow(QtGui.QWidget):
         max_y = None
         max_pos_x = 0
         max_pos_y = 0
-
-
         # for all connexe parts
         for index in xrange(len(g.C)):
 
@@ -848,20 +849,19 @@ class MainWindow(QtGui.QWidget):
                 if not first_pos:
                     first_pos = pos
 
-                e = node_asm_bb(n.data, self)
-                e.h = MyHighlighter(e)
+                #e = node_asm_bb(n.data, self)
+                #e.h = MyHighlighter(e)
                 p_x = pos[0] - n.view.w/2 + max_pos_x - min_pos_x
                 p_y = pos[1] - n.view.h/2
-                e.setpos(p_x, p_y, n.view.w, n.view.h)
+                #e.setpos(p_x, p_y, n.view.w, n.view.h)
                 # set pos to all_bloc node
-                b = asmbloc.getblocby_label(all_bloc, n.view.k)
+                b = n.data
                 b.g_pos = (p_x, p_y, n.view.w, n.view.h)
-
                 if p_x + n.view.w > new_max_pos_x:
                     new_max_pos_x = p_x + n.view.w
-                wproxy = self.scene.addWidget(e)
-                self.scene_blocs.append(wproxy)
-                e.show()
+                #wproxy = self.scene.addWidget(e)
+                #self.scene_blocs.append(wproxy)
+                #e.show()
 
             for e in g.C[index].sE:
                 min_x = None
@@ -877,39 +877,83 @@ class MainWindow(QtGui.QWidget):
                     p1 = e.v[0].view.xy
                     p2 = e.v[1].view.xy
 
-                    for p in [p1, p2]:
-                        if min_x == None or p[0] < min_x:
-                            min_x = p[0]
-                        if max_x == None or p[0] > max_x:
-                            max_x = p[0]
-                        if min_y == None or p[1] < min_y:
-                            min_y = p[1]
-                        if max_y == None or p[1] > max_y:
-                            max_y = p[1]
                     pts = [p1, p2]
                 else:
-                    for p in e.view.l:
-                        x, y = p[0] + max_pos_x, p[1]
-                        p = x, y
-
-                        if min_x == None or p[0] < min_x:
-                            min_x = p[0]
-                        if max_x == None or p[0] > max_x:
-                            max_x = p[0]
-                        if min_y == None or p[1] < min_y:
-                            min_y = p[1]
-                        if max_y == None or p[1] > max_y:
-                            max_y = p[1]
                     pts = e.view.l
                 for i, p in enumerate(pts):
                     x, y = p[0] + max_pos_x - min_pos_x, p[1]
                     p = x, y
                     pts[i] = p
-                e = graph_edge(min_x, min_y, max_x, max_y, pts, e.data, end_angle, e.view.splines)
-                self.scene.addItem(e)
-                self.scene_edges.append(e)
+
+
+                    if min_x == None or p[0] < min_x:
+                        min_x = p[0]
+                    if max_x == None or p[0] > max_x:
+                        max_x = p[0]
+                    if min_y == None or p[1] < min_y:
+                        min_y = p[1]
+                    if max_y == None or p[1] > max_y:
+                        max_y = p[1]
+
+                e.data.g_pos = (min_x, min_y, max_x, max_y,
+                                pts,
+                                e.data.color, end_angle, e.view.splines)
             max_pos_x = new_max_pos_x
 
+
+    def refresh_nodes(self):
+        self.view.view().current_node = None
+
+        ad = self.history_mngr.history_current.ad
+        all_bloc = self.history_mngr.history_current.all_bloc
+
+        for b in self.scene_blocs:
+            b.widget().destroy()
+            self.scene.removeItem(b)
+        self.scene_blocs = []
+        for e in self.scene_edges:
+            self.scene.removeItem(e)
+        self.scene_edges = []
+        self.scene.clear()
+        w = self.scene.width()
+        h = self.scene.height()
+        self.scene.update(0, 0, w, h)
+
+        if not all_bloc:
+            global syntax_rules
+            print 'DIS', hex(ad)
+            all_bloc = self.dis_callback(ad)
+            syntax_rules = gen_syntax_rules(self.symbol_pool)
+            self.history_mngr.history_current.all_bloc = all_bloc
+            g = asmbloc.bloc2graph(all_bloc)
+            open("graph.txt" , "w").write(g)
+
+        # test if bloc has position already set
+        if not (all_bloc and "g_pos" in all_bloc[0].__dict__):
+            self.set_blocs_pos(ad, all_bloc)
+
+        first_pos = False
+        for b in all_bloc:
+            if not first_pos:
+                first_pos = b.g_pos[:2]
+            txt = str(b.label.name) +":\n"
+            txt += "\n".join(["%.8X  "%x.offset + str(x) for x in b.lines])
+            txt = txt.replace('\t', ' '*4)
+            e = node_asm_bb(txt, self)
+            e.h = MyHighlighter(e)
+            e.setpos(*b.g_pos)
+            wproxy = self.scene.addWidget(e)
+            self.scene_blocs.append(wproxy)
+            e.show()
+
+            for c in b.bto:
+                if not "g_pos" in c.__dict__:
+                    continue
+                g_e = graph_edge(*c.g_pos)
+                self.scene.addItem(g_e)
+                self.scene_edges.append(g_e)
+
+
         scroll_h = self.history_mngr.history_current.scroll_h
         scroll_v = self.history_mngr.history_current.scroll_v
         zoom = self.history_mngr.history_current.zoom
@@ -922,19 +966,6 @@ class MainWindow(QtGui.QWidget):
 
         if first_pos:
             self.view.view().centerOn(first_pos[0], first_pos[1])
-        '''
-        print min_x, max_x, min_y, max_y
-
-        if scroll_h == None or scroll_v == None:
-            print 'default scroll val'
-            scroll_h = 0
-            scroll_v = 0
-        '''
-        """
-        print "scroll val", scroll_h, scroll_v
-        self.view.view().horizontalScrollBar().setValue(scroll_h)
-        self.view.view().verticalScrollBar().setValue(scroll_v)
-        """
 
 
     def populateScene(self):
@@ -960,14 +991,22 @@ class e_refresh(QEvent):
 
 def graph_blocs(ad, symbol_pool, all_bloc, label = False, dis_callback = None, load_state_file = None):
     global app
+    global syntax_rules
+
+
     app = QtGui.QApplication(sys.argv)
     g = MainWindow(dis_callback = dis_callback)
 
     if load_state_file:
         g.restaure(load_state_file)
+        syntax_rules = gen_syntax_rules(g.symbol_pool)
+        # must replace original pool
+        symbol_pool.s = g.symbol_pool.s
+        symbol_pool.s_offset = g.symbol_pool.s_offset
         g.refresh_nodes()
     else:
         g.symbol_pool = symbol_pool
+        syntax_rules = gen_syntax_rules(g.symbol_pool)
         g.new_disasm(ad, all_bloc, label)
         g.refresh_nodes()
     g.show()