예제 #1
0
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();
}
예제 #2
0
/*
 * Detect functions (blocks) that can be merged together.
 */
void
RoseBin_FlowAnalysis::resolveFunctions(SgAsmNode* globalNode) {
  //cerr << " ObjDump-BinRose:: Detecting and merging Functions" << endl;
  vector<SgAsmFunction*> visitedFunctions;
  vector<SgNode*> tree =NodeQuery::querySubTree(globalNode, V_SgAsmFunction);
  //  vector<SgNode*>::iterator itV = tree.begin();
  int nr=0;
  while (!tree.empty()) {
    //  for (;itV!=tree.end();itV++) {
    SgAsmFunction* funcD = isSgAsmFunction(tree.back());
    tree.pop_back();
    nr++;
    if ((nr % 100)==0)
      if (RoseBin_support::DEBUG_MODE())
        cerr << " funcListSize : " << tree.size() << "  -- iteration : " << nr << "   func " << funcD->get_name() << endl;

    //SgAsmFunction* funcD = isSgAsmFunction(*itV);
    //itV++;
    ROSE_ASSERT(funcD);
    // make sure we dont visit a function twice


    vector <SgNode*> funcVec =funcD->get_traversalSuccessorContainer();
    int last = funcVec.size()-1;
    if (last<0)
      continue;
    bool hasStopCondition=false;
    for (unsigned int itf = 0; itf < funcVec.size() ; itf++) {
      SgAsmx86Instruction* finst = isSgAsmx86Instruction(funcVec[itf]);
      ROSE_ASSERT(finst);
      if (finst->get_kind() == x86_ret || finst->get_kind() == x86_hlt) {
        hasStopCondition=true;
      }
    }
    //cerr << " last : " << last << endl;
    SgAsmx86Instruction* lastInst = isSgAsmx86Instruction(funcVec[last]);
    ROSE_ASSERT(lastInst);
    SgAsmx86Instruction* nextInst = isSgAsmx86Instruction(resolveFunction(lastInst, hasStopCondition));
    if (nextInst) {
      SgAsmFunction* nextFunc = isSgAsmFunction(nextInst->get_parent());
      if (nextFunc) {
        ROSE_ASSERT(g_algo->info);
        g_algo->info->returnTargets[funcD].insert(g_algo->info->returnTargets[nextFunc].begin(), g_algo->info->returnTargets[nextFunc].end());
        // make sure that this function is being changed and should not be covered again
        //visitedFunctions.push_back(nextFunc);
        // visit current function after alternation again
        //tree.push_back(funcD);
        // now we remove this next function and iterate thrgouh all instructions and
        // attach them to the old function
        vector <SgNode*> funcNextVec =nextFunc->get_traversalSuccessorContainer();
        for (unsigned int i=0; i < funcNextVec.size(); ++i) {
          SgAsmInstruction* inst = isSgAsmInstruction(funcNextVec[i]);
          ROSE_ASSERT(inst);
          inst->set_parent(funcD);
          funcD->append_statement(inst);
          //nextFunc->remove_statement(inst);
          // delete nextFunc; // should delete this later when iterator is done
        }
        nextFunc->remove_children();
        nextFunc->set_parent(NULL);
        isSgAsmBlock(globalNode)->remove_statement(nextFunc);
      }
    }
  } // for

}