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