/************************************************************************** * Main function. This function is run on each node that is being traversed * in the graph. For each node, we determine the successors and check * if those have been previously seen. If yes, a cycle may exist. **************************************************************************/ bool CompassAnalyses::CycleDetection::Traversal::run(string& name, SgGraphNode* node, SgGraphNode* previous){ // check known function calls and resolve variables ROSE_ASSERT(node); //cerr << " cycledetection->run " << node->get_name() << endl; SgAsmFunction* func = isSgAsmFunction(node->get_SgNode()); if (func) { // if the node is a function, we clear the visited nodes // this should speed up our search visited.clear(); return false; } successors.clear(); ROSE_ASSERT(vizzGraph); vizzGraph->getSuccessors(node, successors); vector<SgGraphNode*>::iterator succ = successors.begin(); for (;succ!=successors.end();++succ) { // for each successor do... SgGraphNode* next = *succ; // if the node is an instruction, we check if it was visited // if not, we add it to the visited set, otherwise a cycle is present std::set<SgGraphNode*>::iterator it =visited.find(next); if (it!=visited.end()) { // found this node in visited list SgAsmX86Instruction* nodeSg = isSgAsmX86Instruction(node->get_SgNode()); SgAsmX86Instruction* nextSg = isSgAsmX86Instruction(next->get_SgNode()); if (debug) { std::string outputText = "Found possible cycle between "; outputText+=stringifyX86InstructionKind(nodeSg->get_kind()) + " ("; outputText+=RoseBin_support::HexToString(nodeSg->get_address()) + ") and "; outputText+=stringifyX86InstructionKind(nextSg->get_kind()) + " ("; outputText+=RoseBin_support::HexToString(nextSg->get_address()) + ")"; std::cerr << outputText << std::endl; output->addOutput(new CheckerOutput(nodeSg, outputText)); } bool validCycle = checkIfValidCycle(node,next); if (validCycle) { std::string outputText = "Found cycle between "; outputText+=stringifyX86InstructionKind(nodeSg->get_kind()) + " ("; outputText+=RoseBin_support::HexToString(nodeSg->get_address()) + ") and "; outputText+=stringifyX86InstructionKind(nextSg->get_kind()) + " ("; outputText+=RoseBin_support::HexToString(nextSg->get_address()) + ")"; std::cerr << outputText << std::endl; output->addOutput(new CheckerOutput(nodeSg, outputText)); cycleFound[node]=next; } else { if (debug) std::cerr << "This is not a cyclic node " << std::endl; } } } visited.insert(node); return false; }
void AstDOTGeneration::writeIncidenceGraphToDOTFile(SgIncidenceDirectedGraph* graph, const std::string& filename) { // Output all nodes rose_graph_integer_node_hash_map & nodes = graph->get_node_index_to_node_map (); for( rose_graph_integer_node_hash_map::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgGraphNode* node = it->second; if( commentOutNodeInGraph(node) == false ) { string nodeoption; string nodelabel=string("\\n")+node->get_name(); nodelabel += additionalNodeInfo(node); string additionalOptions = additionalNodeOptions(node); string x; string y; x += additionalOptions; nodeoption += additionalOptions; // dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); dotrep.addNode(node,nodelabel,nodeoption); addAdditionalNodesAndEdges(node); } } // Output edges rose_graph_integer_edge_hash_multimap & outEdges = graph->get_node_index_to_edge_multimap_edgesOut (); for( rose_graph_integer_edge_hash_multimap::const_iterator outEdgeIt = outEdges.begin(); outEdgeIt != outEdges.end(); ++outEdgeIt ) { // if(debug) std::cerr << " add edge from node ... " << std::endl; // debug SgDirectedGraphEdge* graphEdge = isSgDirectedGraphEdge(outEdgeIt->second); ROSE_ASSERT(graphEdge!=NULL); if ( commentOutNodeInGraph(graphEdge) == false ) { string edgelabel=string("\\n")+graphEdge->get_name(); string edgeoption = additionalEdgeOptions(graphEdge->get_from(),graphEdge->get_to(),edgelabel); dotrep.addEdge(graphEdge->get_from(),edgelabel,graphEdge->get_to(),edgeoption + "dir=forward"); addAdditionalNodesAndEdges(graphEdge); } } dotrep.writeToFileAsGraph(filename); }
void CompassAnalyses::BinaryInterruptAnalysis::Traversal::getValueForDefinition(std::vector<uint64_t>& vec, std::vector<uint64_t>& positions, uint64_t& fpos, SgGraphNode* node, std::pair<X86RegisterClass, int> reg ) { set <SgGraphNode*> defNodeSet = getDefFor(node, reg); if (RoseBin_support::DEBUG_MODE()) cout << " size of found NodeSet = " << defNodeSet.size() <<endl; set <SgGraphNode*>::const_iterator it = defNodeSet.begin(); for (;it!=defNodeSet.end();++it) { SgGraphNode* defNode = *it; if (RoseBin_support::DEBUG_MODE() && defNode) cout << " investigating ... " << defNode->get_name() <<endl; ROSE_ASSERT(defNode); SgAsmx86Instruction* inst = isSgAsmx86Instruction(defNode->get_SgNode()); ROSE_ASSERT(inst); positions.push_back(inst->get_address()); // the right hand side of the instruction is either a use or a value bool memRef = false, regRef = false; std::pair<X86RegisterClass, int> regRight = check_isRegister(defNode, inst, true, memRef, regRef); if (RoseBin_support::DEBUG_MODE()) { string regName = unparseX86Register(RegisterDescriptor(reg.first, reg.second, 0, 64), NULL); string regNameRight = unparseX86Register(RegisterDescriptor(regRight.first, regRight.second, 0, 64), NULL); cout << " VarAnalysis: getValueForDef . " << regName << " right hand : " << regNameRight <<endl; } if (!regRef) { // it is either a memref or a value if (!memRef) { // get value of right hand side instruction uint64_t val = getValueOfInstr(inst, true); vec.push_back(val); fpos = inst->get_address(); if (RoseBin_support::DEBUG_MODE()) cout << " found valueOfInst = " << RoseBin_support::ToString(val) <<endl; } } else { // it is a register reference. I.e we need to follow the usage edge to find the // definition of that node SgGraphNode* usageNode = g_algo->getDefinitionForUsage(vizzGraph,defNode); if (usageNode && usageNode!=node) { if (RoseBin_support::DEBUG_MODE() && usageNode) cout << " following up usage for " << usageNode->get_name() <<endl; getValueForDefinition(vec, positions, fpos, usageNode, regRight); } else { // we look at the same node. cout << " ERROR :: Either following usage to itself or usageNode = NULL. " << usageNode << endl; } } } }
foreach(SgDirectedGraphEdge *edge, edges) { SgGraphNode *toNode = edge->get_to(); SgFunctionDeclaration *toDecl = isSgFunctionDeclaration(toNode->get_SgNode()); ROSE_ASSERT(toDecl != NULL); if(toDecl->get_specialFunctionModifier().isConstructor() || toDecl->get_specialFunctionModifier().isDestructor()) continue; if(find(functions.begin(), functions.end(), toDecl) == functions.end()) { graph->removeDirectedEdge(edge); std::cout << "Edge removed from " << defDecl->get_qualified_name().getString() << " to " << toDecl->get_qualified_name().getString()<< std::endl; } }
void RoseBin_ControlFlowAnalysis::getCFGNodesForFunction(std::set<SgGraphNode*>& visited_f, std::set<std::string>& visited_names, SgGraphNode* next_n, std::string nodeName){ #if 1 ASSERT_not_reachable("no longer supported"); #else // traverse the graph from next to node std::vector<SgGraphNode*> successors_f; // std::set<SgGraphNode*> visited_f; //std::set<std::string> visited_names; vector<SgGraphNode*> worklist; worklist.push_back(next_n); visited_f.insert(next_n); visited_names.insert(nodeName); while (!worklist.empty()) { SgGraphNode* current = worklist.back(); worklist.pop_back(); successors_f.clear(); vizzGraph->getSuccessors(current, successors_f); vector<SgGraphNode*>::iterator succ = successors_f.begin(); for (;succ!=successors_f.end();++succ) { SgGraphNode* next = *succ; std::set<SgGraphNode*>::iterator it =visited_f.find(next); if (sameParents(current,next)) if (it==visited_f.end()) { // if (sameParents(current,next)) worklist.push_back(next); visited_f.insert(next); SgNode* internal = next->get_SgNode(); SgAsmInstruction* inst = isSgAsmInstruction(internal); if (inst) { string name = RoseBin_support::HexToString(inst->get_address()); if (debug) cerr << " adding node to function : ."<<name<<"."<<endl; visited_names.insert(name); } } } // for } // while #endif }
SgGraphNode* RoseBin_FlowAnalysis::addCFNode(string& name, string& type, int address, bool isFunction, SgNode* int_node) { ROSE_ASSERT(int_node); ostringstream addrhex; addrhex << hex << setw(8) << address ; string addr_str = addrhex.str(); SgGraphNode* n_source = NULL; if (isFunction) { addr_str+="_f"; } rose_graph_string_integer_hash_multimap::iterator name_iterator = vizzGraph->get_string_to_node_index_multimap().find(addr_str); if (name_iterator == vizzGraph->get_string_to_node_index_multimap().end()) { n_source=vizzGraph->addNode(addr_str,int_node); ROSE_ASSERT(n_source); //cerr << " ............ RoseBin_FlowAnalysis >>>>>>>>>>>>>>>> Adding node : " << // addr_str << " idx: " << n_source->get_index() << endl; n_source->append_properties(SgGraph::name, name); n_source->set_SgNode(int_node); //n_source->set_type(type); } else { // exit(1); int index = name_iterator->second; ROSE_ASSERT(index>=0); rose_graph_integer_node_hash_map themap = vizzGraph->get_node_index_to_node_map(); //cerr << " RoseBin_FlowAnalysis -- NODE ALREADY EXISTS! at index: " << index << endl; rose_graph_integer_node_hash_map::iterator it = themap.find(index); if (it==themap.end()) { ROSE_ASSERT(false); } SgGraphNode* node = it->second; ROSE_ASSERT(node->get_SgNode()); return node; } ROSE_ASSERT(n_source->get_SgNode()); return n_source; }
void RoseBin_FlowAnalysis::getRootNodes(vector <SgGraphNode*>& rootNodes) { nrOfFunctions=0; ROSE_ASSERT(vizzGraph); //cerr << " get Root nodes " << endl; rose_graph_integer_node_hash_map::const_iterator itn = vizzGraph->get_node_index_to_node_map().begin(); for (; itn!=vizzGraph->get_node_index_to_node_map().end();++itn) { // string hex_address = itn->first; SgGraphNode* node = isSgGraphNode(itn->second); string hex_address = node->get_name(); //ROSE_ASSERT(hex_address==hex_addr_tmp); SgNode* internal = node->get_SgNode(); SgAsmFunction* func = isSgAsmFunction(internal); if (func) { rootNodes.push_back(node); //cerr << " ............................. rootNode : " << hex_address << " " << node->get_name() << endl; nrOfFunctions++; } } }
void RoseBin_DataFlowAnalysis::traverseNodes(RoseBin_DataFlowAbstract* analysis) { if (RoseBin_support::DEBUG_MODE_MIN()) cerr << " >> Traversing over all nodes and adding label ... " << endl; rose_graph_integer_node_hash_map::iterator itn = vizzGraph->get_node_index_to_node_map().begin(); for (; itn!=vizzGraph->get_node_index_to_node_map().end();++itn) { SgGraphNode* node = isSgGraphNode(itn->second); ROSE_ASSERT(node); SgNode* internal = node->get_SgNode(); ROSE_ASSERT(internal); SgAsmInstruction* inst = isSgAsmInstruction(internal); if (inst) { uint64_t address = inst->get_address(); RoseBin_Variable* var = analysis->getVariable(address); if (var) { std::string var_str = var->toString(); node->append_properties(SgGraph::variable,var_str); } } } }
std::set < uint64_t > RoseBin_DataFlowAnalysis::getDefForInst( uint64_t inst, std::pair<X86RegisterClass, int> initName) { std::set <uint64_t> hexSet; SgGraphNode* node = getNodeFor(inst); if (node==NULL) cerr << "ERROR: getDefForInst " << RoseBin_support::HexToString(inst) << " does not exist! " << endl; set<SgGraphNode*> nodes = defuse->getDefFor(node, initName); set<SgGraphNode*>::iterator it = nodes.begin(); for (;it!=nodes.end();++it) { SgGraphNode* n = *it; if (n) { SgAsmInstruction* instNode = isSgAsmInstruction(n->get_SgNode()); if (instNode) { hexSet.insert(instNode->get_address()); //cerr << "INSERT: getDefForInst " << //RoseBin_support::HexToString(instNode->get_address()) << endl; } } } return hexSet; }
void RoseBin_DataFlowAbstract::printDefTableToFile( std::string fileName) { std::ofstream myfile; myfile.open(fileName.c_str()); vector<SgGraphNode*> sorted; tabletype::iterator it2 = deftable.begin(); for (;it2!=deftable.end();++it2) { SgGraphNode* node = it2->first; sorted.push_back(node); } std::sort(sorted.begin(), sorted.end()); // tabletype::iterator it = deftable.begin(); //for (;it!=deftable.end();++it) { vector<SgGraphNode*>::iterator it = sorted.begin(); for (;it!=sorted.end();++it) { // SgGraphNode* node = it->first; SgGraphNode* node = *it; // const multitype& type = getDefinitionsFor(node); const multitype& type = getDefMultiMapFor(node); multitype::const_iterator itm = type.begin(); if (node) { string line = ""+node->get_name()+" : \n"; for (;itm!=type.end();++itm) { std::pair<X86RegisterClass, int> code = itm->first; SgGraphNode* nodeDef = itm->second; string registerName = unparseX86Register(RegisterDescriptor(code.first, code.second, 0, 64)); string def = registerName+" - "+nodeDef->get_name(); line+=" "+def+"\n"; } myfile << line ; } } myfile.close(); }
void CFG::buildCFG(CFGNode n) { ROSE_ASSERT(n.getNode()); if (explored_.count(n) > 0) return; explored_.insert(n); SgGraphNode* from = NULL; if (all_nodes_.count(n) > 0) { from = all_nodes_[n]; } else { from = new SgGraphNode; from->set_SgNode(n.getNode()); from->addNewAttribute("info", new CFGNodeAttribute(n.getIndex(), graph_)); all_nodes_[n] = from; graph_->addNode(from); } std::vector<VirtualCFG::CFGEdge> outEdges = n.outEdges(); foreach (const VirtualCFG::CFGEdge& edge, outEdges) { CFGNode tar = edge.target(); SgGraphNode* to = NULL; if (all_nodes_.count(tar) > 0) to = all_nodes_[tar]; else { to = new SgGraphNode; to->set_SgNode(tar.getNode()); to->addNewAttribute("info", new CFGNodeAttribute(tar.getIndex(), graph_)); all_nodes_[tar] = to; graph_->addNode(to); } graph_->addDirectedEdge(new SgDirectedGraphEdge(from, to)); }
/*********************************************************************** * (10/31/07) tps: Traverses the graph for each node in rootNodes * and applies to each node the evaluate function * which can be either def_use, variable detection or emulation * Each node in the controlflow of rootNode is traversed (forward) * and only if the hasChanged function returns false, the algorithm * comes to a fixpoint ***********************************************************************/ void RoseBin_DataFlowAnalysis::traverseGraph(vector <SgGraphNode*>& rootNodes, RoseBin_DataFlowAbstract* analysis, bool interprocedural){ if (RoseBin_support::DEBUG_MODE_MIN()) cerr << " traverseGraph : debug: " << RoseBin_support::resBool(RoseBin_support::DEBUG_MODE()) << " debug_min : " << RoseBin_support::resBool(RoseBin_support::DEBUG_MODE_MIN()) << endl; // Number of functions traversed int funcNr =0; // --------------------------------------------------------------------- // stores the nodes that still needs to be visited // vector<SgGraphNode*> worklist; deque<SgGraphNode*> worklist; nodeHashSetType worklist_hash; // a vector of successors of the current node vector<SgGraphNode*> successors; // --------------------------------------------------------------------- // iterate through all functions vector<SgGraphNode*>::iterator it = rootNodes.begin(); for (; it!=rootNodes.end();++it) { // current node SgGraphNode* node = *it; string func_name = vizzGraph->getProperty(SgGraph::name, node); RoseBin_support::checkText(func_name); funcNr++; if (RoseBin_support::DEBUG_MODE()) { cout << "\n\n ----------- dataflow analysis of function ("+RoseBin_support::ToString(funcNr)+"/"+ RoseBin_support::ToString(rootNodes.size())+") : " << func_name << " visited size : " << visited.size() << " total visited nodes : " << nrOfNodesVisited << endl; // debug } if (RoseBin_support::DEBUG_MODE_MIN()) { cerr << " ----------- dataflow analysis of function ("+RoseBin_support::ToString(funcNr)+"/"+ RoseBin_support::ToString(rootNodes.size())+") : " << func_name << " visited size : " << visited.size() << " total visited nodes : " << nrOfNodesVisited << " def size : " << analysis->getDefinitionSize() << endl; } // indicates whether the current value for this node has changed bool hasChanged=false; // pushback into worklist and visited list worklist.push_back(node); worklist_hash.insert(node); visited.insert(node); visitedCounter[node] = 1; vector <SgGraphNode*> pre; // while there are still graph nodes in the worklist do while (worklist.size()>0) { nrOfNodesVisited++; // the new node is taken from the back of the worklist //node = worklist.back(); //worklist.pop_back(); node = worklist.front(); worklist.pop_front(); worklist_hash.erase(node); // get the successors of the current node and store in successors vector string name = vizzGraph->getProperty(SgGraph::name, node); //if (RoseBin_support::DEBUG_MODE_MIN() && node) // if (node->get_SgNode()) // cerr << node->get_SgNode()->class_name() << " " << node << " " << node->get_name() << endl; if (RoseBin_support::DEBUG_MODE_MIN() && node) { SgAsmInstruction* instr = isSgAsmInstruction(node->get_SgNode()); if (instr) { SgAsmFunction* funcParent = isSgAsmFunction(instr->get_parent()); if (funcParent) { string parent = funcParent->get_name(); cout << " ---- analysis of node in function : " << parent << " defs " << analysis->getDefinitionSize() << " visited : " << RoseBin_support::ToString(visitedCounter[node]) << endl; } } } if (RoseBin_support::DEBUG_MODE()) cout << "\n evaluating: " << name << endl; // do something with the current node // e.g. checkVariables(name, node); SgGraphNode* nodeBefore= NULL; BeforeMapType::const_iterator it = nodeBeforeMap.find(node); if (it!=nodeBeforeMap.end()) nodeBefore = it->second; // successor vector is empty on each new node successors.clear(); ROSE_ASSERT(isSgIncidenceDirectedGraph(vizzGraph)); isSgIncidenceDirectedGraph(vizzGraph)->getSuccessors(node, successors); hasChanged = analysis->run(name, node, nodeBefore); // append the successors to the worklist if (RoseBin_support::DEBUG_MODE()) cout << ">> getting successors (" << successors.size() << ") for : " << name << endl; // if (successors.size()==0) // cout << "PROBLEM ..................................................... : " << endl; vector<SgGraphNode*>::iterator succ = successors.begin(); for (;succ!=successors.end();++succ) { // for each successor do... SgGraphNode* next = *succ; SgAsmX86Instruction* nodeN = isSgAsmX86Instruction(node->get_SgNode()); //if (!nodeN) continue; SgAsmX86Instruction* nextN = isSgAsmX86Instruction(next->get_SgNode()); //if (!nextN) continue; string name_n = vizzGraph->getProperty(SgGraph::name, next); bool call = false; bool exceptionCallNext = false; if (nextN) exceptionCallNext = exceptionCall(nextN->get_kind() == x86_call ? nextN : 0); bool exceptionCallNode = false; if (nodeN) exceptionCallNode = exceptionCall(nodeN->get_kind() == x86_call ? nodeN : 0); if (RoseBin_support::DEBUG_MODE()) std::cout << " exceptionCallNode : " << exceptionCallNode << " exceptionCallNext : " << exceptionCallNext << endl; // if function call is call to malloc we have an exception and follow the call path if ((exceptionCallNode && !exceptionCallNext)) { } else if ( //if ( (nodeN && nodeN->get_kind() == x86_call) || (nextN && nextN->get_kind() == x86_ret) ) call = true; //bool sameParent = analysis->sameParents(node, next); bool validNode=false; if (g_algo->isValidCFGEdge(next, node) || exceptionCallNode) validNode = true; // debug ------------------------ if (RoseBin_support::DEBUG_MODE()) { string nodeBeforeStr=""; if (nodeBefore) nodeBeforeStr= nodeBefore->get_name(); cout << " DEBUG : >>>>>>>> previous node " << nodeBeforeStr << " This node : " << name << " next node : " << name_n << " ** validNode : " << RoseBin_support::resBool(validNode) << endl; } // ---------------------------------- if (( interprocedural==false && !call) // || (interprocedural==true && validNode)) { if (visited.find(next)==visited.end()) { // if the successor is not yet visited // mark as visited and put into worklist if (RoseBin_support::DEBUG_MODE()) cout << " never visited next node before... " << name_n << " interprocedural : " << interprocedural << " call : " << call << endl; if (RoseBin_support::DEBUG_MODE()) cout << "adding to visited : " << name_n << endl; visited.insert(next); nodeBeforeMap[next]=node; visitedCounter[next]=1; vizzGraph->setProperty(SgGraph::visitedCounter, next, RoseBin_support::ToString(1)); if (!containsHash(worklist_hash,next)) { // add next node only if the next node if (RoseBin_support::DEBUG_MODE()) cout << "adding to worklist: " << name_n << endl; worklist.push_back(next); worklist_hash.insert(next); } } else { // if the successor has been visited, we need to check if it has changed // if it has not, we continue, else we need to push it back to the worklist int nr = visitedCounter[next]; if (RoseBin_support::DEBUG_MODE()) cout << " visited next node before... " << RoseBin_support::ToString(nr) << " Changed == " << RoseBin_support::resBool(hasChanged) << endl; if (hasChanged) { visitedCounter[next]=++nr; vizzGraph->setProperty(SgGraph::visitedCounter, next, RoseBin_support::ToString(nr)); if (RoseBin_support::DEBUG_MODE()) cout << " has changed : " << RoseBin_support::resBool(hasChanged) << " -- interprocedural : " << RoseBin_support::resBool(interprocedural) << " -- Call : " << RoseBin_support::resBool(call) << " ------> new number: " << RoseBin_support::ToString(nr) << " -- contained in hash? : " << RoseBin_support::resBool(containsHash(worklist_hash,next)) << " ---- nr of Defs: " << RoseBin_support::ToString(analysis->getDefinitionSize()) << " ---- nr of Use: " << RoseBin_support::ToString(analysis->getUsageSize()) << endl; if (interprocedural || (!interprocedural && !call)){ //sameParent)) { //!call && ) { if (!containsHash(worklist_hash,next)) { worklist_hash.insert(next); worklist.push_back(next); if (RoseBin_support::DEBUG_MODE()) cout << " adding to worklist: " << name_n << endl; } } } else if (RoseBin_support::DEBUG_MODE()) cout << " has NOT changed. " << endl; //else we continue with the next node } } } // for } // while worklist.size()>0 } // for rootNodes }
void RoseBin_GMLGraph::printEdges( VirtualBinCFG::AuxiliaryInformation* info, bool forward_analysis, std::ofstream& myfile, SgDirectedGraphEdge* edge) { // traverse edges and visualize results of graph SgGraphNode* source = isSgGraphNode(edge->get_from()); SgGraphNode* target = isSgGraphNode(edge->get_to()); ROSE_ASSERT(source); ROSE_ASSERT(target); string edgeLabel=""; map < int , string> edge_p = edge->get_properties(); map < int , string>::iterator prop = edge_p.begin(); //string type = node->get_type(); for (; prop!=edge_p.end(); ++prop) { int addr = prop->first; // cerr << " dot : property for addr : " << addr << " and node " << hex_address << endl; if (addr==SgGraph::edgeLabel) edgeLabel = prop->second; if (edgeLabel.length()>1) if (edgeLabel[0]!='U') edgeLabel=""; } SgAsmStatement* binStat_s = isSgAsmStatement(source->get_SgNode()); SgAsmStatement* binStat_t = isSgAsmStatement(target->get_SgNode()); if (binStat_s==NULL || binStat_t==NULL) { //cerr << "binStat_s==NULL || binStat_t==NULL" << endl; } else { map <SgAsmStatement*, int>::iterator it_s = nodesMap.find(binStat_s); map <SgAsmStatement*, int>::iterator it_t = nodesMap.find(binStat_t); int pos_s=0; int pos_t=0; if (it_s!=nodesMap.end()) pos_s = it_s->second; if (it_t!=nodesMap.end()) pos_t = it_t->second; if (pos_s==0 || pos_t==0) { //cerr << " GMLGraph edge, node == 0 " << endl; } string output = "edge [\n label \""+edgeLabel+"\"\n source " + RoseBin_support::ToString(pos_s) + "\n target " + RoseBin_support::ToString(pos_t) + "\n"; // ------------------ SgAsmX86Instruction* contrl = isSgAsmX86Instruction(source->get_SgNode()); string add = ""; if (contrl && x86InstructionIsControlTransfer(contrl)) { // the source is a control transfer function // we use either dest or dest_list // dest is used for single destinations during cfg run // dest_list is used for a static cfg image vector<VirtualBinCFG::CFGEdge> outEdges = contrl->cfgBinOutEdges(info); SgAsmX86Instruction* dest = isSgAsmX86Instruction(outEdges.empty() ? NULL : outEdges.back().target().getNode()); bool dest_list_empty = true; if (contrl->get_kind() == x86_ret) dest_list_empty = outEdges.empty(); SgAsmInstruction* nextNode = isSgAsmInstruction(target->get_SgNode()); ROSE_ASSERT(nextNode); if (dest) { //string type = "jmp_if"; if (dest==nextNode) { if (contrl->get_kind() == x86_call || contrl->get_kind() == x86_ret) { add += " graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#FF0000\" ] ]\n"; } else if (contrl->get_kind() == x86_jmp) { add += " graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#FF0000\" ] ]\n"; } else add += " graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#00FF00\" ] ]\n"; } else if (forward_analysis && (contrl->get_kind() == x86_call || contrl->get_kind() == x86_jmp)) { add += " graphics [ type \"line\" arrow \"last\" fill \"#FFFF00\" ] ]\n"; } } else if (contrl->get_kind() == x86_ret ) { //&& dest_list_empty) { // in case of a multiple return add += " graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#3399FF\" ] ]\n"; } } string type_n = getProperty(SgGraph::type, edge); if (type_n==RoseBin_support::ToString(SgGraph::usage)) { add = " graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#000000\" ] ]\n"; } // skip the function declaration edges for now // bool blankOutput=false; //if (skipFunctions) //if (isSgAsmFunction(binStat_s)) // blankOutput=true; if (skipInternalEdges) { SgAsmX86Instruction* contrl = isSgAsmX86Instruction(source->get_SgNode()); if (contrl && x86InstructionIsControlTransfer(contrl) && contrl->get_kind() != x86_ret) { if (contrl->get_kind() == x86_call) output += " Edge_Color_ FF0000 \n Type_ \"[ 33554432 CALL_EDGE ]\" \n"; else if (contrl->get_kind() == x86_jmp) output += " Edge_Color_ 00FF00 \n Type_ \"[ 33554432 FILECALL_EDGE ]\" \n"; else output += " Edge_Color_ 0000FF \n "; } //else // blankOutput=true; } if (add=="") output += " graphics [ type \"line\" arrow \"last\" fill \"#000000\" ] ]\n"; else output +=add; myfile << output; } // } // ---------- // nodesMap.clear(); }
void RoseBin_GMLGraph::printNodes( bool dfg, RoseBin_FlowAnalysis* flow,bool forward_analysis, std::ofstream& myfile, string& recursiveFunctionName) { //bool firstFunc = true; // traverse nodes and visualize results of graph funcMap.clear(); nodesMap.clear(); //cerr << " Preparing graph - Nr of Nodes : " << nodes.size() << " edges : " << edges.size() << endl; //SgGraphNodeList* gnodes = get_nodes(); // rose_graph_hash_multimap& nodes = get_nodes()->get_nodes(); rose_graph_integer_node_hash_map nodes = get_node_index_to_node_map(); int counter=nodes.size(); int count=0; rose_graph_integer_node_hash_map::iterator itn2 = nodes.begin(); for (; itn2!=nodes.end();++itn2) { counter++; count++; pair<int, SgGraphNode*> nt = *itn2; // string hex_address = itn2->first; SgGraphNode* node = isSgGraphNode(itn2->second); string hex_address =node->get_name(); SgNode* internal = node->get_SgNode(); SgAsmFunction* func = isSgAsmFunction(internal); if (func) { vector<SgNode*> list; FindInstructionsVisitorx86 vis; #ifdef _MSC_VER //#pragma message ("WARNING: Removed reference to AstQueryNamespace::querySubTree()") // ROSE_ASSERT(false); // CH (4/7/2010): Workaround for MSVC vector<SgAsmX86Instruction*> temp_list; AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &temp_list )); list.resize(temp_list.size()); std::copy(temp_list.begin(), temp_list.end(), list.begin()); #else #if defined(__APPLE__) && defined(__MACH__) //Pei-Hung (7/28/2016): OSX El Capitan has issue with bind2nd. vector<SgAsmX86Instruction*> temp_list; AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &temp_list )); list.resize(temp_list.size()); std::copy(temp_list.begin(), temp_list.end(), list.begin()); #else AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &list )); #endif #endif int validInstructions = func->nrOfValidInstructions(list); funcMap[func]=counter; nodesMap[func]=count; string name = func->get_name(); string text = "node [\n id " + RoseBin_support::ToString(counter) + "\n id_ " + RoseBin_support::ToString(counter) + "\n label \"" + name + "\"\n "; text +=" nrinstr_ "+RoseBin_support::ToString(validInstructions)+" \n"; text+= " isGroup 1\n isGroup_ 1\n ]\n"; if (name=="frame_dummy") { //cerr << text << endl; vector<SgNode*> succs = func->get_traversalSuccessorContainer(); vector<SgNode*>::iterator j = succs.begin(); //cerr << " ------------- free_dummy"<<endl; int ii=0; for (;j!=succs.end();j++) { //SgNode* n = *j; //cerr << " Node contained at pos:"<<ii<<" - " << n->class_name() << endl; ii++; } //cerr << " number of validInstructions: " << validInstructions << endl; } if (grouping) myfile << text; } SgAsmInstruction* bin_inst = isSgAsmInstruction(internal); if (bin_inst) nodesMap[bin_inst]=count; } //cerr << " Writing graph to GML - Nr of Nodes : " << nodes.size() << endl; int pos=0; rose_graph_integer_node_hash_map::iterator itn = nodes.begin(); for (; itn!=nodes.end();++itn) { pos++; // string hex_address = itn->first; SgGraphNode* node = isSgGraphNode(itn->second); string hex_address = node->get_name(); SgNode* internal = node->get_SgNode(); SgAsmFunction* func = isSgAsmFunction(internal); string text=""; // specifies that this node has no destination address nodest_jmp = false; // specifies that there is a node that has a call error (calling itself) error =false; // specifies a call to a unknown location nodest_call = false; // specifies where its an int instruction interrupt = false; if (func) { string name = func->get_name(); //cerr << " if part name : " << name << endl; ROSE_ASSERT(node); if (grouping==false) { map < int , string> node_p = node->get_properties(); map < int , string>::iterator prop = node_p.begin(); string name = "noname"; string type = "removed";//node->get_type(); for (; prop!=node_p.end(); ++prop) { int addr = prop->first; //cerr << " gml : property for addr : " << addr << endl; if (addr==SgGraph::nodest_jmp) nodest_jmp = true; else if (addr==SgGraph::itself_call) error = true; else if (addr==SgGraph::nodest_call) nodest_call = true; else if (addr==SgGraph::interrupt) interrupt = true; // else // name = prop->second; } } int parent = funcMap[func]; RoseBin_support::checkText(name); int length = name.length(); text = "node [\n id " + RoseBin_support::ToString(pos) + "\n label \"" + name + "\"\n"; if (nodest_jmp) { text += " graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#FF0000\" ]\n"; text +=" Node_Color_ \"FF0000\" \n"; } else if (nodest_call) { text += " graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#FF9900\" ]\n"; text +=" Node_Color_ \"FF9900\" \n"; } else if (interrupt) { text += " graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#0000FF\" ]\n"; text +=" Node_Color_ \"0000FF\" \n"; } else if (error) { text += " graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#66FFFF\" ]\n"; text +=" Node_Color_ \"66FFFF\" \n"; }else { text += " graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#9933FF\" ]\n"; text +=" Node_Color_ \"9933FF\" \n"; } text +=" gid "+RoseBin_support::ToString(parent)+" \n"; text +=" skip_ 1 \n"; text +=" gid_ "+RoseBin_support::ToString(parent)+" ]\n"; // skip functions for now // if (skipFunctions) // text =""; } /*not a func*/ else { SgAsmX86Instruction* bin_inst = isSgAsmX86Instruction(internal); //cerr << " else part " << endl; SgAsmFunction* funcDecl_parent = NULL; if (bin_inst) { funcDecl_parent = isSgAsmFunction(bin_inst->get_parent()); if (funcDecl_parent==NULL) funcDecl_parent = isSgAsmFunction(bin_inst->get_parent()->get_parent()); } if (funcDecl_parent==NULL) { cerr << " ERROR : printNodes preparation . No parent found for node : " << bin_inst->class_name() << " " << hex_address << endl; continue; } if ((pos % 10000)==0) cout << " GMLGraph:: printing GML Nodes : " << pos << endl; string name = getInternalNodes(node, forward_analysis,bin_inst); int parent=0; map <SgAsmFunction*, int>::iterator its = funcMap.find(funcDecl_parent); if (its!=funcMap.end()) parent = funcMap[funcDecl_parent]; if (parent==0) cerr << " GMLGraph parent == 0 " << endl; if (onlyControlStructure && x86InstructionIsControlTransfer(bin_inst)) { text = "node [\n id " + RoseBin_support::ToString(pos) + "\n" + name ; int instrnr = funcDecl_parent->get_childIndex(bin_inst); text +=" instrnr_ "+RoseBin_support::ToString(instrnr)+" \n"; text +=" gid_ "+RoseBin_support::ToString(parent)+" \n"; text +=" gid "+RoseBin_support::ToString(parent)+" ]\n"; } else { text = "node [\n id " + RoseBin_support::ToString(pos) + "\n" + name ; int instrnr = funcDecl_parent->get_childIndex(bin_inst); text +=" instrnr_ "+RoseBin_support::ToString(instrnr)+" \n"; text +=" gid_ "+RoseBin_support::ToString(parent)+" \n"; text +=" gid "+RoseBin_support::ToString(parent)+" ]\n"; } } myfile << text; // cerr << " this node : " << text << endl; } funcMap.clear(); }
/**************************************************** * traverse the binary AST ****************************************************/ void RoseBin_FlowAnalysis::visit(SgNode* node) { // cerr << " traversing node " << node->class_name() << endl; if (isSgAsmFunction(node) ) { SgAsmFunction* binDecl = isSgAsmFunction(node); string name = binDecl->get_name(); ostringstream addrhex; addrhex << hex << setw(8) << binDecl->get_address() ; if (name=="") { name=addrhex.str(); binDecl->set_name(name); } SgAsmStatement* stat = NULL; // SgAsmStatementPtrList& list = binDecl->get_statementList(); vector<SgAsmInstruction*> list; FindInstructionsVisitor vis; AstQueryNamespace::querySubTree(binDecl, std::bind2nd( vis, &list )); int sizeList = list.size(); if (sizeList==0) { //cerr << " this function is empty!! " << endl; return; } //if ((func_nr % 1)==0) // if (RoseBin_support::DEBUG_MODE()) // cout << analysisName << " Func Nr: " << (++func_nr) << " blocks:" << // sizeList << " ***************** checking function : " << name << endl; if (forward_analysis) { stat = list.front(); } else { // get the last instruction in a function (backward control flow) stat = list.back(); } ROSE_ASSERT(stat); // if (RoseBin_support::DEBUG_MODE()) //cout << ">>>>>>>>>>>>>. checking statement in function : " << name << " .. " << stat->class_name() << endl; if (isSgAsmInstruction(stat)) { SgAsmInstruction* inst = isSgAsmInstruction(stat); ROSE_ASSERT(inst); // check the control flow of the first instruction in a function string typeFunction ="function"; SgGraphNode* src=NULL; if (analysisName=="callgraph") { // src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), false, binDecl); src = addCFNode (name, typeFunction, binDecl->get_address(), false, binDecl); } else { //src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), true, binDecl); //cerr << ">> adding node (f) src: " << RoseBin_support::HexToString(binDecl->get_address()) << endl; src = addCFNode (name, typeFunction, binDecl->get_address(), true, binDecl); string mnemonic=inst->get_mnemonic(); //SgGraphNode* trg = vizzGraph->createNode (mnemonic, typeNode, inst->get_address(), vizzGraph->graph->get_graph_id(),false, inst); //cerr << ">> adding node (first) trg: " << RoseBin_support::HexToString(inst->get_address()) << endl; SgGraphNode* trg = addCFNode (mnemonic, typeNode, inst->get_address(), false, inst); string unp_name = unparseInstructionWithAddress(inst); trg->append_properties(SgGraph::name,unp_name); if (analysisName=="dfa") trg->append_properties(SgGraph::dfa_standard,unp_name); //cerr << "Create edge " << endl; // SgDirectedGraphEdge* edge = vizzGraph->createEdge ( typeFunction, vizzGraph->graph->get_graph_id(), src, binDecl->get_address(), trg, inst->get_address()); SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge ( src, trg, typeFunction); vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg)); } local_visited.clear(); worklist_forthisfunction.push(inst); funcDecl = binDecl; funcDeclNode = src; checkControlFlow(inst, sizeList, sizeList, name, func_nr); } else { if (RoseBin_support::DEBUG_MODE()) cerr << "This is not an Instruction " << endl; } } }
void RoseBin_ControlFlowAnalysis::printGraph(std::string fileName, std::set<std::string>& filter) { #if 1 ASSERT_not_reachable("no longer supported"); #else std::set<std::string>::const_iterator it = filter.begin(); for (;it!=filter.end();++it) { std::cerr << "CFG -- contains filter: ." << *it << "." << endl; } // typedef rose_hash::unordered_map <std::string, SgGraphNode*> nodeType; // typedef rose_hash::unordered_map <string, SgGraphNode*,hash_stringptr> nodeType; rose_graph_integer_node_hash_map result; //rose_graph_hash_multimap& nodes = vizzGraph->get_node_index_to_node_map(); rose_graph_integer_node_hash_map nodes = vizzGraph->get_node_index_to_node_map(); rose_graph_integer_node_hash_map::iterator itn2 = nodes.begin(); for (; itn2 != nodes.end();++itn2) { // string hex_address = itn2->first; SgGraphNode* node = itn2->second; string hex_address = node->get_name(); //string hex_addr_tmp = node->get_name(); //ROSE_ASSERT(hex_address==hex_addr_tmp); SgNode* internal = node->get_SgNode(); SgAsmFunction* func = isSgAsmFunction(internal); if (func) { std::cerr << "ControlFlowAnalysis:: found function: ." << hex_address << "." <<endl; std::set<std::string>::const_iterator it = filter.find(hex_address); if (it!=filter.end()) { //std::cerr << " ******************* match ********************* " << std::endl; set<SgGraphNode*> gns; set<std::string> names; getCFGNodesForFunction(gns,names,node,hex_address); if (debug) cerr << " nodes in function: " << gns.size() << " " << names.size() <<endl; ROSE_ASSERT(gns.size()==names.size()); set<SgGraphNode*>::const_iterator it2 = gns.begin(); set<std::string>::const_iterator it3 = names.begin(); for (;it2!=gns.end();++it2, ++it3) { std::string name = *it3; SgGraphNode* n = *it2; if (debug) cerr << " adding to result ."<<name<<"."<<endl; result.insert(make_pair(itn2->first,n)); } } } } rose_graph_integer_node_hash_map nodesResult = nodes; rose_graph_integer_node_hash_map::iterator itn23 = nodes.begin(); for (; itn23!=nodes.end();++itn23) { //string hex_address = isSgGraphNode(itn23->second)->get_name(); int pos = itn23->first; // rose_graph_integer_node_hash_map::iterator it = result.find(hex_address); rose_graph_integer_node_hash_map::iterator it = result.find(pos); if (it==result.end()) { // not found in result, i.e. delete //nodesResult.erase(hex_address); nodesResult.erase(pos); } } // vizzGraph->nodes=nodesResult; #if 0 // vizzGraph->nodes=result; // create file bool forward_analysis=true; bool multiedge=false; std::ofstream myfile; myfile.open(fileName.c_str()); string name = "ROSE Graph"; vizzGraph->printProlog(myfile, name); string functionName=""; vizzGraph->setGrouping(true); vizzGraph->printNodes(true, this, forward_analysis, myfile,functionName); nrNodes=vizzGraph->nodes.size(); vizzGraph->printEdges(this,myfile, multiedge); nrEdges=vizzGraph->get_node_index_to_edge_multimap_edgesOut().size(); vizzGraph->printEpilog(myfile); myfile.close(); #endif #if 1 RoseBin_Graph* gr = new RoseBin_DotGraph(); gr->graph = new SgIncidenceDirectedGraph("test");//SgDirectedGraph("test","test"); gr->get_node_index_to_node_map()=nodesResult; //typedef SB_DirectedGraph::edgeType edgeType; rose_graph_integer_edge_hash_multimap edges = vizzGraph->get_node_index_to_edge_multimap_edgesOut(); rose_graph_integer_edge_hash_multimap resultEdges; rose_graph_integer_edge_hash_multimap::iterator itEdg = edges.begin(); for (; itEdg!=edges.end();++itEdg) { int index = itEdg->first; SgGraphNode* node = NULL; rose_graph_integer_node_hash_map::iterator nIT = vizzGraph->get_node_index_to_node_map().find(index); if (nIT!=vizzGraph->get_node_index_to_node_map().end()) node=nIT->second; ROSE_ASSERT(node); SgDirectedGraphEdge* edge = isSgDirectedGraphEdge(itEdg->second); SgGraphNode* target = isSgGraphNode(edge->get_to()); rose_graph_integer_node_hash_map::iterator itn2 = nodesResult.begin(); bool foundS=false; if (node) foundS=true; bool foundT=false; for (; itn2!=nodesResult.end();++itn2) { SgGraphNode* n = itn2->second; //if (n==source) foundS=true; if (n==target) foundT=true; } if (foundS==false || foundT==false) { } else resultEdges.insert(make_pair(node->get_index(),edge)); } gr->get_node_index_to_edge_multimap_edgesOut()=resultEdges; // create file bool forward_analysis=true; bool multiedge=false; std::ofstream myfile; myfile.open(fileName.c_str()); string name = "ROSE Graph"; gr->printProlog(myfile, name); string functionName=""; gr->setGrouping(true); gr->printNodes(true, this, forward_analysis, myfile,functionName); nrNodes=gr->get_node_index_to_node_map().size(); ROSE_ASSERT(g_algo->info); gr->printEdges(g_algo->info, this,myfile, multiedge); nrEdges=gr->get_node_index_to_edge_multimap_edgesOut().size(); gr->printEpilog(myfile); myfile.close(); #endif #endif }
void RoseBin_FlowAnalysis::checkControlFlow( SgAsmInstruction* binInst, int functionSize, int countDown, string& currentFunctionName, int func_nr) { //cerr << "check control flow" << endl; while (!worklist_forthisfunction.empty()) { SgAsmInstruction* binInst = worklist_forthisfunction.top(); worklist_forthisfunction.pop(); ROSE_ASSERT(binInst); countDown--; int address = binInst->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; ROSE_ASSERT(g_algo->info); vector <VirtualBinCFG::CFGEdge> vec; if (forward_analysis) { vec = binInst->cfgBinOutEdges(g_algo->info); if (isSgAsmx86Instruction(binInst) && isSgAsmx86Instruction(binInst)->get_kind() == x86_call) { // vec.push_back(VirtualBinCFG::CFGEdge(VirtualBinCFG::CFGNode(binInst), VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(binInst->get_address() + binInst->get_raw_bytes().size())), g_algo->info)); } } else vec = binInst->cfgBinInEdges(g_algo->info); string name = binInst->get_mnemonic(); // if (RoseBin_support::DEBUG_MODE()) // cout << " " << addrhex.str() << " " << func_nr << " :: " << functionSize << // "/" << countDown << " ---------- next CFG instruction : " << name << " vecSize : " << vec.size() << endl; for (int i=0; i < (int)vec.size(); i++) { VirtualBinCFG::CFGEdge edge = vec[i]; VirtualBinCFG::CFGNode cfg_target = edge.target(); VirtualBinCFG::CFGNode cfg_source = edge.source(); if (!forward_analysis) { cfg_target = edge.source(); cfg_source = edge.target(); } SgAsmInstruction* bin_target = isSgAsmInstruction(cfg_target.getNode()); SgAsmInstruction* thisbin = isSgAsmInstruction(cfg_source.getNode()); ROSE_ASSERT(thisbin); SgAsmx86Instruction* thisbinX86 = isSgAsmx86Instruction(thisbin); ROSE_ASSERT (thisbinX86); string src_mnemonic = thisbin->get_mnemonic(); int src_address = thisbin->get_address(); if (analysisName=="callgraph") src_address = funcDecl->get_address(); ostringstream addrhex_s; addrhex_s << hex << setw(8) << src_address ; SgGraphNode* src =NULL; string hexStr = addrhex_s.str(); if (analysisName!="callgraph") { vector<SgGraphNode*> sources; vizzGraph->checkIfGraphNodeExists(hexStr, sources); vector<SgGraphNode*>::const_iterator src_it = sources.begin(); for (;src_it!=sources.end();++src_it) { // should only be one node! adapted to new interface src = *src_it; } if (src==NULL) { // src= vizzGraph->createNode (src_mnemonic, typeNode, src_address, vizzGraph->graph->get_graph_id(), false, thisbin); src= addCFNode (src_mnemonic, typeNode, src_address, false, thisbin); string unp_name = unparseInstructionWithAddress(thisbin); src->append_properties(SgGraph::name,unp_name); if (analysisName=="dfa") src->append_properties(SgGraph::dfa_standard,unp_name); } ROSE_ASSERT(src); if (thisbinX86->get_kind() == x86_call) { uint64_t returnAddr = thisbinX86->get_address() + thisbinX86->get_raw_bytes().size(); ROSE_ASSERT(g_algo->info); SgAsmInstruction* retInsn = g_algo->info->getInstructionAtAddress(returnAddr); if (retInsn) { //worklist_forthisfunction.push(retInsn); //ostringstream tgthex_s; //tgthex_s << hex << setw(8) << returnAddr ; //string tgtStr = tgthex_s.str(); //SgGraphNode* tgt = vizzGraph->checkIfGraphNodeExists(tgtStr); // tps (25 Aug 2008) : this line seems broken! //string mne = retInsn->get_mnemonic(); //if (!tgt) {tgt = vizzGraph->createNode(mne, typeNode, returnAddr, vizzGraph->graph->get_graph_id(), false, retInsn);} // cerr << " ------> Creating return edge : " << thisbinX86->get_address() << " " << returnAddr << endl; // vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), src, thisbinX86->get_address(), tgt, returnAddr); } } } else if (analysisName=="callgraph") { // These are special cases that annotate the call graph (nodes) // so that the visualization can pick up the properties and color correctly ROSE_ASSERT(g_algo->info); if (thisbinX86->get_kind() == x86_jmp) { if (thisbinX86->cfgBinOutEdges(g_algo->info).empty()) { funcDeclNode->append_properties(SgGraph::nodest_jmp,RoseBin_support::ToString("nodest_jmp")); } } else if (thisbinX86->get_kind() == x86_call) { //cerr << "CallGRAPH: Found call : " << // RoseBin_support::HexToString(VirtualBinCFG::CFGNode(thisbinX86).getNode()->get_address()) << " to " << // RoseBin_support::HexToString(VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(thisbinX86->get_address() + thisbinX86->get_raw_bytes().size())).getNode()->get_address()) << endl; vector<VirtualBinCFG::CFGEdge> dests = thisbinX86->cfgBinOutEdges(g_algo->info); dests.push_back(VirtualBinCFG::CFGEdge(VirtualBinCFG::CFGNode(thisbinX86), VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(thisbinX86->get_address() + thisbinX86->get_raw_bytes().size())), g_algo->info)); if (!dests.empty()) { SgAsmNode* parent = isSgAsmNode(dests[0].target().getNode()->get_parent()); if (!db) parent = isSgAsmNode(parent->get_parent()); if (parent) { SgAsmFunction* funcdestparent = isSgAsmFunction(parent); string trg_func_name = funcdestparent->get_name(); if (trg_func_name==currentFunctionName) { funcDeclNode->append_properties(SgGraph::itself_call,RoseBin_support::ToString("itself_call")); } } } else { funcDeclNode->append_properties(SgGraph::nodest_call,RoseBin_support::ToString("nodest_call")); //cerr << " no destination found for call " << addrhex.str() << endl; } } else if (thisbinX86->get_kind() == x86_int) { funcDeclNode->append_properties(SgGraph::interrupt,RoseBin_support::ToString("interrupt")); } } if (bin_target!=NULL) { string trg_func_name = ""; int trg_func_address =1; string hexStrf = ""; SgAsmFunction* funcDeclparent=NULL; if (analysisName=="callgraph") { SgAsmNode* parent = dynamic_cast<SgAsmNode*>(bin_target->get_parent()); if (parent==NULL) continue; if (!db) parent = isSgAsmNode(parent->get_parent()); ROSE_ASSERT(parent); funcDeclparent = isSgAsmFunction(parent); ROSE_ASSERT(funcDeclparent); trg_func_name = funcDeclparent->get_name(); trg_func_address = funcDeclparent->get_address(); ostringstream addrhex_tf; addrhex_tf << hex << setw(8) << trg_func_address ; hexStrf = addrhex_tf.str(); //cerr << " CALLGRAPH TARGET PARENT : " << hexStrf << endl; } string trg_mnemonic = bin_target->get_mnemonic(); int trg_address = bin_target->get_address(); ostringstream addrhex_t; addrhex_t << hex << setw(8) << trg_address ; if (RoseBin_support::DEBUG_MODE()) cout << " OUTEDGES TO: vec[" << i << "/" << vec.size() << "] :" << addrhex_t.str() << " " << trg_mnemonic << endl; string hexStr = addrhex_t.str(); SgGraphNode* trg=NULL; vector<SgGraphNode*> targets; if (analysisName=="callgraph") vizzGraph->checkIfGraphNodeExists(hexStrf, targets); else vizzGraph->checkIfGraphNodeExists(hexStr, targets); vector<SgGraphNode*>::const_iterator src_it = targets.begin(); for (;src_it!=targets.end();++src_it) { // should only be one node! adapted to new interface trg = *src_it; } //ROSE_ASSERT(trg); bool target_visited = false; // DQ (4/23/2009): We want the type defined in the base class. // rose_hash::unordered_map <string, SgAsmInstruction*>::iterator vis = local_visited.find(hexStr); // CH (4/9/2010): Use boost::unordered instead //#ifndef _MSCx_VER #if 1 rose_hash::unordered_map <string, SgAsmInstruction*>::iterator vis = local_visited.find(hexStr); #else rose_hash::unordered_map <string, SgAsmInstruction*,rose_hash::hash_string>::iterator vis = local_visited.find(hexStr); #endif if (vis!=local_visited.end()) target_visited=true; if (trg==NULL) { if (analysisName=="callgraph") { // cerr << " >>> TARGET FUNC NAME " << trg_func_name << endl; //trg = vizzGraph->createNode (trg_func_name, typeNode, trg_func_address, vizzGraph->graph->get_graph_id(),false, funcDeclparent); trg = addCFNode (trg_func_name, typeNode, trg_func_address,false, funcDeclparent); } else { //trg = vizzGraph->createNode (trg_mnemonic, typeNode, trg_address, vizzGraph->graph->get_graph_id(),false, bin_target); trg = addCFNode (trg_mnemonic, typeNode, trg_address, false, bin_target); } string unp_name = unparseInstructionWithAddress(bin_target); //cout << " (target==NULL) unparse name : " << unp_name << endl; trg->append_properties(SgGraph::name,unp_name); if (analysisName=="dfa") trg->append_properties(SgGraph::dfa_standard,unp_name); } else { string unp_name = unparseInstructionWithAddress(bin_target); //cout << " unparse name : " << unp_name << endl; trg->append_properties(SgGraph::name,unp_name); if (analysisName=="dfa") trg->append_properties(SgGraph::dfa_standard,unp_name); } ROSE_ASSERT(trg); local_visited[hexStr] = bin_target; string name=""; if (analysisName=="callgraph") name = RoseBin_support::ToString(src_address)+RoseBin_support::ToString(trg_func_address); else name = RoseBin_support::ToString(src_address)+RoseBin_support::ToString(trg_address); bool exists = vizzGraph->checkIfDirectedGraphEdgeExists(src, trg); if (!exists) { if (analysisName=="callgraph") { if (currentFunctionName!=trg_func_name && thisbinX86->get_kind() != x86_ret) { // SgDirectedGraphEdge* edge = vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), funcDeclNode, src_address, trg, trg_func_address); SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge( funcDeclNode, trg, typeEdge); //cerr << "CallGraph : create edge : " << RoseBin_support::HexToString(src_address) << " to func : " << RoseBin_support::HexToString(trg_func_address) << endl; vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg)); } } else { //string addr = RoseBin_support::HexToString(binInst->get_address()); //if (addr==" 8048392" || addr==" 80482fd") // cerr << " >>>>>>>>>> found " << addr << " -- target_address : " << RoseBin_support::HexToString(trg_address) << endl; // SgDirectedGraphEdge* edge =vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), src, src_address, trg, trg_address); SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge( src, trg, typeEdge); vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg)); } } if (analysisName!="callgraph") { // handle return edges SgAsmStatementPtrList sources = thisbin->get_sources(); SgAsmStatementPtrList::iterator it = sources.begin(); for (;it!=sources.end();++it) { SgAsmInstruction* instT = isSgAsmInstruction(*it); //cerr << " This node is called from : " << instT->get_address() << endl; ostringstream addr_t; addr_t << hex << setw(8) << instT->get_address() ; SgGraphNode* trg =NULL; string hexStr = addr_t.str(); vector<SgGraphNode*> targets; vizzGraph->checkIfGraphNodeExists(hexStr, targets); vector<SgGraphNode*>::const_iterator src_it = targets.begin(); for (;src_it!=targets.end();++src_it) { // should only be one node! adapted to new interface trg = *src_it; } //trg= vizzGraph->checkIfGraphNodeExists(hexStr); if (trg==NULL) { string hexa = RoseBin_support::HexToString(instT->get_address()); hexa = hexa.substr(1,hexa.size()); string name = "0x"+hexa+":"+instT->get_mnemonic(); //trg= vizzGraph->createNode (name, typeNode, instT->get_address(), vizzGraph->graph->get_graph_id(), false, instT); trg= addCFNode(name, typeNode, instT->get_address(), false, instT); } bool exists = vizzGraph->checkIfDirectedGraphEdgeExists( trg,src); if (!exists) { bool same = sameParents(trg,src); if (!same) { SgDirectedGraphEdge* edge =vizzGraph->addDirectedEdge( trg, src, typeEdge); //SgDirectedGraphEdge* edge =vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), trg, instT->get_address(), src, src_address); vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg)); } } } } if (!target_visited) { // check if target is in the same function!!! SgAsmNode* block = bin_target; if (!db) block = isSgAsmNode(bin_target->get_parent()); ROSE_ASSERT(block); SgAsmFunction* funcPar = isSgAsmFunction(block->get_parent()); if (funcPar) { string nameFunc = funcPar->get_name(); if (nameFunc==currentFunctionName) { //checkControlFlow(bin_target, functionSize, countDown, currentFunctionName); worklist_forthisfunction.push(bin_target); } } else { if (RoseBin_support::DEBUG_MODE()) cerr << " ERROR:: Target Instruction has no parent! " << bin_target->class_name() << endl; } } // if visited } else { nr_target_missed++; if (binInst) if (RoseBin_support::DEBUG_MODE()) cerr << " WARNING:: no target found for " << RoseBin_support::HexToString(binInst->get_address()) << " " << binInst->class_name() << endl; } } } // if (RoseBin_support::DEBUG_MODE()) // cout << " ------------------------ done with instr: " << name << " " << addrhex.str() << endl; }