angr / angr

A powerful and user-friendly binary analysis platform!
http://angr.io
BSD 2-Clause "Simplified" License
7.48k stars 1.07k forks source link

What is the best practice to get CFGs of individual functions that also include inter-procedural edges? #3654

Open weixiao-zhan opened 1 year ago

weixiao-zhan commented 1 year ago

Question

I noticed

  1. graph_of_interest = [func.graph for func_addr, func in proj.kb.functions.items()] won't include inter-procedural edges, such as call edges.

  2. graph_of_interest = proj.analyses.CFGFast() a. would include many false functions and blocks. They are not reported in proj.kb.functions and indeed do not contain any instructions. b. appear to not include fall-through edges

So what is the best practice to get CFGs of individual functions and entire binary which also include inner-procedural fall-through and inter-procedural call edges?

ltfish commented 1 year ago

For the first question, can you try func.transition_graph? func.graph only includes nodes that are local to the function.

For the second question, what do you mean by "false functions and blocks?" An example on a binary would help me understand this better.

If you want to get "real" functions from kb.functions, remember to remove all functions whose .alignment = True.

So what is the best practice to get CFGs of individual functions and entire binary

For individual function CFGs, use proj.kb.functions[func_addr].transition_graph (as I explained before).

For the entire binary, use proj.analyses.CFGFast().model. It gives you a model with a full graph of all nodes in the CFG. You may also want to specify normalize=True when building the CFG to get an IDA-like, normalized CFG where nodes do not overlap with each other.