graph.i: AddCommand() was broken

- updated the ex_graph.py sample
- updated function usage comments
This commit is contained in:
elias.bachaalany 2010-05-06 07:56:25 +00:00
parent f4b1a7d87c
commit 5cede13626
3 changed files with 69 additions and 34 deletions

View File

@ -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!"

View File

@ -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
"""

View File

@ -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)>