Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 09-23-2020, 06:40
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 725
Rept. Given: 35
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 666
Thanks Rcvd at 1,050 Times in 475 Posts
chants Reputation: 48
Using IDA Pro to generate Control Flow Graphs

Does anyone know a simple method to take IDA Pro to generate Control Flow Graphs (CFG) for each function in a very basic numbered edge format e.g. to graphviz or simply a list of successor nodes. The edges should be ordered by their occurrence or scanning/memory order. In other words, something like:
Code:
1 -> 2;
2 -> 3;
2 -> 4;
3 -> 5;
4 ->5;
Or even without the edges properly ordered as just a vertex successor list:
Code:
[2], [3, 4], [5], [5]
I know I could write a plugin to do this but it seems like such a basic task to generate CFGs that it would be nice not to reinvent the wheel if this is already possible.
Reply With Quote
  #2  
Old 09-23-2020, 10:22
TQN TQN is offline
VIP
 
Join Date: Apr 2003
Location: Vietnam
Posts: 341
Rept. Given: 142
Rept. Rcvd 20 Times in 12 Posts
Thanks Given: 166
Thanks Rcvd at 129 Times in 42 Posts
TQN Reputation: 20
You can see the code of Diaphora or FireEye SimplifyGraph.
Reply With Quote
The Following User Says Thank You to TQN For This Useful Post:
chants (09-23-2020)
  #3  
Old 09-23-2020, 13:03
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 725
Rept. Given: 35
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 666
Thanks Rcvd at 1,050 Times in 475 Posts
chants Reputation: 48
Yes perfect just what I was looking for. Am realizing I need a "legitimate" IDA Freeware 7.0 way to do this also . So for that there are no plugins, no IDAPython but the IDC scripting language should be enough to generate GDL files if enumerating all the functions and saving the files separately as can be done by the GUI. Also a method in IDC to save the call graph. The function CFGs and call graph and then GDL can be converted to a more basic format with a simple Python script or any number of graph tools. Otherwise I would need to buy a license. Although after doing that proof of legitimacy my preferred route is still to use the plugin you linked
Reply With Quote
  #4  
Old 09-24-2020, 00:31
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 725
Rept. Given: 35
Rept. Rcvd 48 Times in 30 Posts
Thanks Given: 666
Thanks Rcvd at 1,050 Times in 475 Posts
chants Reputation: 48
Anyone interested in doing this with IDA Free 7.0, I wrote the IDC script to do the job - will generate GDLs which are an easy to manipulate text graph format. Even many IDC commands are missing but fortunately I came up with a reasonable solution here:

Code:
static get_path_name(filepath)
{
	auto i = strlen(filepath) - 1;
	while (i != 0 && filepath[i] != "\\" && filepath[i] != "/") {
		i--;
	}
	return i == 0 ? filepath : filepath[:i];
}
static remove_bad_chars(name)
{
	auto filtered = "";
	auto i = strlen(name);
	auto c = 0;
	while (c < i) {
		if (strstr("/<>:\"\\|?*", name[c]) == -1) {
			filtered = filtered + name[c];
		}
		c++;
	}
	return filtered;
}
static gen_graphs()
{
	auto p = get_path_name(get_idb_path());
	auto r = get_root_filename();
	//CHART_GEN_GDL = 0x4000
	//FUNCATTR_END = 8
	call_system("mkdir \"" + p + "/" + r + "\"");
	gen_simple_call_chart(p + "/" + r + "/" + "calls", "", 0x4000);
	auto a;
	a = get_next_func(0);
	while (a != -1) {
		gen_flow_graph(p + "/" + r + "/func_" + remove_bad_chars(get_func_name(a)), "", a, get_func_attr(get_next_func(a), 8), 0x4000);
		a = get_next_func(a);
	}
}
Parsing it in Python is pretty easy using some regex tricks:
Code:
  def get_real_cfgs():
    import glob
    import os
    import re
    libNames = ["kernel32.dll"]
    allEdges = []
    for libName in libNames:
      for filePath in glob.glob(os.getenv("USERPROFILE") + "/Documents/" + libName + "/*.gdl"):
        edges = []
        with open(filePath) as fp:
          line = fp.readline()
          while line:
            match = re.search("^edge: { sourcename: \"(\w+)\" targetname: \"(\w+)\" label: \"\w+\" color: \w+ }\n$", line)
            if match is None: match = match = re.search("^edge: { sourcename: \"(\w+)\" targetname: \"(\w+)\" }\n$", line)
            if not match is None:
              edges.append((int(match[1]), int(match[2])))
            line = fp.readline()
        if len(edges) != 0: allEdges.append(edges)
    return allEdges

Last edited by chants; 09-24-2020 at 01:15.
Reply With Quote
The Following 3 Users Say Thank You to chants For This Useful Post:
niculaita (09-24-2020), SinaDiR (10-01-2020), TQN (11-14-2020)
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Net reactor 6x control flow remover and string decryptor Zeokat Source Code 0 11-14-2020 00:07
Vba2Graph - Generate call graphs from VBA code for easier analysis TechLord Source Code 0 08-31-2018 15:37
Interesting blog from Endgame on disarming Control Flow Guard in exploits MOV_EDI_EDI General Discussion 0 04-27-2017 07:57
What's the regular SDK compile flow with ECC check? bridgeic General Discussion 1 08-29-2014 09:14


All times are GMT +8. The time now is 18:38.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )