mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
from __future__ import print_function
|
|
# -----------------------------------------------------------------------
|
|
# This is an example illustrating how to use the user graphing functionality
|
|
# in Python
|
|
# (c) Hex-Rays
|
|
#
|
|
from idaapi import *
|
|
|
|
class GraphCloser(action_handler_t):
|
|
def __init__(self, graph):
|
|
action_handler_t.__init__(self)
|
|
self.graph = graph
|
|
|
|
def activate(self, ctx):
|
|
self.graph.Close()
|
|
|
|
def update(self, ctx):
|
|
return AST_ENABLE_ALWAYS
|
|
|
|
|
|
class ColorChanger(action_handler_t):
|
|
def __init__(self, graph):
|
|
action_handler_t.__init__(self)
|
|
self.graph = graph
|
|
|
|
def activate(self, ctx):
|
|
self.graph.color = self.graph.color ^ 0xffffff
|
|
self.graph.Refresh()
|
|
return 1
|
|
|
|
def update(self, ctx):
|
|
return AST_ENABLE_ALWAYS
|
|
|
|
|
|
class MyGraph(GraphViewer):
|
|
def __init__(self, funcname, result):
|
|
self.title = "call graph of " + funcname
|
|
GraphViewer.__init__(self, self.title)
|
|
self.funcname = funcname
|
|
self.result = result
|
|
self.color = 0xff00ff
|
|
|
|
def OnRefresh(self):
|
|
self.Clear()
|
|
id = self.AddNode((self.funcname, self.color))
|
|
for x in self.result.keys():
|
|
callee = self.AddNode((x, self.color))
|
|
self.AddEdge(id, callee)
|
|
|
|
return True
|
|
|
|
def OnGetText(self, node_id):
|
|
return self[node_id]
|
|
|
|
def OnPopup(self, form, popup_handle):
|
|
# graph closer
|
|
actname = "graph_closer:%s" % self.title
|
|
desc = action_desc_t(actname, "Close: %s" % self.title, GraphCloser(self))
|
|
attach_dynamic_action_to_popup(form, popup_handle, desc)
|
|
|
|
# color changer
|
|
actname = "color_changer:%s" % self.title
|
|
desc = action_desc_t(actname, "Change colors: %s" % self.title, ColorChanger(self))
|
|
attach_dynamic_action_to_popup(form, popup_handle, desc)
|
|
|
|
|
|
def show_graph():
|
|
f = idaapi.get_func(here())
|
|
if not f:
|
|
print("Must be in a function")
|
|
return
|
|
# Iterate through all function instructions and take only call instructions
|
|
result = {}
|
|
tmp = idaapi.insn_t()
|
|
for x in [x for x in FuncItems(f.start_ea) if (idaapi.decode_insn(tmp, x) and idaapi.is_call_insn(tmp))]:
|
|
for xref in XrefsFrom(x, idaapi.XREF_FAR):
|
|
if not xref.iscode: continue
|
|
t = get_func_name(xref.to)
|
|
if not t:
|
|
t = hex(xref.to)
|
|
result[t] = True
|
|
g = MyGraph(get_func_name(f.start_ea), result)
|
|
if g.Show():
|
|
return g
|
|
else:
|
|
return None
|
|
|
|
g = show_graph()
|
|
if g:
|
|
print("Graph created and displayed!")
|