mirror of
https://github.com/cemu-project/idapython.git
synced 2025-02-17 18:36:23 +01:00
graph.i: AddCommand() was broken
- updated the ex_graph.py sample - updated function usage comments
This commit is contained in:
parent
f4b1a7d87c
commit
5cede13626
@ -22,7 +22,26 @@ class MyGraph(GraphViewer):
|
|||||||
def OnGetText(self, node_id):
|
def OnGetText(self, node_id):
|
||||||
return str(self[node_id])
|
return str(self[node_id])
|
||||||
|
|
||||||
def main():
|
def OnCommand(self, cmd_id):
|
||||||
|
"""
|
||||||
|
Triggered when a menu command is selected through the menu or its hotkey
|
||||||
|
@return: None
|
||||||
|
"""
|
||||||
|
if self.cmd_close == cmd_id:
|
||||||
|
self.Close()
|
||||||
|
return
|
||||||
|
|
||||||
|
print "command:", cmd_id
|
||||||
|
|
||||||
|
def Show(self):
|
||||||
|
if not GraphViewer.Show(self):
|
||||||
|
return False
|
||||||
|
self.cmd_close = self.AddCommand("Close", "F2")
|
||||||
|
if self.cmd_close == 0:
|
||||||
|
print "Failed to add popup menu item!"
|
||||||
|
return True
|
||||||
|
|
||||||
|
def show_graph():
|
||||||
f = idaapi.get_func(here())
|
f = idaapi.get_func(here())
|
||||||
if not f:
|
if not f:
|
||||||
print "Must be in a function"
|
print "Must be in a function"
|
||||||
@ -37,6 +56,11 @@ def main():
|
|||||||
t = hex(xref.to)
|
t = hex(xref.to)
|
||||||
result[t] = True
|
result[t] = True
|
||||||
g = MyGraph(GetFunctionName(f.startEA), result)
|
g = MyGraph(GetFunctionName(f.startEA), result)
|
||||||
g.Show()
|
if g.Show():
|
||||||
|
return g
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
main()
|
g = show_graph()
|
||||||
|
if g:
|
||||||
|
print "Graph created and displayed!"
|
@ -554,4 +554,15 @@ class _cpu(object):
|
|||||||
return idc.SetRegValue(value, name)
|
return idc.SetRegValue(value, name)
|
||||||
|
|
||||||
cpu = _cpu()
|
cpu = _cpu()
|
||||||
|
"""This is a special class instance used to access the registers as if they were attributes of this object.
|
||||||
|
For example to access the EAX register:
|
||||||
|
print "%x" % cpu.Eax
|
||||||
|
"""
|
||||||
|
|
||||||
procregs = _procregs()
|
procregs = _procregs()
|
||||||
|
"""This object is used to access the processor registers. It is useful when decoding instructions and you want to see which instruction is which.
|
||||||
|
For example:
|
||||||
|
x = idautils.DecodeInstruction(here())
|
||||||
|
if x[0] == procregs.Esp:
|
||||||
|
print "This operand is the register ESP
|
||||||
|
"""
|
62
swig/graph.i
62
swig/graph.i
@ -128,7 +128,7 @@ private:
|
|||||||
|
|
||||||
// Check return value to OnRefresh() call
|
// Check return value to OnRefresh() call
|
||||||
PyObject *ret = PyObject_CallMethod(self, (char *)S_ON_REFRESH, NULL);
|
PyObject *ret = PyObject_CallMethod(self, (char *)S_ON_REFRESH, NULL);
|
||||||
if (ret == NULL || !PyBool_Check(ret) || ret != Py_True)
|
if ( ret == NULL || !PyObject_IsTrue(ret) )
|
||||||
{
|
{
|
||||||
Py_XDECREF(ret);
|
Py_XDECREF(ret);
|
||||||
return;
|
return;
|
||||||
@ -311,7 +311,7 @@ private:
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_CLICK, "i", item2->n);
|
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_CLICK, "i", item2->n);
|
||||||
if (result == NULL || !PyBool_Check(result) || result != Py_True)
|
if ( result == NULL || !PyObject_IsTrue(result) )
|
||||||
{
|
{
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
return 1;
|
return 1;
|
||||||
@ -332,7 +332,7 @@ private:
|
|||||||
if (item == NULL || !item->is_node)
|
if (item == NULL || !item->is_node)
|
||||||
return 1;
|
return 1;
|
||||||
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_DBL_CLICK, "i", item->node);
|
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_DBL_CLICK, "i", item->node);
|
||||||
if (result == NULL || !PyBool_Check(result) || result != Py_True)
|
if ( result == NULL || !PyObject_IsTrue(result) )
|
||||||
{
|
{
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
return 1;
|
return 1;
|
||||||
@ -361,9 +361,6 @@ private:
|
|||||||
// in: graph_viewer_t *gv
|
// in: graph_viewer_t *gv
|
||||||
// int curnode
|
// int curnode
|
||||||
// out: 0-ok, 1-forbid to change the current node
|
// out: 0-ok, 1-forbid to change the current node
|
||||||
//graph_viewer_t *v = va_arg(va, graph_viewer_t *);
|
|
||||||
//int curnode = va_argi(va, int);
|
|
||||||
//msg("%x: current node becomes %d\n", v, curnode);
|
|
||||||
if (curnode < 0)
|
if (curnode < 0)
|
||||||
return 0;
|
return 0;
|
||||||
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_SELECT, "i", curnode);
|
PyObject *result = PyObject_CallMethod(self, (char *)S_ON_SELECT, "i", curnode);
|
||||||
@ -427,10 +424,12 @@ private:
|
|||||||
on_lostfocus(va_arg(va, graph_viewer_t *));
|
on_lostfocus(va_arg(va, graph_viewer_t *));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case grcode_user_refresh:
|
case grcode_user_refresh:
|
||||||
on_user_refresh(va_arg(va, mutable_graph_t *));
|
on_user_refresh(va_arg(va, mutable_graph_t *));
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case grcode_user_hint:
|
case grcode_user_hint:
|
||||||
if (cb_flags & GR_HAVE_USER_HINT)
|
if (cb_flags & GR_HAVE_USER_HINT)
|
||||||
{
|
{
|
||||||
@ -446,6 +445,7 @@ private:
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case grcode_changed_current:
|
case grcode_changed_current:
|
||||||
if (cb_flags & GR_HAVE_CHANGED_CURRENT)
|
if (cb_flags & GR_HAVE_CHANGED_CURRENT)
|
||||||
{
|
{
|
||||||
@ -456,6 +456,7 @@ private:
|
|||||||
else
|
else
|
||||||
ret = 0; // allow selection change
|
ret = 0; // allow selection change
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
default:
|
default:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
@ -511,20 +512,10 @@ private:
|
|||||||
place_t *old_pl = get_custom_viewer_place(gv, false, &x, &y);
|
place_t *old_pl = get_custom_viewer_place(gv, false, &x, &y);
|
||||||
if ( old_pl != NULL )
|
if ( old_pl != NULL )
|
||||||
{
|
{
|
||||||
#ifdef __BORLANDC__
|
|
||||||
user_graph_place_t *new_pl = (user_graph_place_t *) old_pl->clone();
|
user_graph_place_t *new_pl = (user_graph_place_t *) old_pl->clone();
|
||||||
#else
|
|
||||||
// although this works, it may not work in the future
|
|
||||||
user_graph_place_t *new_pl = (user_graph_place_t *) qalloc(sizeof(user_graph_place_t));
|
|
||||||
memcpy(new_pl, old_pl, sizeof(user_graph_place_t));
|
|
||||||
#endif
|
|
||||||
new_pl->node = nid;
|
new_pl->node = nid;
|
||||||
jumpto(gv, new_pl, x, y);
|
jumpto(gv, new_pl, x, y);
|
||||||
#ifdef __BORLANDC__
|
|
||||||
delete new_pl;
|
delete new_pl;
|
||||||
#else
|
|
||||||
qfree(new_pl);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,9 +717,9 @@ void pyg_close(PyObject *self)
|
|||||||
py_graph_t::Close(self);
|
py_graph_t::Close(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t pyg_add_command(PyObject *self, const char *title, const char *hotkey)
|
PyObject *pyg_add_command(PyObject *self, const char *title, const char *hotkey)
|
||||||
{
|
{
|
||||||
return py_graph_t::AddCommand(self, title, hotkey);
|
return Py_BuildValue("n", py_graph_t::AddCommand(self, title, hotkey));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pyg_select_node(PyObject *self, int nid)
|
void pyg_select_node(PyObject *self, int nid)
|
||||||
@ -811,10 +802,10 @@ class GraphViewer:
|
|||||||
|
|
||||||
def AddCommand(self, title, hotkey):
|
def AddCommand(self, title, hotkey):
|
||||||
"""
|
"""
|
||||||
Adds a menu command to the graph.
|
Adds a menu command to the graph. Call this command after the graph is shown (with Show()).
|
||||||
Once a command is added, a command id is returned. The commands are handled inside the OnCommand() handler
|
Once a command is added, a command id is returned. The commands are handled inside the OnCommand() handler
|
||||||
|
|
||||||
@return: 0 or the command id
|
@return: 0 on failure or the command id
|
||||||
"""
|
"""
|
||||||
return _idaapi.pyg_add_command(self, title, hotkey)
|
return _idaapi.pyg_add_command(self, title, hotkey)
|
||||||
|
|
||||||
@ -822,6 +813,7 @@ class GraphViewer:
|
|||||||
"""
|
"""
|
||||||
Event called when the graph is refreshed or first created.
|
Event called when the graph is refreshed or first created.
|
||||||
From this event you are supposed to create nodes and edges.
|
From this event you are supposed to create nodes and edges.
|
||||||
|
This callback is mandatory.
|
||||||
@note: ***It is important to clear previous nodes before adding nodes.***
|
@note: ***It is important to clear previous nodes before adding nodes.***
|
||||||
@return: Returning true tells the graph viewer to use the items. Otherwise old items will be used.
|
@return: Returning true tells the graph viewer to use the items. Otherwise old items will be used.
|
||||||
"""
|
"""
|
||||||
@ -830,13 +822,18 @@ class GraphViewer:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# def OnActivate(self):
|
# def OnActivate(self):
|
||||||
# """Triggered when the graph window gets the focus"""
|
# """
|
||||||
|
# Triggered when the graph window gets the focus
|
||||||
|
# @return: None
|
||||||
|
# """
|
||||||
# print "Activated...."
|
# print "Activated...."
|
||||||
|
#
|
||||||
# def OnDeactivate(self):
|
# def OnDeactivate(self):
|
||||||
# """Triggered when the graph window loses the focus"""
|
# """Triggered when the graph window loses the focus
|
||||||
|
# @return: None
|
||||||
|
# """
|
||||||
# print "Deactivated...."
|
# print "Deactivated...."
|
||||||
|
#
|
||||||
# def OnSelect(self, node_id):
|
# def OnSelect(self, node_id):
|
||||||
# """
|
# """
|
||||||
# Triggered when a node is being selected
|
# Triggered when a node is being selected
|
||||||
@ -862,11 +859,13 @@ class GraphViewer:
|
|||||||
# @return: None if no hint is avail or a string designating the hint
|
# @return: None if no hint is avail or a string designating the hint
|
||||||
# """
|
# """
|
||||||
# return "hint for " + str(node_id)
|
# return "hint for " + str(node_id)
|
||||||
|
#
|
||||||
# def OnClose(self):
|
# def OnClose(self):
|
||||||
# """Triggered when the graph viewer window is being closed"""
|
# """Triggered when the graph viewer window is being closed
|
||||||
|
# @return: None
|
||||||
|
# """
|
||||||
# print "Closing......."
|
# print "Closing......."
|
||||||
|
#
|
||||||
# def OnClick(self, node_id):
|
# def OnClick(self, node_id):
|
||||||
# """
|
# """
|
||||||
# Triggered when a node is clicked
|
# Triggered when a node is clicked
|
||||||
@ -874,18 +873,19 @@ class GraphViewer:
|
|||||||
# """
|
# """
|
||||||
# print "clicked on", self[node_id]
|
# print "clicked on", self[node_id]
|
||||||
# return True
|
# return True
|
||||||
|
#
|
||||||
# def OnDblClick(self, node_id):
|
# def OnDblClick(self, node_id):
|
||||||
# """
|
# """
|
||||||
# Triggerd when a node is double-clicked.
|
# Triggerd when a node is double-clicked.
|
||||||
# @note: check OnClick() event
|
# @return: False to ignore the click and True otherwise
|
||||||
# """
|
# """
|
||||||
# print "dblclicked on", self[node_id]
|
# print "dblclicked on", self[node_id]
|
||||||
# return True
|
# return True
|
||||||
|
#
|
||||||
# def OnCommand(self, cmd_id):
|
# def OnCommand(self, cmd_id):
|
||||||
# """
|
# """
|
||||||
# Triggered when a menu command is selected through the menu or its hotkey
|
# Triggered when a menu command is selected through the menu or its hotkey
|
||||||
|
# @return: None
|
||||||
# """
|
# """
|
||||||
# print "command:", cmd_id
|
# print "command:", cmd_id
|
||||||
#</pycode(py_graph)>
|
#</pycode(py_graph)>
|
||||||
@ -896,7 +896,7 @@ class GraphViewer:
|
|||||||
void pyg_refresh(PyObject *self);
|
void pyg_refresh(PyObject *self);
|
||||||
void pyg_close(PyObject *self);
|
void pyg_close(PyObject *self);
|
||||||
|
|
||||||
Py_ssize_t pyg_add_command(PyObject *self, const char *title, const char *hotkey);
|
PyObject *pyg_add_command(PyObject *self, const char *title, const char *hotkey);
|
||||||
void pyg_select_node(PyObject *self, int nid);
|
void pyg_select_node(PyObject *self, int nid);
|
||||||
bool pyg_show(PyObject *self);
|
bool pyg_show(PyObject *self);
|
||||||
//</inline(py_graph)>
|
//</inline(py_graph)>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user