Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing some of the functionality for IDA's graph viewer and the folding or unfolding of code. #145

Open
arizvisa opened this issue Oct 26, 2021 · 3 comments

Comments

@arizvisa
Copy link
Owner

This is a placeholder for a PR that will eventually expose some of IDA's graph viewer to the plugin. I'm waiting for some responses from hex-rays, but ideally the ability to group and ungroup graph nodes as well as hide and unhiding of code should be exposed.

@arizvisa
Copy link
Owner Author

For the first part, it's documented here at https://hex-rays.com/blog/igors-tip-of-the-week-31-hiding-and-collapsing/. Unfortunately you can't nest hidden ranges, which means we'll have to keep track of them ourselves and then update them only when we want to update the user-interface.

@arizvisa
Copy link
Owner Author

For the second part, here's my notes so far from looking at https://github.com/mandiant/SimplifyGraph. Unfortunately, it doesn't seem to work. I should be getting clarification on this though, soon...

old:
    tform = idaapi.get_current_tform()
    idaapi.BWN_DISASM == idaapi.get_tform_type(view)
    tcontrol = idaapi.get_tform_idaview(tform)
new:
    tcontrol = idaapi.get_current_viewer()
    #view = idaapi.get_graph_viewer(tw)
    idaapi.BWN_DISASM == idaapi.get_widget_type(tcontrol)
idaapi.TCCRT_GRAPH == idaapi.get_view_renderer_type(tcontrol)
mgraph = idaapi.get_viewer_graph(tcontrol)
cnode = idaapi.viewer_get_curnode(tcontrol)
?gv = idaapi.get_graph_viewer(tcontrol)

tcontrol = idaapi.get_current_viewer()
ni = idaapi.node_info_t()
cnode = idaapi.viewer_get_curnode(tcontrol)
ok = idaapi.viewer_get_node_info(tcontrol, ni, cnode)
print(ok)

@arizvisa
Copy link
Owner Author

I forgot to paste it into this issue. It seems that we should avoid the viewer stuff and focus on mutable_graph_t. Groups seem to be part of the "synthetic" view, and this will take some more fiddling to get things squared away.

Ftr, here's my exchange with them. Thanks to both Igor and Arnaud.

Hi Ali,

[first of all, sorry for the delay!]

On 10/27/21 21:24, Ali Rizvi-Santiago wrote:
> […]
> Not to be pedantic, you mentioned that `viewer_get_node_info()` would
> return data only for nodes changed from the default, but then included
> "group" in that list. Was that purposeful?

Yes, Igor wrote this on purpose: if you create a group in a graph
(either programmatically or through the UI) IDA will store the group
information about that "synthetic" (i.e., not part of the flow chart)
node in the IDB, using the `[gs]et_node_info` primitives.

> I'm asking because I had messed around with changing the text in a
> grouped node, and I couldn't get `set_node_info` or `get_node_info` to
> work, however `viewer_get_node_info` and `viewer_set_node_info` both
> seemed to have worked without issue. 

`[gs]et_node_info` should work too, provided you know the graph ID.

> As per your inclusion of "group",
> is the `viewer_*` functions the suggested way that I interact with the
> appearance of a node that has been grouped via
> `mutable_graph_t.create_group`, or are these `viewer_*` functions
> literally _only_ for things that the _user_ has modified from the
> default?

You should be able to use both `[gs]et_node_info`, and `viewer_*`
versions.

For example, assume the following:
- function at 0x8048450 w/ 4 nodes (0, 1, 2, 3)
- I created a group with 2nd & 3rd nodes, called 'test'
   (that'll be node 4)

Then, using the CLI:
---
Python>import ida_graph
Python>ni = ida_graph.node_info_t()
Python>gid = 0x8048450 # start of function; that's how IDA View-A
attributes graph IDs
Python>ida_graph.get_node_info(ni, gid, 4)
True
Python>ni.text
'test'
Python>ni2 = ida_graph.node_info_t()
Python>ida_view = ida_kernwin.find_widget("IDA View-A")
Python>gv = ida_graph.get_graph_viewer(ida_view)
Python>gv
<Swig Object of type 'TWidget *' at 0x7f7ab96befc0>
Python>ida_graph.viewer_get_node_info(gv, ni, 4)
True
Python>ni.text
'test'
Python>ida_graph.viewer_get_node_info(gv, ni, 0x1337)
False
---

So, in short, the benefit of using `viewer_*` variants, is pretty much
_only_ that they know the graph ID they are working with. Otherwise,
they're basically just wrappers around `[gs]et_node_info`.

Please let us know if that doesn't help!

Best regards,
          A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant