| IDA SDK

Public Attributes | Public Member Functions | Public Types | Friends | List of all members
interactive_graph_t Class Reference

## 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

Inherits drawable_graph_t.

## 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 = current_layout
| see Proximity view layouts
point_t | circle_center
| for layout_circle
int | circle_radius = 0
| for layout_circle
hook_cb_t * | callback = nullptr
| user-defined callback
void * | callback_ud = nullptr
| user data for callback

## Public Member Functions
idaapi | interactive_graph_t (uval_t id)
idaapi | interactive_graph_t (const drawable_graph_t &g, uval_t id)
virtual int idaapi | size (void) const override
| Get the total number of nodes (including group nodes, and including hidden nodes.) More...
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) More...
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? More...
virtual bool idaapi | exists (int node) const override
| Is the node visible? More...
int idaapi | get_node_representative (int node)
| Get the node that currently visually represents 'node'. More...
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? More...
bool idaapi | groups_are_present (void) const
| Is there any group node in the graph? More...
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'. More...
bool idaapi | delete_group (int group)
| Delete a group node. More...
bool idaapi | change_group_visibility (int group, bool expand)
| Expand/collapse a group node. More...
bool idaapi | change_visibility (const intvec_t &nodes, bool expand)
| Change visibility of multiple group nodes. More...
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'. More...
virtual void idaapi | resize (int n) GCC_PUREVIRT
| Resize the graph to 'n' nodes. More...
virtual int idaapi | add_node (const rect_t *r) GCC_PUREVIRT
| Add a node, possibly with a specific geometry. More...
virtual ssize_t idaapi | del_node (int n) GCC_PUREVIRT
| Delete a node. More...
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. More...
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
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
virtual rect_t &idaapi | nrect (int n)=0
virtual edge_info_t *idaapi | get_edge (edge_t e)=0
virtual drawable_graph_t *idaapi | clone (void) const =0
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
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 | size (void) const =0
virtual int idaapi | node_qty (void) const
virtual bool idaapi | exists (int node) const
virtual int idaapi | entry (void) const
virtual int idaapi | exit (void) const
virtual int idaapi | nsucc (int node) const =0
virtual int idaapi | npred (int node) const =0
virtual int idaapi | succ (int node, int i) const =0
virtual int idaapi | pred (int node, int i) const =0
virtual bool idaapi | empty (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 Types
typedef qvector< rect_t > | node_layout_t

## Friends
ssize_t idaapi | graph_dispatcher (void *, int code, va_list va)

## 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. More...
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'. More...

## Member Function Documentation

## ◆ size()

virtual int idaapi interactive_graph_t::size | ( | void |  | ) | const
| inline override virtual

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
| inline override virtual

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.

## ◆ empty()

bool idaapi interactive_graph_t::empty | ( | void |  | ) | const
| inline override virtual

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
| inline override virtual

Is the node visible?

Parameters

  node | the 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

  node | the node

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

## ◆ 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

  node | the 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

## ◆ 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

  nodes | the 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

  group | the 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

  group | the group node
  expand | whether 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

  nodes | the group nodes
  expand | whether to expand or collapse

Returns
  success (true if any group node was modified)

## ◆ nsucc()

virtual int idaapi interactive_graph_t::nsucc | ( | int | b | ) | const
| inline override virtual

Implements gdl_graph_t.

## ◆ npred()

virtual int idaapi interactive_graph_t::npred | ( | int | b | ) | const
| inline override virtual

Implements gdl_graph_t.

## ◆ succ()

virtual int idaapi interactive_graph_t::succ | ( | int | b,
|  | int | i
| ) |  | const
| inline override virtual

Implements gdl_graph_t.

## ◆ pred()

virtual int idaapi interactive_graph_t::pred | ( | int | b,
|  | int | i
| ) |  | const
| inline override virtual

Implements gdl_graph_t.

## ◆ 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

  n | the 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

  r | the 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

  n | the node to delete

Returns
  the number of deleted edges

## ◆ 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
| override virtual

Implements drawable_graph_t.

## ◆ nrect()

rect_t &idaapi interactive_graph_t::nrect | ( | int | n | ) |
| inline override virtual

Implements drawable_graph_t.

## ◆ get_edge()

virtual edge_info_t *idaapi interactive_graph_t::get_edge | ( | edge_t | e | ) |
| override virtual

Implements drawable_graph_t.

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

- graph.hpp