8

Extracting control flow graph in JSON with radare2: $> python import r2pipe r2 = r2pipe.open("/bin/ls") r2.cmd("aaa") # See radare.today/posts/analysis-by-default/ cfg = r2.cmdj("agj") https://github.com/radare/radare2-bindings/tree/master/r2pipe/python


8

The ag command and subcommands can help you to output the visual graph into Graphviz format. [0x00000000]> ag? Usage: ag<graphtype><format> [addr] Graph commands: | aga[format] Data references graph .... | agf[format] Basic blocks function graph .... Output formats: | <blank> Ascii art | * ...


7

I wrote an article on that very topic about 20 years ago. It's titled Assembly Language Control Flow Graphing and was published in the September 1998 issue of Dr. Dobb's Journal. It used Perl to parse the assembly code to generate a Postscript representation of the control flow graph. That graph then can either be printed or viewed on screen by anything ...


7

In fact, you have many of these tools. Mostly, what you seems to need is what is called symbolic execution of binary programs which requires to translate the semantics of the assembly language into an intermediate language to pass it to an SMT-solver that handle bit-vector logic formula (usually Z3). But, beware, not all tools support the translation to an ...


6

For now, the most efficient approaches in practice seems to follow the principle of symbolic execution. This technique, originally developed to automatically build-up a set of test cases based on a given source code, has been recently used in binary analysis to discover and (partially) recover the CFG of the analyzed binary program. Most of the time, if you ...


4

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


4

It depends on target's assembly language and compiler which your executable was compiled with. For example C language switch/case clause may be implemented in a manner which allows your tree to be not binary. switch (a) { case 1: return 1; break; case 2: return 10; break; case 3: return 100; break; case 4: return 1000; break; case 5: ...


4

Although Nirlzr's answer explains it pretty well, here's an example that considers C++ code and vtables are present. The code is taken from here #include <iostream> using namespace std; class Vehicle { public: virtual void ApplyBreaks() { cout << "Vehicle Break" << endl; } virtual void ApplyHorns() { cout << "Vehicle Horns" <&...


4

If you want to get a node and edge count for a function's graph in IDA, you can calculate it with the given IDAPython code: func = idaapi.get_func(here()) g = idaapi.FlowChart(func) nodes = 0 edges = 0 for x in g: nodes += 1 for succ in x.succs(): edges += 1 for pred in x.preds(): edges += 1 print "Number of nodes", nodes print "Number of ...


3

However I don't know how to get the function calls from the nodes Are you saying you want to know which function a node belongs to, or which function a node is calling? For the former, each block has a corresponding CFGNode object that are in the graph. Each CFGNode has a .function_address member, which tells you the address of the function that the node ...


2

You could look at the radare project: https://github.com/radare/radare2 Their ESIL representation of mnemonics can help you track down the access to variables, registers and even flags. https://radare.gitbooks.io/radare2book/content/disassembling/esil.html For example, inc edi will result in edi,++=,$o,of,=,$s,sf,=,$z,zf,=,$p,pf,=


2

I am sorry for this self-advertisement, but I am developing a tool here. My final goal is to recover the original control flow graph of virtualized binaries. But at a step of this, for visualization purpose, I have implemented a functionality to reconstruct the CFG of binaries from traces. The main implementation of this reconstrution is in the file src/lib/...


2

If there are no other references, this indicates there are no call sub_xyz (that IDA identified, at least). Instead, IDA only identified one cross-reference to sub_xyz, and that reference was a hardcoded offset in a data variable. Usually, there's a piece of code that accesses that data and indirectly calls the function, so you could search for cross-...


1

After a few days of trial and error I figured out something called GhidraDev which is an add-on to eclipse, through it you can create your own Ghidra projects and use the API with ease. Instructions on how to install it into eclipse can be found in ghidra_9.0.4 -> Extensions -> Eclipse -> GhidraDev -> GhidraDev_README.html. Ghidra can be downloaded here: ...


1

You can do this using [headless analyser] (https://ghidra.re/ghidra_docs/analyzeHeadlessREADME.html#recursive) script. Check out it's usage here. You can find this file in ghidhra/support directory. The ghidra api is available here. You can use this api to write custom scripts, either in java or python 2.7. Then you can do: ./analyzeHeadless /...


1

A nice framework to look at is Triton which does a good job in Dynamic Symbolic Execution. I ended up looking at the code and implementing my own solution with their same approach.


1

One would have to look at the code. How are the jump targets calculated? From your diagrams it could also be something as simple as: void jump_to_x_plus_5(uint x) { jmp x+5; } void jump_to_x_plus_7(uint x) { jmp x+7; } void jump_to_x_plus_9(uint x) { jmp x+9; } And they just replaced all absolute jumps in the .asm with calls to random.choice() of those ...


1

FWIW: I managed to restore the original graph by undefining the whole function, then recreate it one opcode at a time, starting from the bottom. At each step I made sure to switch into graph view - and at some point IDA drew a graph that was complete gibberish. I then right-clicked and selected the "Layout Graph" option, and viola - the complete graph of ...


1

It may be a result of unrecognized or misunderstood switch/case. Please post all the assembly code of the function - this will probably help to locate it.


1

Angr (breaks easily or computes forever) If you are still interested in finding a solution, you might want to give angr another try. You should hop on our slack channel (angr.slack.com, please get an invite from http://angr.io) so we can solve any CFG recovery issues together. I believe angr gives you the best flexibility out of all solutions you have ...


1

To make IDA recognize the code as a procedure, press P at the start of it. Ida "automatically presses the P key" if it sees a direct call to that address. However, if the source code was C++ or another language with classes, the function might never be called directly, only indirectly through the vtable (table of method start addresses) of the class. In ...


1

Sadly, there is no out-of-the-box solution. Even in academic research, most projects tackling this issue are heavily restricted. To be able to reconstruct the control flow graph, you would need information about all possible values for the arguments of objc_msgSend in order to figure out which function is invoked on which object. This problem is potentially ...


Only top voted, non community-wiki answers of a minimum length are eligible