7

Lately I'm using Ghidra and I don't find the API to get the control flow graph of a given function. Can someone help me?

Thank you in advance.

EDIT: it is different from the other question (link) because I'm asking for the API.

5
  • Possible duplicate of How to display the CFG of a function in Ghidra?
    – perror
    Mar 18, 2019 at 8:54
  • 1
    I edited. I'm asking for the API, so it is not a duplicate.
    – Benny
    Mar 18, 2019 at 9:46
  • 2
    Hi and welcome to RE.SE! Could you be more specific on what you want to do with the flow graphs? Layout? Create your own? The api is pretty vast ghidra.re/ghidra_docs/api/index-all.html
    – Nordwald
    Mar 18, 2019 at 10:27
  • 1
    Hi! Given a function, I need to extract its CFG so as to count its edges and nodes for computing the cyclomatic complexity and other metrics. I already browsed through Ghidra's documentation, but I didn't find what I need.
    – Benny
    Mar 18, 2019 at 10:52
  • 1
    I used calculateCyclomaticComplexity​ function to compute the cyclomatic complexity, but I found no API to explicitly generate a control flow graph from which I can extract nodes and edges.
    – Benny
    Mar 18, 2019 at 11:03

1 Answer 1

6

I'm looking for the same thing and for now I found the class PcodeSyntaxTree having a method called getBasicBlocks(), which returns an array of PcodeBlockBasic elements. This second class has methods like getIn and getOut which retrieve incoming and outgoing nodes (basic blocks), respectively. So I think using this methods should be the interface for interacting with the CFG programmatically. But sadly I didn't figure out yet how to get this PcodeSyntaxTree object, but will continue investigating.

I hope this can help you a bit!

links: http://ghidra.re/ghidra_docs/api/ghidra/program/model/pcode/PcodeSyntaxTree.html http://ghidra.re/ghidra_docs/api/ghidra/program/model/pcode/PcodeBlockBasic.html

PS.: Other thing you can do is to study the code of calculateCyclomaticComplexity​ method, which uses this BasickBlock models, I think I will probably do that.

EDIT: good news I think. I found the DecompleResults class, having the method getHighFunction() which returns a HighFunction object. HighFunction class extends to PcodeSyntaxTree, so it has also the getBasicBlocks method. From that point you can go on.

DecompileResults class is contained in ghidra.app.decompiler, as well as DecompInterface, which has the decompileFunction() method that returns a DecompileResults object.

From https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java :

// Make calls to the decompiler: 
// *   DecompileResults res = ifc.decompileFunction(func,0,taskmonitor);

links: https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java

https://ghidra.re/ghidra_docs/api/ghidra/app/decompiler/DecompileResults.html https://ghidra.re/ghidra_docs/api/ghidra/program/model/pcode/HighFunction.html

EDIT 2:

I can imagine something like this (in python api):

import ghidra.app.decompiler as decomp

interface = decomp.DecompInterface()

# decompileFunction(function, timeout, monitor)
# according to documentation, function is a Function object, timeout is int,
# and monitor is an OPTIONAL ARGUMENT of TaskMonitor type. 
# However, it doesn't say anything about a default value for this argument 
# and omitting the arg in the call falls in an error.

results = interface.decompileFunction(func, 0, taskMonitor)
hf = results.getHighFunction()

bbList = hf.getBasicBlocks()

# ...
# ...
# ...

5
  • Great, you helped me a lot, thank you so much!
    – Benny
    May 17, 2019 at 17:43
  • You're welcome! btw, I've found another useful information, check this answer in a reported issue: github.com/NationalSecurityAgency/ghidra/issues/… I'm using that Block Model due I couldn't figure out yet how to properly create and configure an instance of the DecompInterface class May 20, 2019 at 13:19
  • @MauricioSanfilippo did the code above work for you. I used TaskMonitor.DUMMY as for the third parameter and passed a Function objrct but nothing get disassembled for me. Did you find a solution?
    – hEShaN
    Jul 19, 2020 at 20:10
  • @hEShaN Nope, I couldn't figure out how to use the DecompInterface. But I went with the SimpleBlockModel approach, which worked fine for me and it seems to be even simpler. You can read github.com/NationalSecurityAgency/ghidra/issues/… I created some scripts to get and traverse the graph, I can share them with you if you want. It's mostly ad-hoc but it worked, maybe you can improve them if they don't work for you as they currently are Jul 20, 2020 at 21:27
  • thank you very much. Do u have a link to those scripts. Thanks again!
    – hEShaN
    Jul 21, 2020 at 2:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.