1
0
Fork 0

DBG: use BridgeCFGraph in RecursiveAnalysis

This commit is contained in:
mrexodia 2016-07-12 07:49:29 +02:00
parent e5c3370ae2
commit 1c09f5ff01
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
2 changed files with 51 additions and 107 deletions

View File

@ -23,7 +23,7 @@ void RecursiveAnalysis::SetMarkers()
{
if(mDump)
for(const auto & function : mFunctions)
FileHelper::WriteAllText(StringUtils::sprintf("cfgraph_" fhex ".dot", function.entryPoint), function.ToDot());
FileHelper::WriteAllText(StringUtils::sprintf("cfgraph_" fhex ".dot", function.entryPoint), GraphToDot(function));
//set function ranges
for(const auto & function : mFunctions)
@ -151,13 +151,17 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
addr += size;
}
}
//third pass: correct the parents
//third pass: correct the parents + add brtrue and brfalse to the exits
graph.parents.clear();
for(const auto & nodeIt : graph.nodes)
for(auto & nodeIt : graph.nodes)
{
const auto & node = nodeIt.second;
auto & node = nodeIt.second;
graph.AddParent(node.start, node.brtrue);
graph.AddParent(node.start, node.brfalse);
if(node.brtrue)
node.exits.push_back(node.brtrue);
if(node.brfalse)
node.exits.push_back(node.brfalse);
}
mFunctions.push_back(graph);
}

View File

@ -14,116 +14,56 @@ public:
template<class T>
using UintMap = std::unordered_map<duint, T>;
struct CFNode
using CFNode = BridgeCFNode;
using CFGraph = BridgeCFGraph;
static String NodeToString(const CFNode & n)
{
duint parentGraph; //function of which this node is a part
duint start; //start of the block
duint end; //end of the block (inclusive)
duint brtrue; //destination if condition is true
duint brfalse; //destination if condition is false
duint icount; //number of instructions in node
bool terminal; //node is a RET
bool split; //node is a split (brtrue points to the next node)
return StringUtils::sprintf("start: " fhex ", %" fext "d\nend: " fhex "\nfunction: " fhex, n.start, n.icount, n.end, n.parentGraph);
}
explicit CFNode(duint parentGraph, duint start, duint end)
: parentGraph(parentGraph),
start(start),
end(end),
brtrue(0),
brfalse(0),
icount(0),
terminal(false),
split(false)
{
}
explicit CFNode()
: CFNode(0, 0, 0)
{
}
String ToString() const
{
return StringUtils::sprintf("start: " fhex ", %" fext "d\nend: " fhex "\nfunction: " fhex, start, icount, end, parentGraph);
}
};
struct CFGraph
static const char* GetNodeColor(const CFGraph & graph, const CFNode & node)
{
duint entryPoint; //graph entry point
UintMap<CFNode> nodes; //CFNode.start -> CFNode
UintMap<UintSet> parents; //CFNode.start -> parents
if(node.terminal)
return "firebrick";
if(node.start == graph.entryPoint)
return "forestgreen";
return "lightblue";
}
explicit CFGraph(duint entryPoint)
: entryPoint(entryPoint)
static String GraphToDot(const CFGraph & graph)
{
String result = "digraph CFGraph {\n";
for(const auto & node : graph.nodes)
result += StringUtils::sprintf(" n" fhex "[label=\"%s\" style=filled fillcolor=%s shape=box]\n",
node.second.start,
NodeToString(node.second).c_str(),
GetNodeColor(graph, node.second));
result += "\n";
for(const auto & node : graph.nodes)
{
}
void AddNode(const CFNode & node)
{
nodes[node.start] = node;
AddParent(node.start, node.brtrue);
AddParent(node.start, node.brfalse);
}
void AddParent(duint child, duint parent)
{
if(!child || !parent)
return;
auto found = parents.find(child);
if(found == parents.end())
{
UintSet p;
p.insert(parent);
parents[child] = p;
}
else
found->second.insert(parent);
}
const char* GetNodeColor(const CFNode & node) const
{
if(node.terminal)
return "firebrick";
if(node.start == entryPoint)
return "forestgreen";
return "lightblue";
}
String ToDot() const
{
String result = "digraph CFGraph {\n";
for(const auto & node : nodes)
result += StringUtils::sprintf(" n" fhex "[label=\"%s\" style=filled fillcolor=%s shape=box]\n",
if(node.second.brtrue)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [color=%s]\n",
node.second.start,
node.second.ToString().c_str(),
GetNodeColor(node.second));
result += "\n";
for(const auto & node : nodes)
{
if(node.second.brtrue)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [color=%s]\n",
node.second.start,
node.second.brtrue,
node.second.split ? "black" : "green");
if(node.second.brfalse)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [color=red]\n",
node.second.start,
node.second.brfalse);
}
result += "\n";
for(const auto & parent : parents)
{
for(const auto & node : parent.second)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [style=dotted color=grey]\n",
node,
parent.first);
}
result += "}";
return result;
node.second.brtrue,
node.second.split ? "black" : "green");
if(node.second.brfalse)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [color=red]\n",
node.second.start,
node.second.brfalse);
}
};
result += "\n";
for(const auto & parent : graph.parents)
{
for(const auto & node : parent.second)
result += StringUtils::sprintf(" n" fhex "-> n" fhex " [style=dotted color=grey]\n",
node,
parent.first);
}
result += "}";
return result;
}
protected:
duint mEntryPoint;