/* #<pydoc> def generate_disassembly(ea, max_lines, as_stack, notags): """ Generate disassembly lines (many lines) and put them into a buffer @param ea: address to generate disassembly for @param max_lines: how many lines max to generate @param as_stack: Display undefined items as 2/4/8 bytes @return: - None on failure - tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing the most important line number and a tuple of generated lines """ pass #</pydoc> */ PyObject *py_generate_disassembly( ea_t ea, int max_lines, bool as_stack, bool notags) { PYW_GIL_CHECK_LOCKED_SCOPE(); if ( max_lines <= 0 ) Py_RETURN_NONE; qstring qbuf; char **lines = new char *[max_lines]; int lnnum; int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack); newref_t py_tuple(PyTuple_New(nlines)); for ( int i=0; i<nlines; i++ ) { const char *s = lines[i]; size_t line_len = strlen(s); if ( notags ) { qbuf.resize(line_len+5); tag_remove(s, &qbuf[0], line_len); s = (const char *)&qbuf[0]; } PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s)); qfree(lines[i]); } delete [] lines; return Py_BuildValue("(iO)", lnnum, py_tuple.o); }
/* #<pydoc> def generate_disassembly(ea, max_lines, as_stack, notags): """ Generate disassembly lines (many lines) and put them into a buffer @param ea: address to generate disassembly for @param max_lines: how many lines max to generate @param as_stack: Display undefined items as 2/4/8 bytes @return: - None on failure - tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing the most important line number and a tuple of generated lines """ pass #</pydoc> */ PyObject *py_generate_disassembly( ea_t ea, int max_lines, bool as_stack, bool notags) { PYW_GIL_CHECK_LOCKED_SCOPE(); if ( max_lines <= 0 ) Py_RETURN_NONE; qstring qbuf; qstrvec_t lines; int lnnum; int nlines = generate_disassembly(&lines, &lnnum, ea, max_lines, as_stack); newref_t py_tuple(PyTuple_New(nlines)); for ( int i=0; i < nlines; i++ ) { const qstring &l = lines[i]; const char *s = l.c_str(); if ( notags ) { tag_remove(&qbuf, l); s = qbuf.c_str(); } PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s)); } return Py_BuildValue("(iO)", lnnum, py_tuple.o); }
//-------------------------------------------------------------------------- static int idaapi gr_callback(void *ud, int code, va_list va) { bool result = false; switch ( code ) { // a graph node has been double clicked case grcode_dblclicked: // in: graph_viewer_t *gv // selection_item_t *current_item // out: 0-ok, 1-ignore click { DECLARE_GI_VARS; va_arg(va, graph_viewer_t *); selection_item_t *s = va_arg(va, selection_item_t *); if ( s != NULL && s->is_node ) jumpto(fg->get_addr(s->node)); } break; // refresh user-defined graph nodes and edges case grcode_user_refresh: // in: mutable_graph_t *g // out: success { DECLARE_GI_VARS; if ( !gi->is_refresh_needed() ) break; gi->mark_as_refreshed(); fg->reset(); func_t *f = get_func(gi->func_ea); if ( f == NULL ) break; fg->walk_func(f, &fg_opts, 2); mutable_graph_t *mg = va_arg(va, mutable_graph_t *); // we have to resize mg->reset(); mg->resize(fg->count()); callgraph_t::edge_iterator end = fg->end_edges(); for ( callgraph_t::edge_iterator it=fg->begin_edges(); it != end; ++it ) { mg->add_edge(it->id1, it->id2, NULL); } fg->clear_edges(); result = true; } break; // retrieve text for user-defined graph node case grcode_user_text: // in: mutable_graph_t *g // int node // const char **result // bgcolor_t *bg_color (maybe NULL) // out: must return 0, result must be filled // NB: do not use anything calling GDI! { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int node = va_arg(va, int); const char **text = va_arg(va, const char **); bgcolor_t *bgcolor = va_arg(va, bgcolor_t *); callgraph_t::funcinfo_t *fi = fg->get_info(node); result = fi != NULL; if ( result ) { *text = fi->name.c_str(); if ( bgcolor != NULL ) *bgcolor = fi->color; } } break; // retrieve hint for the user-defined graph case grcode_user_hint: // in: mutable_graph_t *g // int mousenode // int mouseedge_src // int mouseedge_dst // char **hint // 'hint' must be allocated by qalloc() or qstrdup() // out: 0-use default hint, 1-use proposed hint { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int mousenode = va_argi(va, int); va_argi(va, int); va_argi(va, int); char **hint = va_arg(va, char **); ea_t addr; if ( mousenode != -1 && (addr = fg->get_addr(mousenode)) != BADADDR ) { char *lines[50]; int nl = generate_disassembly(addr, lines, qnumber(lines), NULL, false); qstring all_lines; for ( int i = 0; i < nl; i++) { if ( i != 0 ) all_lines += "\n"; all_lines += lines[i]; qfree(lines[i]); } *hint = all_lines.extract(); } result = true; // use our hint } break; // graph is being destroyed case grcode_destroyed: { DECLARE_GI_VAR; graph_info_t::destroy(gi); } break; } return (int)result; }