DBG: use BridgeCFGraph in RecursiveAnalysis
This commit is contained in:
parent
e5c3370ae2
commit
1c09f5ff01
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue