From 1c09f5ff01e58da876031a522389141de30b0be0 Mon Sep 17 00:00:00 2001 From: mrexodia Date: Tue, 12 Jul 2016 07:49:29 +0200 Subject: [PATCH] DBG: use BridgeCFGraph in RecursiveAnalysis --- src/dbg/analysis/recursiveanalysis.cpp | 12 +- src/dbg/analysis/recursiveanalysis.h | 146 ++++++++----------------- 2 files changed, 51 insertions(+), 107 deletions(-) diff --git a/src/dbg/analysis/recursiveanalysis.cpp b/src/dbg/analysis/recursiveanalysis.cpp index 7212f846..d50029af 100644 --- a/src/dbg/analysis/recursiveanalysis.cpp +++ b/src/dbg/analysis/recursiveanalysis.cpp @@ -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); } diff --git a/src/dbg/analysis/recursiveanalysis.h b/src/dbg/analysis/recursiveanalysis.h index 55cc29e4..b76da7b4 100644 --- a/src/dbg/analysis/recursiveanalysis.h +++ b/src/dbg/analysis/recursiveanalysis.h @@ -14,116 +14,56 @@ public: template using UintMap = std::unordered_map; - 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 nodes; //CFNode.start -> CFNode - UintMap 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;