/** Fall-through virtual address. A block's fall-through address is the virtual address that follows the last byte of the * block's last instruction. The block must have instructions (e.g., it cannot be a strict data block). */ rose_addr_t SgAsmBlock::get_fallthrough_va() { ROSE_ASSERT(!get_statementList().empty()); SgAsmInstruction *last = isSgAsmInstruction(get_statementList().back()); ROSE_ASSERT(last!=NULL); return last->get_address() + last->get_size(); }
boost::any InstructionListModel::data(const Wt::WModelIndex &index, int role) const { ASSERT_require(index.isValid()); ASSERT_require(index.row()>=0 && (size_t)index.row() < insns_.size()); SgAsmInstruction *insn = insns_[index.row()]; if (Wt::DisplayRole == role) { switch (index.column()) { case C_ADDR: { return Wt::WString(StringUtility::addrToString(insn->get_address())); } case C_BYTES: { std::string s; for (size_t i=0; i<insn->get_raw_bytes().size(); ++i) { uint8_t byte = insn->get_raw_bytes()[i]; char buf[32]; sprintf(buf, "%02x", byte); s += std::string(i?" ":"") + buf; } return Wt::WString(s); } case C_CHARS: { std::string s; for (size_t i=0; i<insn->get_raw_bytes().size(); ++i) { char ch = insn->get_raw_bytes()[i]; s += std::string(i?" ":"") + (isgraph(ch) ? std::string(1, ch) : std::string(" ")); } return Wt::WString(s); } case C_STACKDELTA: { int64_t delta = insn->get_stackDelta(); if (delta == SgAsmInstruction::INVALID_STACK_DELTA) return Wt::WString(""); std::string s = (delta >= 0 ? "+" : "") + boost::lexical_cast<std::string>(delta); return Wt::WString(s); } case C_NAME: { return Wt::WString(unparseMnemonic(insn)); } case C_ARGS: { std::string s; const RegisterDictionary *regs = ctx_.partitioner.instructionProvider().registerDictionary(); const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands(); for (size_t i=0; i<operands.size(); ++i) s += (i?", ":"") + unparseExpression(operands[i], NULL, regs); return Wt::WString(s); } case C_COMMENT: { return Wt::WString(insn->get_comment()); } default: ASSERT_not_reachable("invalid column number"); } } return boost::any(); }
void RoseBin_FlowAnalysis::initFunctionList(SgAsmNode* globalNode) { vector<SgNode*> tree =NodeQuery::querySubTree(globalNode, V_SgAsmInstruction); vector<SgNode*>::iterator itV = tree.begin(); for (;itV!=tree.end();itV++) { SgAsmInstruction* inst = isSgAsmInstruction(*itV); if (inst) { uint64_t addr = inst->get_address(); rememberInstructions[addr] = inst; } } }
uint64_t RoseBin_FlowAnalysis::getAddressForNode(SgGraphNode* node) { ROSE_ASSERT(node); SgAsmInstruction* inst = isSgAsmInstruction(node->get_SgNode()); uint64_t addr = 0; if (inst) { addr = inst->get_address(); } else { // this is probably not an instruction } return addr; }
virtual void visit(SgNode* n) { SgAsmInstruction* insn = isSgAsmInstruction(n); if (!insn) return; #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT #if 1 ASSERT_not_reachable("no longer supported"); #else vector<CFGEdge> outEdgesSoFar = insn->cfgBinOutEdges(info); for (size_t i = 0; i < outEdgesSoFar.size(); ++i) { info->incomingEdges[outEdgesSoFar[i].target().getNode()].insert(insn->get_address()); } #endif #else printf ("This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n"); ROSE_ASSERT(false); #endif }
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 }
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); } } } }
SgAsmInstruction* InstructionProvider::operator[](rose_addr_t va) const { SgAsmInstruction *insn = NULL; if (!insnMap_.getOptional(va).assignTo(insn)) { if (useDisassembler_ && memMap_.at(va).require(MemoryMap::EXECUTABLE).exists()) { try { insn = disassembler_->disassembleOne(&memMap_, va); } catch (const Disassembler::Exception &e) { insn = disassembler_->make_unknown_instruction(e); ASSERT_not_null(insn); uint8_t byte; if (1==memMap_.at(va).limit(1).require(MemoryMap::EXECUTABLE).read(&byte).size()) insn->set_raw_bytes(SgUnsignedCharList(1, byte)); ASSERT_require(insn->get_address()==va); ASSERT_require(insn->get_size()==1); } } insnMap_.insert(va, insn); } return insn; }
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; }
/** HashAST::visit * * Called by traverse. Gets the whatever data is of interest and puts * it in the hash. * * @param[in] node to submit to hash **/ void AstHash::visit(SgNode* node) { //Always include the type of each node in the hash VariantT vType = node->variantT(); hasher_.insert(vType); //If it's an instruction, include the mnemonic, and maybe the address SgAsmInstruction* asmInstruction = isSgAsmInstruction(node); if(asmInstruction != NULL) { std::string mnemonic = asmInstruction->get_mnemonic(); hasher_.insert(mnemonic); if(includeAddresses) { rose_addr_t addr = asmInstruction->get_address(); hasher_.insert(addr); } return; } //Always include register references SgAsmRegisterReferenceExpression* regRef = isSgAsmRegisterReferenceExpression(node); if(regRef != NULL) { unsigned regHash = regRef->get_descriptor().hash(); hasher_.insert(regHash); return; } //Maybe inlcude constants (integers, floats, pointers) if(includeConstants) { SgAsmConstantExpression* constExpr = isSgAsmConstantExpression(node); if(constExpr != NULL) { std::string mnemonic = constExpr->get_bitVector().toHex(); hasher_.insert(mnemonic); return; } } }
bool GraphAlgorithms::isValidCFGEdge(SgGraphNode* sgNode, SgGraphNode* sgNodeBefore) { if (!sgNode || !sgNodeBefore) return false; // bool isAUnconditionalControlTransfer = false; bool valid = true; bool isDirectedControlFlowEdge = false; SgAsmX86Instruction* inst = isSgAsmX86Instruction(sgNodeBefore->get_SgNode()); SgAsmInstruction* instSgNode = isSgAsmInstruction(sgNode->get_SgNode()); SgAsmInstruction* instSgNodeBefore = isSgAsmInstruction(sgNodeBefore->get_SgNode()); if (instSgNode && instSgNodeBefore) { if (RoseBin_support::DEBUG_MODE()) cout << " *** instSgNode && instSgNodeBefore " << endl; SgAsmFunction* f1 = isSgAsmFunction(instSgNode->get_parent()); SgAsmFunction* f2 = isSgAsmFunction(instSgNodeBefore->get_parent()); if (f1==NULL) f1 = isSgAsmFunction(instSgNode->get_parent()->get_parent()); if (f2==NULL) f2 = isSgAsmFunction(instSgNodeBefore->get_parent()->get_parent()); if (f1 && f2) { // (tps - 05/23/08) : the semantics of the previous implementation is: // check the node before in the instruction set and check if it is the same as the previous node // todo: the following line must be changed... the size of the current node does not give you the last node! if (RoseBin_support::DEBUG_MODE()) cout << " *** f1 && f2 " << endl; SgAsmInstruction* nodeBeforeInSet = NULL; int byte = 1; ROSE_ASSERT(info); while (nodeBeforeInSet==NULL && byte<8) { nodeBeforeInSet = info->getInstructionAtAddress(instSgNode->get_address() - byte); byte++; } if (RoseBin_support::DEBUG_MODE()) cout << " *** nodeBeforeInSet = " << nodeBeforeInSet << " instSgNodeBefore : " << instSgNodeBefore << " byte : " << byte << endl; if (nodeBeforeInSet == instSgNodeBefore) { //if (!isAsmUnconditionalBranch(nodeBeforeInSet)) if (RoseBin_support::DEBUG_MODE()) cout << " isDirectedControlFlowEdge = true -- isAsmUnconditionalBranch(nodeBeforeInSet) : " << isAsmUnconditionalBranch(nodeBeforeInSet) << endl; isDirectedControlFlowEdge = true; } if (RoseBin_support::DEBUG_MODE()) { cout << " *** f1 && f2 -- isDirectionalControlFlowEdge: " << isDirectedControlFlowEdge << endl; cout << " inst->get_kind() == x86_call : " << (inst->get_kind() == x86_call) << " inst->get_kind() == x86_ret : " << (inst->get_kind() == x86_ret) << endl; } if ((inst->get_kind() == x86_call || inst->get_kind() == x86_ret) && isDirectedControlFlowEdge) valid=false; } } /* if (RoseBin_support::DEBUG_MODE()) { cout << " ValidCFGEdge::: sgNode " << sgNode->get_name() << " sgNodeBefore " << sgNodeBefore->get_name() << " instSgNode << " << instSgNode << " instSgNodeBefore << " << instSgNodeBefore << " is Valid node ? " << RoseBin_support::resBool(valid) << " isControlFlowEdge " << RoseBin_support::resBool(isDirectedControlFlowEdge) << endl; } */ return valid; }
DOTSynthesizedAttribute AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l) { SubTreeSynthesizedAttributes::iterator iter; ROSE_ASSERT(node); // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str()); // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute if (ia.skipSubTree == true) { // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute // Figured this out: if we return a valid pointer then we get a node in the DOT graph // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute // with a NUL pointer then the node will NOT appear in the DOT graph. // return DOTSynthesizedAttribute(node); return DOTSynthesizedAttribute(NULL); } string nodeoption; if(AstTests::isProblematic(node)) { // cout << "problematic node found." << endl; nodeoption="color=\"orange\" "; } string nodelabel=string("\\n")+node->class_name(); // DQ (1/24/2009): Added support for output of isForward flag in the dot graph. SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node); if (genericDeclaration != NULL) { // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward"; ROSE_ASSERT(name.empty() == false); // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST. SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration); if (classDeclaration != NULL) { nodelabel += string("\\n") + classDeclaration->get_name(); } // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST. SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration); if (functionDeclaration != NULL) { nodelabel += string("\\n") + functionDeclaration->get_name(); } nodelabel += string("\\n") + name; } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgInitializedName* initializedName = isSgInitializedName(node); if (initializedName != NULL) { nodelabel += string("\\n") + initializedName->get_name(); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgIntVal* intValue = isSgIntVal(node); if (intValue != NULL) { nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value()); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgVarRefExp* varRefExp = isSgVarRefExp(node); if (varRefExp != NULL) { SgVariableSymbol* variableSymbol = varRefExp->get_symbol(); ROSE_ASSERT(variableSymbol != NULL); string name = variableSymbol->get_name(); nodelabel += string("\\n name = ") + name; } // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph. SgAsmInstruction* genericInstruction = isSgAsmInstruction(node); if (genericInstruction != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. #if 1 string unparsedInstruction = unparseInstruction(genericInstruction); string addressString = StringUtility::numberToString( (void*) genericInstruction->get_address() ); // string name = genericInstruction->get_mnemonic(); string name = unparsedInstruction + "\\n address: " + addressString; #else string name = unparsedInstruction + "\\n" + addressString; #endif ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } SgAsmExpression* genericExpression = isSgAsmExpression(node); if (genericExpression != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT string name = unparseExpression(genericExpression, NULL, NULL); ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes. // In generall there are long list of these IR nodes in the binary and this helps make some sense of // the lists (sections, symbols, etc.). SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node); if (binaryFileFormatNode != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // The case of binary file format IR nodes can be especially confusing so we want the // default to output some more specific information for some IR nodes (e.g. sections). string name; SgAsmGenericSection* genericSection = isSgAsmGenericSection(node); if (genericSection != NULL) { SgAsmGenericString* genericString = genericSection->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node); if (genericSymbol != NULL) { SgAsmGenericString* genericString = genericSymbol->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); if (name.empty() == true) name = "no_name_for_symbol"; } SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node); if (genericDLL != NULL) { SgAsmGenericString* genericString = genericDLL->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node); if (peImportItem != NULL) { SgAsmGenericString* genericString = peImportItem->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node); if (asmDwarfLine != NULL) { char buffer[100]; // It does not work to embed the "\n" into the single sprintf parameter. // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column()); sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address()); name = buffer; sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column()); name += string("\\n") + buffer; } SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node); if (asmDwarfConstruct != NULL) { name = asmDwarfConstruct->get_name(); } #if 0 // This might not be the best way to implement this, since we want to detect common base classes of IR nodes. switch (node->variantT()) { case V_SgAsmElfSection: { SgAsmElfSection* n = isSgAsmElfSection(node); name = n->get_name(); break; } default: { // No additional information is suggested for the default case! } } #endif if (name.empty() == false) nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (11/29/2008): Output the directives in the label of the IR node. SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node); if (preprocessorDirective != NULL) { string s = preprocessorDirective->get_directiveString(); // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables. while (s.find("\"") != string::npos) { s.replace(s.find("\""),1,"\'"); } if (s.empty() == false) nodelabel += string("\\n") + s; } nodelabel += additionalNodeInfo(node); // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.) // nodeoption += additionalNodeOptions(node); string additionalOptions = additionalNodeOptions(node); // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size()); // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size()); string x; string y; x += additionalOptions; nodeoption += additionalOptions; DOTSynthesizedAttribute d(0); // DQ (7/27/2008): Added mechanism to support pruning of AST bool commentoutNode = commentOutNodeInGraph(node); if (commentoutNode == true) { // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option. // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file. if (SgProject::get_verbose() > 0) { printf ("Skipping the use of this IR node in the DOT Graph \n"); } } else { // ************************** switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption); break; case PREORDER: case TOPDOWN: dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); break; case POSTORDER: case BOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption); break; default: assert(false); } ++tdbuTrace; ++buTrace; // add edges or null values int testnum=0; for (iter = l.begin(); iter != l.end(); iter++) { string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]); string toErasePrefix = "p_"; if (AstTests::isPrefix(toErasePrefix,edgelabel)) { edgelabel.erase(0, toErasePrefix.size()); } if ( iter->node == NULL) { // SgNode* snode=node->get_traversalSuccessorContainer()[testnum]; AstSuccessorsSelectors::SuccessorsContainer c; AstSuccessorsSelectors::selectDefaultSuccessors(node,c); SgNode* snode=c[testnum]; // isDefault shows that the default constructor for synth attribute was used if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) ) { // handle bugs in SAGE dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red "); } else { if (snode == NULL) { dotrep.addNullValue(node,"",edgelabel,""); } } } else { // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.) string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel); switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both"); break; case PREORDER: case TOPDOWN: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward"); break; case POSTORDER: case BOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back"); break; default: assert(false); } } testnum++; } // ************************** } // DQ (7/4/2008): Support for edges specified in AST attributes AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism(); if (astAttributeContainer != NULL) { // Loop over all the attributes at this IR node for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++) { // std::string name = i->first; AstAttribute* attribute = i->second; ROSE_ASSERT(attribute != NULL); // This can return a non-empty list in user-defined attributes (derived from AstAttribute). // printf ("Calling attribute->additionalNodeInfo() \n"); std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo(); // printf ("nodeList.size() = %lu \n",nodeList.size()); for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++) { SgNode* nodePtr = i_node->nodePtr; string nodelabel = i_node->label; string nodeoption = i_node->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str()); // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption ); } // printf ("Calling attribute->additionalEdgeInfo() \n"); std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo(); // printf ("edgeList.size() = %lu \n",edgeList.size()); for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++) { string edgelabel = i_edge->label; string edgeoption = i_edge->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str()); dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward"); } } } switch(node->variantT()) { // DQ (9/1/2008): Added case for output of SgProject rooted DOT file. // This allows source code and binary files to be combined into the same DOT file. case V_SgProject: { SgProject* project = dynamic_cast<SgProject*>(node); ROSE_ASSERT(project != NULL); string generatedProjectName = SageInterface::generateProjectName( project ); // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); if (generatedProjectName.length() > 40) { // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); generatedProjectName = "aggregatedFileNameTooLong"; printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str()); } string filename = string("./") + generatedProjectName + ".dot"; // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str()); if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str()); dotrep.writeToFileAsGraph(filename); break; } // case V_SgFile: case V_SgSourceFile: case V_SgBinaryComposite: { SgFile* file = dynamic_cast<SgFile*>(node); ROSE_ASSERT(file != NULL); string original_filename = file->getFileName(); // DQ (7/4/2008): Fix filenamePostfix to go before the "." // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot"; string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot"; // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent()); // printf ("file->get_parent() = %p \n",file->get_parent()); // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... "; // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified // on the command line. A SgProject is still built even when a single file is specificed // on the command line, however there are cases where a SgFile can be built without a // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files. // If there is a SgProject then output the dot file from there, else output as a SgFile. if (file->get_parent() == NULL) { // If there is no SgProject then output the file now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n"); dotrep.writeToFileAsGraph(filename); } else { // There is a SgProject IR node, but if we will be traversing it we want to output the // graph then (so that the graph will include the SgProject IR nodes and connect multiple // files (SgSourceFile or SgBinaryComposite IR nodes). if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() ) { // This SgProject node was not input as part of the traversal, // so we will not be traversing the SgProject IR nodes and we // have to output the graph now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n"); dotrep.writeToFileAsGraph(filename); } else { if ( SgProject::get_verbose() >= 1 ) printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n"); } } // cout << "done." << endl; break; } // DQ (7/23/2005): Implemented default case to avoid g++ warnings // about enum values not handled by this switch default: { // nothing to do here break; } } d.node = node; return d; }
int main(int argc, char *argv[]) { std::ios_base::sync_with_stdio(true); std::string hostname = "localhost"; short port = 32002; /* Process command-line arguments. ROSE will do most of the work, but we need to look for the --debugger switch. */ for (int argno=1; argno<argc; argno++) { if (!strncmp(argv[argno], "--debugger=", 11)) { char *colon = strchr(argv[argno]+11, ':'); if (colon) { hostname = std::string(argv[argno]+11, colon-(argv[argno]+11)); char *rest; port = strtol(colon+1, &rest, 0); if (rest && *rest) { fprintf(stderr, "invalid argument for --debugger=HOST:PORT switch\n"); exit(1); } } else { hostname = argv[argno]+11; } memmove(argv+argno, argv+argno+1, (argc-(argno+1))*sizeof(*argv)); --argc; break; } } fprintf(stderr, "Parsing and disassembling executable...\n"); SgProject *project = frontend(argc, argv); /* Connect to debugger */ fprintf(stderr, "Connecting to debugger at %s:%d\n", hostname.c_str(), port); Debugger dbg(hostname, port); /* Choose an interpretation */ SgAsmInterpretation *interp = isSgAsmInterpretation(NodeQuery::querySubTree(project, V_SgAsmInterpretation).back()); assert(interp); Disassembler *disassembler = Disassembler::lookup(interp)->clone(); assert(disassembler!=NULL); fprintf(stderr, "Setting break points...\n"); int status __attribute__((unused)) = dbg.setbp(0, 0xffffffff); assert(status>=0); fprintf(stderr, "Starting executable...\n"); uint64_t nprocessed = 0; dbg.cont(); /* Advance to the first breakpoint. */ while (1) { nprocessed++; unsigned char insn_buf[15]; size_t nread = dbg.memory(dbg.rip(), sizeof insn_buf, insn_buf); SgAsmInstruction *insn = NULL; try { insn = disassembler->disassembleOne(insn_buf, dbg.rip(), nread, dbg.rip(), NULL); } catch(const Disassembler::Exception &e) { std::cerr <<"disassembler exception: " <<e <<"\n"; } if (!insn) { dbg.cont(); continue; } /* Trace instructions */ fprintf(stderr, "[%07"PRIu64"] 0x%08"PRIx64": %s\n", nprocessed, insn->get_address(), unparseInstruction(insn).c_str()); /* Single step to cause the instruction to be executed remotely. Then compare our state with the remote state. */ dbg.step(); } exit(1); /*FIXME*/ }
/**************************************************** * 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; } } }
virtual void visit(SgNode* n) { SgAsmInstruction* insn = isSgAsmInstruction(n); if (!insn) return; info->addressToInstructionMap[insn->get_address()] = insn; }
void colorTable(BinQGUI* instance, const std::vector<int >& addInstr, const std::vector<int >& minusInst, vector_start_at_one<SgNode*>& insnsA, vector_start_at_one<SgNode*>& insnsB ) { if (instance==NULL) return; const char* results [] = {"PLUS", "MINUS"}; std::vector<QColor> colors; colors.push_back( QColor(233,150,122) ); colors.push_back( QColor(135,206,255) ); for( unsigned int choice = 0; choice < sizeof(results)/sizeof(char*) ; choice++ ) { std::string currentName(results[choice]); const std::vector< int >& currentResults = ( choice == 0 ? addInstr : minusInst ); QColor& color = colors[choice]; for (unsigned int k=0;k<currentResults.size();++k) { int insnNr = currentResults[k]; SgAsmInstruction* instA = choice == 1 ? isSgAsmInstruction(insnsA[insnNr]) : NULL; SgAsmInstruction* instB = choice == 0 ? isSgAsmInstruction(insnsB[insnNr]) :NULL; #if 0 cerr << choice << " Found " << currentName << " in A (a:" << a <<",b:"<<b<<") : " << endl << " " << RoseBin_support::HexToString(instA->get_address()) << " " << instA->get_mnemonic() <<endl << " " << RoseBin_support::HexToString(instB->get_address()) << " " << instB->get_mnemonic() <<endl; #endif int myPosA=0; int myPosB=0; if(choice == 1) { for(size_t i=0; i < instance->itemsFileA.size(); i++ ) { SgAsmStatement* stmts = isSgAsmStatement(instance->itemsFileA[i]->statement); // ROSE_ASSERT(stmts); SgAsmInstruction* inst = isSgAsmInstruction(stmts); if (inst && inst->get_address()==instA->get_address()) { myPosA=instance->itemsFileA[i]->row; // instance->itemsFileA[i]->plus=true; instance->itemsFileA[i]->bg=color; #if 0 SgNode* node = instance->itemsFileA[i]->statement; ROSE_ASSERT(node); rose_addr_t rt = instance->itemsFileA[i]->addr; ROSE_ASSERT(rt==instA->get_address()); // delete instance->itemsFileA[i]->bg=QColor(255,0,0); QColor col = instance->itemsFileA[i]->bg; string cols = col.name().toStdString(); // instance->codeTableWidget->setBgColor(instance->itemsFileA[i]->bg,0,i); cerr << "Node " << node->class_name() << " address: " << RoseBin_support::HexToString(instA->get_address()) << " color : " << cols << endl; #endif for (int j=1;j<instance->maxrows;j++) { instance->codeTableWidget->setBgColor(instance->itemsFileA[i]->bg,j,i); } } } } else for(size_t i=0; i < instance->itemsFileB.size(); i++ ) { SgNode* stmts = instance->itemsFileB[i]->statement; SgAsmInstruction* inst = isSgAsmInstruction(stmts); if (inst && inst->get_address()==instB->get_address()) { myPosB=instance->itemsFileB[i]->row; instance->itemsFileB[i]->bg=color; for (int j=1;j<instance->maxrows;j++) instance->codeTableWidget2->setBgColor(instance->itemsFileB[i]->bg,j,i); } } std::string resultsString ="%1 Found " + currentName + " in A (a:%2,b:%3) (a:%4,b:%5) %6 %7 "; QString res = QString( resultsString.c_str()) .arg(k) .arg(insnNr) .arg(insnNr) .arg(myPosA) .arg(myPosB) .arg(QString(RoseBin_support::HexToString(choice == 1 ? instA->get_address() : instB->get_address()).c_str())) .arg(QString( choice == 1 ? instA->get_mnemonic().c_str() : instB->get_mnemonic().c_str())); instance->analysisResult->append(res); } } // if (instance) // instance->updateByteItemList(); }
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; }