IDA C++ SDK 9.2
Loading...
Searching...
No Matches
interactive_graph_t Class Reference

The base class used to display graphs in IDA. More...

#include <graph.hpp>

Inheritance diagram for interactive_graph_t:
drawable_graph_t gdl_graph_t

Public Types

typedef qvector< rect_tnode_layout_t

Public Member Functions

idaapi interactive_graph_t (uval_t id)
idaapi interactive_graph_t (const drawable_graph_t &g, uval_t id)
virtual ~interactive_graph_t ()
virtual int idaapi size (void) const override
 Get the total number of nodes (including group nodes, and including hidden nodes.)
virtual int idaapi node_qty (void) const override
 Get the number of visible nodes (the list can be retrieved using gdl.hpp's node_iterator)
void idaapi clear (void)
 Clears all nodes & edges information in this instance (does not remove node_info_t stored in the database.)
virtual bool idaapi empty (void) const override
 Is the graph (visually) empty?
virtual bool idaapi exists (int node) const override
 Is the node visible?
int idaapi get_node_representative (int node)
 Get the node that currently visually represents 'node'.
int idaapi get_node_group (int node) const
void idaapi set_node_group (int node, int group)
bool idaapi is_deleted_node (int node) const
void idaapi set_deleted_node (int node)
bool idaapi is_subgraph_node (int node) const
bool idaapi is_dot_node (int node) const
bool idaapi is_group_node (int node) const
bool idaapi is_displayable_node (int node) const
bool idaapi is_simple_node (int node) const
bool idaapi is_collapsed_node (int node) const
bool idaapi is_uncollapsed_node (int node) const
bool idaapi is_visible_node (int node) const
 Is the node currently visible?
bool idaapi groups_are_present (void) const
 Is there any group node in the graph?
int idaapi get_first_subgraph_node (int group) const
int idaapi get_next_subgraph_node (int group, int current) const
void idaapi insert_visible_nodes (intvec_t &nodes, int group) const
void idaapi insert_simple_nodes (intvec_t &nodes, int group) const
bool idaapi check_new_group (const intvec_t &nodes, intvec_t &refined)
int idaapi create_group (const intvec_t &nodes)
 Create a new group node, that will contain all the nodes in 'nodes'.
bool idaapi delete_group (int group)
 Delete a group node.
bool idaapi change_group_visibility (int group, bool expand)
 Expand/collapse a group node.
bool idaapi change_visibility (const intvec_t &nodes, bool expand)
 Change visibility of multiple group nodes.
virtual int idaapi nsucc (int b) const override
virtual int idaapi npred (int b) const override
virtual int idaapi succ (int b, int i) const override
virtual int idaapi pred (int b, int i) const override
const intvec_t &idaapi succset (int b) const
const intvec_t &idaapi predset (int b) const
void idaapi reset (void)
virtual bool idaapi redo_layout (void) GCC_PUREVIRT
 Recompute the layout, according to the value of 'current_layout'.
virtual void idaapi resize (int n) GCC_PUREVIRT
 Resize the graph to 'n' nodes.
virtual int idaapi add_node (const rect_t *r) GCC_PUREVIRT
 Add a node, possibly with a specific geometry.
virtual ssize_t idaapi del_node (int n) GCC_PUREVIRT
 Delete a node.
virtual bool idaapi add_edge (int i, int j, const edge_info_t *ei) GCC_PUREVIRT
virtual bool idaapi del_edge (int i, int j) GCC_PUREVIRT
virtual bool idaapi replace_edge (int i, int j, int x, int y) GCC_PUREVIRT
virtual bool idaapi refresh (void) GCC_PUREVIRT
 Refresh the graph.
virtual interactive_graph_t *idaapi clone (void) const override GCC_PUREVIRT
const rect_t &idaapi nrect (int n) const
virtual rect_t &idaapi nrect (int n) override
virtual edge_info_t *idaapi get_edge (edge_t e) override GCC_PUREVIRT
virtual bool idaapi set_nrect (int n, const rect_t &r) GCC_PUREVIRT
virtual bool idaapi set_edge (edge_t e, const edge_info_t *ei) GCC_PUREVIRT
bool idaapi create_digraph_layout (void)
void idaapi del_custom_layout (void)
bool idaapi get_custom_layout (void)
void idaapi set_custom_layout (void) const
bool idaapi get_graph_groups (void)
void idaapi set_graph_groups (void) const
virtual ea_t idaapi calc_group_ea (const intvec_t &) new api
point_t idaapi calc_center_of (const intvec_t &nodes) const
void idaapi move_to_same_place (const intvec_t &collapsing_nodes, point_t p)
void idaapi move_grouped_nodes (const intvec_t &groups, const interactive_graph_t *ng)
virtual bool idaapi is_user_graph () new api
Public Member Functions inherited from drawable_graph_t
virtual ~drawable_graph_t ()
void idaapi clear (void)
void idaapi dump_graph (const char *header) const
bool idaapi calc_bounds (rect_t *r)
void idaapi calc_fitting_params (const rect_t &area, const rect_t &r, graph_location_info_t *gli, double max_zoom)
bool idaapi calc_fitting_params (const rect_t &area, graph_location_info_t *gli, double max_zoom)
int idaapi for_all_nodes_edges (graph_visitor_t &nev, bool visit_nodes=true)
const edge_info_t *idaapi get_edge_ports (edge_t e, point_t &s, point_t &d) const
void idaapi add_node_edges (edgevec_t &dlist, int node)
const rect_t &idaapi nrect (int n) const
const edge_info_t *idaapi get_edge (edge_t e) const
bool idaapi create_tree_layout (void)
bool idaapi create_circle_layout (point_t p, int radius)
bool idaapi create_polar_tree_layout (point_t p, int radius)
bool idaapi create_radial_tree_layout (point_t p, int radius)
bool idaapi create_orthogonal_layout (void)
void set_callback (hook_cb_t *_callback, void *_ud)
ssize_t vgrcall (int code, va_list va)
ssize_t grcall (int code,...)
Public Member Functions inherited from gdl_graph_t
 DEFINE_MEMORY_ALLOCATION_FUNCS () virtual ~gdl_graph_t()
virtual char *idaapi get_node_label (char *iobuf, int iobufsize, int n) const
virtual void idaapi print_graph_attributes (FILE *fp) const
virtual bool idaapi print_node (FILE *fp, int n) const
virtual bool idaapi print_edge (FILE *fp, int i, int j) const
virtual void idaapi print_node_attributes (FILE *fp, int n) const
virtual int idaapi entry (void) const
virtual int idaapi exit (void) const
virtual bgcolor_t idaapi get_node_color (int n) const
virtual bgcolor_t idaapi get_edge_color (int i, int j) const
void idaapi gen_gdl (FILE *fp) const
void idaapi gen_gdl (const char *file) const
size_t idaapi nedge (int node, bool ispred) const
int idaapi edge (int node, int i, bool ispred) const
int idaapi front (void)
node_iterator idaapi begin (void) const
node_iterator idaapi end (void) const
bool idaapi path_exists (int m, int n) const
void idaapi gen_dot (FILE *fp) const
void idaapi gen_dot (const char *file) const

Public Attributes

uval_t gid
 graph id - unique for the database for flowcharts it is equal to the function start_ea
intvec_t belongs
 the subgraph the node belongs to INT_MAX means that the node doesn't exist sign bit means collapsed node
bytevec_t node_flags
 node flags
array_of_intvec_t org_succs
array_of_intvec_t org_preds
array_of_intvec_t succs
array_of_intvec_t preds
node_layout_t nodes
edge_infos_wrapper_t edges
Public Attributes inherited from drawable_graph_t
qstring title
 graph title
bool rect_edges_made = false
 have create rectangular edges?
layout_type_t current_layout = layout_none
 see Proximity view layouts
point_t circle_center
 for layout_circle
int circle_radius = 0
 for layout_circle
hook_cb_tcallback = nullptr
 user-defined callback
voidcallback_ud = nullptr
 user data for callback

Additional Inherited Members

Protected Member Functions inherited from drawable_graph_t
void idaapi get_connected_components (intvec_t &entries) const
 Returns one entry point for each connected component.
int idaapi calc_longest_pathes (const node_set_t &entries, intvec_t &tops, int row_height) const
 Find longest paths from the entries.
void idaapi move_nodes_down (intvec_t &tops, const node_ordering_t &post, int first_reverser_node, int row_height) const
 Move entry nodes down as much as possible.
void idaapi create_graph_row_info (const intvec_t &tops, graph_row_info_t &gri, int graph_height) const
 Create graph row info from 'tops'.
void idaapi calc_row_heights (graph_row_info_t &gri) const
 Calculate height of each row.
void idaapi minimize_crossings (graph_row_info_t &gri) const
 Minimize crossings.
void idaapi set_x_coords (const graph_row_info_t &gri, const node_set_t &selfrefs, int first_added_node)
 Calculate x coords of all nodes.
void idaapi gather_edge_segments (const graph_row_info_t &gri, edge_segs_vec_t &ges) const
 Gather information about all edge segments.
void idaapi make_rect_edges (graph_row_info_t &gri, const edge_segs_vec_t &ges, int first_reverser_node)
 Make all edges rectangular.
void idaapi assign_edge_ports (const graph_row_info_t &gri, const node_set_t &selfrefs)
 Assign ports to edges.
void idaapi recalc_edge_widths (const edgeset_t &back_edges, const edge_infos_t &self_edges)
 Recalculate width of all edges.
void idaapi clear_layout_info (void)
 Clear layout information in the graph.
void idaapi depth_first (node_ordering_t *pre, node_ordering_t *post, edge_typer_t *et) const
void idaapi create_spanning_tree (edge_typer_t *et, node_set_t *entries, edgeset_t *back_edges, node_ordering_t *pre, node_ordering_t *post) const
void idaapi tree_layout (edge_typer_t &et, const node_set_t &entries)
bool idaapi path_back (const array_of_node_set_t &domin, int m, int n) const
 Is there a path from M to N which terminates with a back edge to N?
bool idaapi path_back (edge_typer_t &et, int m, int n) const
int idaapi visit_nodes (int node, graph_node_visitor_t &gv) const
 Visit nodes starting from 'node', depth first.
int idaapi visit_paths (int node, graph_path_visitor_t &gv) const
 Visit all possible paths starting from 'node'.

Detailed Description

The base class used to display graphs in IDA.

The interactive_graph_t introduces the following notions on top of the ones that parent classes already provide:

  • ability to add/remove nodes
  • ability to add/remove edges
  • grouping/ungrouping nodes
  • expanding/collapsing existing groups

While the adding/removing of nodes & edges is, in itself, a fairly straightforward notion, 'groups' can be a bit more tricky to figure out.

For the purpose of illustrating what 'groups' are, and how they are handled, let's assume that we are analyzing a binary that contains multiple bits of connected information scattered all over the place in a read-only '.rodata' segment.

In order to simplify analysis that scattered-but-connected data, the user might choose to write a small plugin that represents the data in a graph form:

+--------------------------—+ | Driver object #1 | | address: 0x400100 | | size: 0x200 bytes | +----------—+------------—+ | +---------------------—+ | +--------—+--------------—+ | Driver object #2 | | address: 0x407380 | | size: 0x180 bytes | | (seems to maintain state of | | the I/O ports) | +-—+----—+-------------—+ | | +------------—+ +-------------—+ | | +----------—+--------—+ +----—+----------—+ | Unknown object #1 | | Driver object #3 | | address: 0x404100 | | address: 0x402000 | | size: 0x80 bytes | | size: 4KB | | (credentials?) | | (mostly mutexes) | +----------------------—+ +------------------—+

In this case, the graph has 4 nodes, each showing some information that is relevant to the analyst. In order to implement this, the plugin must keep, somewhere in memory, the relevant information about the nodes. In this case, it would have a set of 4 items, from which the nodes texts can be generated and provided back to IDA's UI.

If one was to call the following methods on the interactive_graph_t instance that is being displayed by IDA, one would get:

interactive_graph_t::size() -> 4 interactive_graph_t::node_qty() -> 4

Let's now assume the user decides the 2 first nodes are not that interesting after all, and groups them together, in a node labeled "irrelevant".

Then, IDA will modify the interactive_graph_t by adding it a 5th node, which represents that group It's worth pointing out that, it's the interactive_graph_t itself that's doing all the bookkeeping about the groups: the user plugin doesn't need to do anything at all

In addition, calling the methods above now yields: interactive_graph_t::size() -> 5 interactive_graph_t::node_qty() -> 3

Member Typedef Documentation

◆ node_layout_t

Constructor & Destructor Documentation

◆ interactive_graph_t() [1/2]

idaapi interactive_graph_t::interactive_graph_t ( uval_t id)

◆ interactive_graph_t() [2/2]

idaapi interactive_graph_t::interactive_graph_t ( const drawable_graph_t & g,
uval_t id )

◆ ~interactive_graph_t()

virtual interactive_graph_t::~interactive_graph_t ( )
inlinevirtual

Member Function Documentation

◆ size()

virtual int idaapi interactive_graph_t::size ( void ) const
inlineoverridevirtual

Get the total number of nodes (including group nodes, and including hidden nodes.)

See also node_qty()

Returns
the total number of nodes in the graph

Implements gdl_graph_t.

◆ node_qty()

int idaapi interactive_graph_t::node_qty ( void ) const
inlineoverridevirtual

Get the number of visible nodes (the list can be retrieved using gdl.hpp's node_iterator)

See also size()

Returns
the number of visible nodes

Reimplemented from gdl_graph_t.

◆ clear()

void idaapi interactive_graph_t::clear ( void )
inline

Clears all nodes & edges information in this instance (does not remove node_info_t stored in the database.)

◆ empty()

bool idaapi interactive_graph_t::empty ( void ) const
inlineoverridevirtual

Is the graph (visually) empty?

Returns
true if there are no visible nodes

Reimplemented from gdl_graph_t.

◆ exists()

virtual bool idaapi interactive_graph_t::exists ( int node) const
inlineoverridevirtual

Is the node visible?

Parameters
nodethe node number
Returns
success

Reimplemented from gdl_graph_t.

◆ get_node_representative()

int idaapi interactive_graph_t::get_node_representative ( int node)
inline

Get the node that currently visually represents 'node'.

This will find the "closest" parent group node that's visible, by attempting to walk up the group nodes that contain 'node', and will stop when it finds a node that is currently visible.

See also get_group_node()

Parameters
nodethe node
Returns
the node that represents 'node', or 'node' if it's not part of any group

◆ get_node_group()

int idaapi interactive_graph_t::get_node_group ( int node) const
inline

◆ set_node_group()

void idaapi interactive_graph_t::set_node_group ( int node,
int group )
inline

◆ is_deleted_node()

bool idaapi interactive_graph_t::is_deleted_node ( int node) const
inline

◆ set_deleted_node()

void idaapi interactive_graph_t::set_deleted_node ( int node)
inline

◆ is_subgraph_node()

bool idaapi interactive_graph_t::is_subgraph_node ( int node) const
inline

◆ is_dot_node()

bool idaapi interactive_graph_t::is_dot_node ( int node) const
inline

◆ is_group_node()

bool idaapi interactive_graph_t::is_group_node ( int node) const
inline

◆ is_displayable_node()

bool idaapi interactive_graph_t::is_displayable_node ( int node) const
inline

◆ is_simple_node()

bool idaapi interactive_graph_t::is_simple_node ( int node) const
inline

◆ is_collapsed_node()

bool idaapi interactive_graph_t::is_collapsed_node ( int node) const
inline

◆ is_uncollapsed_node()

bool idaapi interactive_graph_t::is_uncollapsed_node ( int node) const
inline

◆ is_visible_node()

bool idaapi interactive_graph_t::is_visible_node ( int node) const
inline

Is the node currently visible?

An invisible node is a node that's part of a group that's currently collapsed.

Parameters
nodethe node
Returns
success

◆ groups_are_present()

bool idaapi interactive_graph_t::groups_are_present ( void ) const

Is there any group node in the graph?

Returns
success

◆ get_first_subgraph_node()

int idaapi interactive_graph_t::get_first_subgraph_node ( int group) const
inline

◆ get_next_subgraph_node()

int idaapi interactive_graph_t::get_next_subgraph_node ( int group,
int current ) const
inline

◆ insert_visible_nodes()

void idaapi interactive_graph_t::insert_visible_nodes ( intvec_t & nodes,
int group ) const

◆ insert_simple_nodes()

void idaapi interactive_graph_t::insert_simple_nodes ( intvec_t & nodes,
int group ) const

◆ check_new_group()

bool idaapi interactive_graph_t::check_new_group ( const intvec_t & nodes,
intvec_t & refined )

◆ create_group()

int idaapi interactive_graph_t::create_group ( const intvec_t & nodes)
inline

Create a new group node, that will contain all the nodes in 'nodes'.

Parameters
nodesthe nodes that will be part of the group
Returns
the group node, or -1 in case of error

◆ delete_group()

bool idaapi interactive_graph_t::delete_group ( int group)
inline

Delete a group node.

This deletes the group node only; it does not delete nodes that are part of the group.

Parameters
groupthe group node
Returns
success

◆ change_group_visibility()

bool idaapi interactive_graph_t::change_group_visibility ( int group,
bool expand )
inline

Expand/collapse a group node.

Parameters
groupthe group node
expandwhether to expand or collapse
Returns
success

◆ change_visibility()

bool idaapi interactive_graph_t::change_visibility ( const intvec_t & nodes,
bool expand )

Change visibility of multiple group nodes.

Parameters
nodesthe group nodes
expandwhether to expand or collapse
Returns
success (true if any group node was modified)

◆ nsucc()

virtual int idaapi interactive_graph_t::nsucc ( int b) const
inlineoverridevirtual

Implements gdl_graph_t.

◆ npred()

virtual int idaapi interactive_graph_t::npred ( int b) const
inlineoverridevirtual

Implements gdl_graph_t.

◆ succ()

virtual int idaapi interactive_graph_t::succ ( int b,
int i ) const
inlineoverridevirtual

Implements gdl_graph_t.

◆ pred()

virtual int idaapi interactive_graph_t::pred ( int b,
int i ) const
inlineoverridevirtual

Implements gdl_graph_t.

◆ succset()

const intvec_t &idaapi interactive_graph_t::succset ( int b) const
inline

◆ predset()

const intvec_t &idaapi interactive_graph_t::predset ( int b) const
inline

◆ reset()

void idaapi interactive_graph_t::reset ( void )
inline

◆ redo_layout()

virtual bool idaapi interactive_graph_t::redo_layout ( void )
virtual

Recompute the layout, according to the value of 'current_layout'.

Returns
success

◆ resize()

virtual void idaapi interactive_graph_t::resize ( int n)
virtual

Resize the graph to 'n' nodes.

Parameters
nthe new size

◆ add_node()

virtual int idaapi interactive_graph_t::add_node ( const rect_t * r)
virtual

Add a node, possibly with a specific geometry.

Parameters
rthe node geometry (can be nullptr)
Returns
the new node

◆ del_node()

virtual ssize_t idaapi interactive_graph_t::del_node ( int n)
virtual

Delete a node.

Parameters
nthe node to delete
Returns
the number of deleted edges

◆ add_edge()

virtual bool idaapi interactive_graph_t::add_edge ( int i,
int j,
const edge_info_t * ei )
virtual

◆ del_edge()

virtual bool idaapi interactive_graph_t::del_edge ( int i,
int j )
virtual

◆ replace_edge()

virtual bool idaapi interactive_graph_t::replace_edge ( int i,
int j,
int x,
int y )
virtual

◆ refresh()

virtual bool idaapi interactive_graph_t::refresh ( void )
virtual

Refresh the graph.

A graph needs refreshing when it's "backing data". E.g., if the number (or contents) of the objects in the above example, change.

Let's say the user's plugin ends up finding a 5th piece of scattered data. It should then add it to its internal list of known objects, and tell IDA that the graph needs to be refreshed, using refresh_viewer(). This will cause IDA to:

  • discard all its internal rendering information,
  • call interactive_graph_t::refresh() on the graph so that the user's plugin has a chance to "sync" the number of nodes & edges that this graph contains, to the information that the plugin has collected so far
  • re-create internal rendering information, and
  • repaint the view
Returns
success

◆ clone()

virtual interactive_graph_t *idaapi interactive_graph_t::clone ( void ) const
overridevirtual

Implements drawable_graph_t.

◆ nrect() [1/2]

const rect_t &idaapi interactive_graph_t::nrect ( int n) const
inline

◆ nrect() [2/2]

rect_t &idaapi interactive_graph_t::nrect ( int n)
inlineoverridevirtual

Implements drawable_graph_t.

◆ get_edge()

virtual edge_info_t *idaapi interactive_graph_t::get_edge ( edge_t e)
overridevirtual

Implements drawable_graph_t.

◆ set_nrect()

virtual bool idaapi interactive_graph_t::set_nrect ( int n,
const rect_t & r )
virtual

◆ set_edge()

bool idaapi interactive_graph_t::set_edge ( edge_t e,
const edge_info_t * ei )
inlinevirtual

◆ create_digraph_layout()

bool idaapi interactive_graph_t::create_digraph_layout ( void )
inline

◆ del_custom_layout()

void idaapi interactive_graph_t::del_custom_layout ( void )
inline

◆ get_custom_layout()

bool idaapi interactive_graph_t::get_custom_layout ( void )
inline

◆ set_custom_layout()

void idaapi interactive_graph_t::set_custom_layout ( void ) const
inline

◆ get_graph_groups()

bool idaapi interactive_graph_t::get_graph_groups ( void )
inline

◆ set_graph_groups()

void idaapi interactive_graph_t::set_graph_groups ( void ) const
inline

◆ calc_group_ea()

virtual ea_t idaapi interactive_graph_t::calc_group_ea ( const intvec_t & )
inlinenewvirtual

◆ calc_center_of()

point_t idaapi interactive_graph_t::calc_center_of ( const intvec_t & nodes) const

◆ move_to_same_place()

void idaapi interactive_graph_t::move_to_same_place ( const intvec_t & collapsing_nodes,
point_t p )

◆ move_grouped_nodes()

void idaapi interactive_graph_t::move_grouped_nodes ( const intvec_t & groups,
const interactive_graph_t * ng )

◆ is_user_graph()

virtual bool idaapi interactive_graph_t::is_user_graph ( )
inlinenewvirtual

Member Data Documentation

◆ gid

uval_t interactive_graph_t::gid

graph id - unique for the database for flowcharts it is equal to the function start_ea

◆ belongs

intvec_t interactive_graph_t::belongs

the subgraph the node belongs to INT_MAX means that the node doesn't exist sign bit means collapsed node

◆ node_flags

bytevec_t interactive_graph_t::node_flags

node flags

◆ org_succs

array_of_intvec_t interactive_graph_t::org_succs

◆ org_preds

array_of_intvec_t interactive_graph_t::org_preds

◆ succs

array_of_intvec_t interactive_graph_t::succs

◆ preds

array_of_intvec_t interactive_graph_t::preds

◆ nodes

node_layout_t interactive_graph_t::nodes

◆ edges

edge_infos_wrapper_t interactive_graph_t::edges

The documentation for this class was generated from the following file: