SHARE
TWEET

Xrefs Graph

a guest Jun 5th, 2011 521 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from idaapi import Form
  2. from idaapi import GraphViewer
  3. import re
  4.  
  5. def getText(ea):
  6.     t=GetFunctionName(ea)
  7.     if t=='':
  8.         t='%s:%x: %s'%(SegName(ea),ea,GetDisasm(ea))
  9.     return t
  10.  
  11. class Xrefs:
  12.     def __init__(self,ea,max_depth=1,regexp=None):
  13.         self.xrefs_to={}
  14.         self.xrefs_from={}
  15.         self.ea=ea
  16.         self.max_depth=max_depth
  17.         self.regexp=regexp            
  18.  
  19.     def _recGetXrefsTo(self,ea,depth=1):
  20.         found=False
  21.         self.xrefs_to[ea]=[]
  22.         for xref in XrefsTo(ea,idaapi.XREF_FAR):
  23.             if not xref.iscode:
  24.                 continue
  25.             x=xref.frm
  26.             f=idaapi.get_func(x)
  27.             if f:
  28.                 x=f.startEA
  29.             if x in self.xrefs_to[ea]:
  30.                 continue
  31.             t=getText(x)
  32.             if self.regexp!=None:
  33.                 if re.search(self.regexp,t)!=None:
  34.                     self.xrefs_to[ea].append(x)
  35.                     found=True
  36.                     continue
  37.                 if f and depth<self.max_depth \
  38.                     and x not in self.xrefs_to \
  39.                     and self._recGetXrefsTo(x,depth+1)==True:
  40.                     self.xrefs_to[ea].append(x)
  41.                     found=True
  42.             else:
  43.                 self.xrefs_to[ea].append(x)
  44.                 if f and depth<self.max_depth and x not in self.xrefs_to:
  45.                     self._recGetXrefsTo(x,depth+1)
  46.         return found
  47.  
  48.     def getXrefsTo(self):
  49.         self.xrefs_to={}
  50.         f=idaapi.get_func(self.ea)
  51.         if f:
  52.             self._recGetXrefsTo(f.startEA)
  53.         return self.xrefs_to
  54.  
  55.     def _recGetXrefsFrom(self,ea,depth=1):
  56.         found=False
  57.         self.xrefs_from[ea]=[]
  58.         for x in [x for x in FuncItems(ea) if idaapi.is_call_insn(x)]:
  59.             for xref in XrefsFrom(x,idaapi.XREF_FAR):
  60.                 if not xref.iscode:
  61.                     continue
  62.                 if xref.to in self.xrefs_from[ea]:
  63.                     continue
  64.                 t=getText(xref.to)
  65.                 if self.regexp!=None:
  66.                     if re.search(self.regexp,t)!=None:
  67.                         self.xrefs_from[ea].append(xref.to)
  68.                         found=True
  69.                         continue
  70.                     if depth<self.max_depth and xref.to not in self.xrefs_from \
  71.                         and self._recGetXrefsFrom(xref.to,depth+1)==True:
  72.                         self.xrefs_from[ea].append(xref.to)
  73.                         found=True
  74.                 else:
  75.                     self.xrefs_from[ea].append(xref.to)
  76.                     if depth<self.max_depth and xref.to not in self.xrefs_from:
  77.                         self._recGetXrefsFrom(xref.to,depth+1)
  78.         return found
  79.  
  80.     def getXrefsFrom(self):
  81.         self.xrefs_from={}
  82.         f=idaapi.get_func(self.ea)
  83.         if f:
  84.             self._recGetXrefsFrom(f.startEA)
  85.         return self.xrefs_from
  86.        
  87. class XrefsGraph(GraphViewer):
  88.     def __init__(self,title,ea,xrefs_to,xrefs_from):
  89.         GraphViewer.__init__(self,title)
  90.         self.xrefs_to=xrefs_to
  91.         self.xrefs_from=xrefs_from
  92.  
  93.     def OnRefresh(self):
  94.         self.Clear()
  95.         nodes={}
  96.         for ea in self.xrefs_to:
  97.             if len(self.xrefs_to[ea])==0:
  98.                 continue
  99.             if ea not in nodes:
  100.                 nodes[ea]=self.AddNode(ea)
  101.             for x in self.xrefs_to[ea]:
  102.                 if x not in nodes:
  103.                     nodes[x]=self.AddNode(x)
  104.                 self.AddEdge(nodes[x],nodes[ea])
  105.         for ea in self.xrefs_from:
  106.             if len(self.xrefs_from[ea])==0:
  107.                 continue
  108.             if ea not in nodes:
  109.                 nodes[ea]=self.AddNode(ea)
  110.             for x in self.xrefs_from[ea]:
  111.                 if x not in nodes:
  112.                     nodes[x]=self.AddNode(x)
  113.                 self.AddEdge(nodes[ea],nodes[x])
  114.         return True
  115.  
  116.     def OnGetText(self,node_id):
  117.         return getText(self[node_id])
  118.  
  119.     def OnDblClick(self,node_id):
  120.         ea=self[node_id]
  121.         idc.Jump(ea)
  122.         return True
  123.  
  124. class XrefsForm(Form):
  125.     def __init__(self):
  126.         Form.__init__(self,r"""STARTITEM {id:iAddr}
  127. BUTTON YES* Yes
  128. BUTTON NO Nope
  129. BUTTON CANCEL Nevermind
  130. Xrefs Graph
  131.  
  132. {FormChangeCb}
  133. <#Address must be within a function#Enter an address:{iAddr}>
  134.  
  135. Directions:
  136. <Cross references from:{rFrom}>
  137. <Cross references to:{rTo}>{cGroupDirections}>
  138.  
  139. Options:
  140. <Recursion:{rRecursion}>
  141. <Include data references (NOT USED YET):{rDrefs}>
  142. <Apply regular expression filter:{rRegexp}>
  143. <Display recursion dots (NOT USED YET):{rDots}>
  144. <Display comments (NOT USED YET):{rComments}>{cGroupOptions}>
  145.  
  146. <##Recursion depth:{iDepth}>
  147. <##Regular expression:{iRegexp}>
  148. """, {
  149.     'iAddr': Form.NumericInput(tp=Form.FT_ADDR),
  150.     'cGroupDirections': Form.ChkGroupControl(('rFrom','rTo')),
  151.     'cGroupOptions': Form.ChkGroupControl(('rRecursion',
  152.                                            'rDrefs',
  153.                                            'rRegexp',
  154.                                            'rDots',
  155.                                            'rComments')),
  156.     'iDepth': Form.NumericInput(tp=Form.FT_UINT64),
  157.     'iRegexp': Form.StringInput(),
  158.     'FormChangeCb': Form.FormChangeCb(self.OnFormChange)
  159.     })
  160.  
  161.     def OnFormChange(self,fid):
  162.         print('>>fid=%d'%(fid))
  163.         return 1
  164.  
  165. def main():
  166.     f=XrefsForm()
  167.     f.Compile()
  168.     f.iAddr.value=here()
  169.     f.iDepth.value=4
  170.     f.cGroupDirections.value=3
  171.     f.cGroupOptions.value=3
  172.     ok=f.Execute()
  173.     print('>>ok=%d'%(ok))
  174.     if ok==1:
  175.         print('f.cGroupDirections.value=%x'%(f.cGroupDirections.value))
  176.         print('f.cGroupOptions.value=%x'%(f.cGroupOptions.value))
  177.         ea=f.iAddr.value
  178.         max_depth=f.iDepth.value
  179.         if f.cGroupOptions.value&1==0:
  180.             max_depth=1            
  181.         regexp=None
  182.         if f.cGroupOptions.value&4!=0:
  183.             regexp=f.iRegexp.value
  184.         x=Xrefs(ea,max_depth,regexp)
  185.         xrefs_to={}
  186.         xrefs_from={}
  187.         if f.cGroupDirections.value&2!=0:
  188.             xrefs_to.update(x.getXrefsTo())
  189.         if f.cGroupDirections.value&1!=0:
  190.             xrefs_from.update(x.getXrefsFrom())
  191.         title='XrefsGraph for %s (depth=%d,regexp=%s)'%(getText(ea),
  192.                                                         max_depth,regexp)
  193.         g=XrefsGraph(title,ea,xrefs_to,xrefs_from)
  194.         g.Show()
  195.  
  196. main()
RAW Paste Data
Top