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
}
示例#2
0
/* FIXME: Stupid SgAsmInstruction interface necessitates a "switch". [RPM 2011-11-11] */
size_t
Partitioner::count_floating_point(const InstructionMap &insns)
{
    size_t retval = 0;
    for (InstructionMap::const_iterator ii=insns.begin(); ii!=insns.end(); ++ii) {
        SgAsmInstruction *insn = ii->second->node;
        switch (insn->variantT()) {
            case V_SgAsmx86Instruction:
                if (x86InstructionIsFloatingPoint(isSgAsmx86Instruction(insn)))
                    ++retval;
                break;
            default:    // to shut up compiler warnings
                break;
        }
    }
    return retval;
}
示例#3
0
bool
GraphAlgorithms::isDirectCFGEdge(SgGraphNode* sgNode,
                                 SgGraphNode* sgNodeBefore) {
  bool isDirectedControlFlowEdge = false;
  SgAsmInstruction* instSgNode = isSgAsmInstruction(sgNode->get_SgNode());
  SgAsmInstruction* instSgNodeBefore = isSgAsmInstruction(sgNodeBefore->get_SgNode());
  ROSE_ASSERT(instSgNode);
  ROSE_ASSERT(instSgNodeBefore);
  if (instSgNode && instSgNodeBefore) {
    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());
    //cerr << "           -- Checking DirectCFG : f1 == f2?  : " << f1 << " " << f2 << 
    //  "  node: " << sgNode->get_name() << "  and before: " << sgNodeBefore->get_name() << endl;
    if (f1 && f2 && f1==f2) {
      ROSE_ASSERT(info);
      vector<VirtualBinCFG::CFGEdge> outEdges = instSgNodeBefore->cfgBinOutEdges(info);
      //cerr << "           -- Checking DirectCFG between: " << sgNode->get_name() << "  and before: " << 
      //        sgNodeBefore->get_name() << "    nr outedges: " << outEdges.size() << endl;
      for (size_t i = 0; i < outEdges.size(); ++i) {
        if (outEdges[i].target().getNode() == instSgNode) {
          isDirectedControlFlowEdge = true;
          break;
        }
      }
    }
  }
  //  cerr << "     ... checking if isDirectedCFGEdge " << isDirectedControlFlowEdge << endl;
  return isDirectedControlFlowEdge;
}
示例#4
0
/* FIXME: Stupid SgAsmInstruction interface necessitates a "switch". [RPM 2011-11-11] */
size_t
Partitioner::count_kinds(const InstructionMap &insns)
{
    std::set<int> kinds;
    for (InstructionMap::const_iterator ii=insns.begin(); ii!=insns.end(); ++ii) {
        SgAsmInstruction *insn = ii->second->node;
        int kind = -1;
        switch (insn->variantT()) {
            case V_SgAsmx86Instruction:     kind = isSgAsmx86Instruction(insn)    ->get_kind(); break;
            case V_SgAsmPowerpcInstruction: kind = isSgAsmPowerpcInstruction(insn)->get_kind(); break;
            case V_SgAsmArmInstruction:     kind = isSgAsmArmInstruction(insn)    ->get_kind(); break;
            default: break; // to shut up compiler warnings
        }
        if (-1!=kind)
            kinds.insert(kind);
    }
    return kinds.size();
}
示例#5
0
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;
}
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;
}
示例#8
0
 /**  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;
         }
     }    
 }
示例#9
0
void
setupInstructionAttributes ( SgProject* project, vector<SgNode*> instructionList, string comment )
   {
  // Refactored code to setup DataMemberInitializationAttribute objects.

     ROSE_ASSERT(project != NULL);

     printf ("dataMemberInitializationWithoutOffsetInMemberFunction(): instructionList.size() = %zu \n",instructionList.size());

  // Keep track of previously referenced variables to avoid redeclaring them in code generation.
  // set<size_t> usedGlobalOffsets;

     for (size_t i = 0; i < instructionList.size(); i++)
        {
       // Get the SgAsmInstruction
          SgAsmInstruction* instruction = isSgAsmInstruction(instructionList[i]);
          ROSE_ASSERT(instruction != NULL);

       // ROSE_ASSERT(instruction != target);
       // printf ("Processing instruction %s \n",unparseInstructionWithAddress(target).c_str());

       // Build an attribute (on the heap)
       // AstAttribute* newAttribute = new VirtualTableLoad(instruction);
          DataMemberInitializationAttribute* variableAttribute = new DataMemberInitializationAttribute(instruction,project);
          ROSE_ASSERT(variableAttribute != NULL);

       // Add it to the AST (so it can be found later in another pass over the AST)
          instruction->addNewAttribute("DataMemberInitializationAttribute",variableAttribute);

          ROSE_ASSERT(variableAttribute->type != NULL);

       // string comment = "Data member initialization in member function: ";
       // printf ("Attaching comment = %s \n",comment.c_str());
          addComment(instruction,comment);
        }
   }
示例#10
0
/****************************************************
 * process operand tuples. 
 * Handles all expressions to be added to the instructions.
 ****************************************************/
void RoseBin_DB_IDAPRO::process_operand_tuples_query(MYSQL* conn, MYSQL_RES* res_set) {
  // get the functions
  rememberOperandStrings.clear(); // Not needed right now

  char* q = (char*)"SELECT * FROM operand_tuples_1 order by operand_id desc";
  if (RoseBin_support::DEBUG_MODE())
    cout << "\n>> QUERY:: " << q << "\n" << endl;
  res_set = process_query(conn,q);
  if (res_set == NULL) {
    print_problemWithResults(conn);
  } else {
    map < int, vector < SgAsmExpression* > > tmp_instruction_map;
    // tmp_instruction_map.clear();
    
    MYSQL_ROW row;
    long address=0;
    int operand_id=-1;
    int position =-1;

    while ((row = mysql_fetch_row(res_set))!=NULL) {
      for (unsigned int i=0; i<mysql_num_fields(res_set);i++) {
        char* ret=(char*)"";
        if (row[i] ==NULL) {
          ret = (char*)"<NULL>";
          if (i==0) address = -1;
          if (i==1) operand_id = -1;
          if (i==2) position = -1;
        } else { 
          ret= row[i];
          if (i==0) address = atoi(ret);
          if (i==1) operand_id = atoi(ret);
          if (i==2) position = atoi(ret);
        }
      }
      //cerr << " >>>>>>>>>> position : " << position;
      // if this would have to be saved in a map, it would need to be a multimap!!
      //if (RoseBin_support::DEBUG_MODE()) {
      ostringstream addrhex;
      addrhex << hex << setw(8) << address ;

      //cout<< "\n\n----------------------------------------------------------------" << endl;
      if (operand_id % 5000 == 0) {
        cout << ">> creating operand_tuple : address: " << addrhex.str() << " " << address << 
          " -  operand_id: " << operand_id << " -  position:" << position << endl;
      }
      //}

      // get the expr_id for the operand_id
      SgAsmExpression* binExp=NULL;
      //string operand_str=(char*)"";
      if (operand_id>=0) {
        // operand_str = rememberOperandStrings.find(operand_id) != rememberOperandStrings.end() ? rememberOperandStrings[operand_id] : "";
        //if (RoseBin_support::DEBUG_MODE())
        //cout << ">>>> operand_str: " << operand_str <<  endl;
        ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ROOT.size());
        int expr_id_root = rememberExpressionTree_ROOT[operand_id];
        ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ParentChild.size());
        map <int, vector<int> > subTree = rememberExpressionTree_ParentChild[operand_id];

        rememberExpressionTree_ROOT.resize(operand_id + 1);
        rememberExpressionTree_ParentChild.resize(operand_id + 1);

        ROSE_ASSERT (expr_id_root < (int)rememberExpressionTree.size());
        exprTreeType exprTree = rememberExpressionTree[expr_id_root];
        string typeOfOperand = resolveType(&exprTree);

#if 0
        // print multimapsolveRe
        if (RoseBin_support::DEBUG_MODE()) {
          multimap<int,int>::iterator it = subTree.begin();
          for (; it!=subTree.end();++it) {
            int f=it->first;
            int s=it->second;
            cout << " mm : " << f << "," << s << endl;
          }
        }
#endif
        binExp = buildROSE->resolveRecursivelyExpression(address,expr_id_root, 
                                                         subTree, 
                                                         typeOfOperand,
                                                         &rememberExpressionTree,
                                                         operand_id,
                                                         &rememberSubstitution,
                                                         &rememberComments);

      } // if operand

      
      // should save for each instruction, a list of operands and their position
      // and add the operand later on to the instruction
      // map < address, map < pos, binExp > >
      vector<SgAsmExpression*>& currentOperands = tmp_instruction_map[address];
      if (position >= (int)currentOperands.size()) currentOperands.resize(position + 1);
      currentOperands[position] = binExp;
#if 0
      map <int, map <int, SgAsmExpression*> >::iterator tmpIt = tmp_instruction_map.find(address);
      bool found=false;
      if (tmpIt!=tmp_instruction_map.end())
        found=true;
      if (found) {
        //cerr << " found   position: " << position << endl;
        // I do not want to add an address into tmp if not in (side effect!)
        map <int, SgAsmExpression*> tmp_map = tmp_instruction_map[address];
        tmp_map[position] = binExp;
        tmp_instruction_map[address] = tmp_map;
      } else {
        // first time visit
        //cerr << " notfound   position: " << position << endl;
        map <int, SgAsmExpression*> tmp_map;
        tmp_map[position] = binExp;
        tmp_instruction_map[address] = tmp_map;
      }
#endif

    } // while


    // get basic_block and append this instruction
    if (RoseBin_support::DEBUG_MODE())
      cout << "\n\n> appending operandList to instruction.  " << endl;
    rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::iterator blockIt;      
    int count = 0;
    cerr << "Instruction count: " << rememberInstructions.size() << endl;
    for (blockIt=rememberInstructions.begin();blockIt!=rememberInstructions.end();++blockIt) {
      ++count;
      if (count % 1000 == 0) cout << "Adding operands to instruction " << count << endl;
      int inst_address = blockIt->first;
      SgAsmInstruction* remInstr = blockIt->second;
      map<int, vector< SgAsmExpression*> >::iterator it = tmp_instruction_map.find(inst_address);
      if (it != tmp_instruction_map.end()) { // Skip for instructions without operands
        vector < SgAsmExpression*>& exprList_forInst = it->second;
        int sizeList = exprList_forInst.size();
        // find each element separately
        for (int i=0; i<sizeList; i++) {
          SgAsmExpression* binExp = exprList_forInst[i];
#if 0
          map <int, SgAsmExpression*>::iterator it = exprList_forInst.find(i);
          // get the elements in order!! this is important.
          SgAsmExpression* binExp = it->second;
#endif
          
          remInstr->get_operandList()->append_operand(binExp);
          binExp->set_parent(remInstr->get_operandList());
          
          exprTreeType exprTree = buildROSE->getDebugHelp(binExp);
          if (RoseBin_support::DEBUG_MODE())
            cout << ">> append operand (to instruction): binExp: " <<binExp  
                 << " - sym: " <<exprTree.symbol << " - immedi: " << exprTree.immediate << endl;
        }
        tmp_instruction_map.erase(it);
      }
    }

  } // if (res_set==NULL)
  checkError(conn,res_set);
}
示例#11
0
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;
   }
示例#12
0
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*/
}
示例#13
0
/****************************************************
 * process all instructions in the DB
 * add the instructions to the blocks
 ****************************************************/
void RoseBin_DB_IDAPRO::process_instruction_query(MYSQL* conn, MYSQL_RES* res_set) {
  rememberInstructions.clear();
  // get the functions
  //  char* q = (char*)"SELECT * FROM instructions_1";
  char *q = (char*)"select *,     (select parent_function from basic_blocks_1 where id = i.basic_block_id      and (i.address - parent_function) >= 0     and (i.address - parent_function) =     (select min(i.address - parent_function) from basic_blocks_1 where id = i.basic_block_id       and (i.address - parent_function) >= 0)     ) as i_f from instructions_1 i order by i.address"; 

  if (RoseBin_support::DEBUG_MODE())
    cout << "\n>> QUERY:: " << q << "\n" << endl;
  res_set = process_query(conn,q);
  if (res_set == NULL) {
    print_problemWithResults(conn);
  } else {
    
    MYSQL_ROW row;
    string mnemonic=(char*)"";
    uint64_t address=0;
    int basic_block=-1;
    int sequence =-1;
    string data=(char*)"";
    int i_func;

    while ((row = mysql_fetch_row(res_set))!=NULL) {
      for (unsigned int i=0; i<mysql_num_fields(res_set);i++) {
        char* ret=(char*)"";
        if (row[i] ==NULL) { 
          ret = (char*)"<NULL>";
          if (i==0) address = -1;
          if (i==1) basic_block = -1;
          if (i==2) mnemonic = ret;
          if (i==3) sequence = -1;
          if (i==4) data=ret;
          if (i==5) i_func= -1;
        } else {
          ret= row[i];
          if (i==0) address = atoi(ret);
          if (i==1) basic_block = atoi(ret);
          if (i==2) mnemonic = ret;
          if (i==3) sequence = atoi(ret);
          if (i==4) data=ret;
          if (i==5) i_func = atoi(ret);
        }
      }
      // patched to adjust to objdump , Apr 26 2007
      if (mnemonic ==(char*)"retn")
        mnemonic = (char*)"ret";
      
      if (RoseBin_support::DEBUG_MODE()) {
        ostringstream addrhex;
        addrhex << hex << setw(8) << address ;
        cout << ">> creating instruction : " << addrhex.str() << " " << address << 
          " - " << basic_block << " - " << mnemonic << " - " << sequence << endl;
      }
      // check if it is an instruction or if it appears in the callgraph,
      // if it is in the callgraph, one wants to create a BinaryCall instead

      // append the instruction to its function
      rose_hash::unordered_map <int, SgAsmFunction* >::iterator func_it = rememberFunctions.find(i_func);
      SgAsmFunction* func = NULL;
      // for (func_it; func_it!=rememberFunctions.end(); ++func_it) {
      if (func_it != rememberFunctions.end()) {
        func = func_it->second;
      } else {
        if (i_func!=-1)
        cerr << " ERROR : cant find the function i_func : " << i_func << " in rememberFunctions for instruction : " << mnemonic << endl;
      }

      
      SgAsmInstruction* instruction = NULL;
      instruction = createInstruction(address, func, mnemonic);
      //        instruction = new SgAsmInstruction(address,bb,mnemonic,"");
      // Sep 29, tps : commented the following line out, since the function was removed.
      //instruction->set_raw_bytes(data);

      ROSE_ASSERT(instruction);

      SgAsmOperandList* operandList = new SgAsmOperandList();
      instruction->set_operandList(operandList);
      operandList->set_parent(instruction);

      ostringstream hexaddr;
      hexaddr << hex << setw(8) << address ;
      if (RoseBin_support::DEBUG_MODE())
        cout << " .rememberInstruction " << instruction->class_name() 
             << "  at : " << address << " hex: " << hexaddr.str() << endl;
      rememberInstructions[address]= instruction ;


      if (func) {
        // get the block in the func and append to it to conform to jeremiah
        func->append_statement(instruction);
        instruction->set_parent(func);
        //vector <SgNode*> blockVec =func->get_traversalSuccessorContainer();
        //SgAsmBlock* block = isSgAsmBlock(blockVec[0]);
        //ROSE_ASSERT(block);
        //block->append_statement(instruction);
        //instruction->set_parent(block);

        ROSE_ASSERT(instruction->get_parent());

        //SgAsmNode* nInst = (SgAsmNode*) instruction;
        //nInst->set_parent(func);

        ostringstream addrhex;
        addrhex << hex << setw(8) << i_func ;
        if (RoseBin_support::DEBUG_MODE())
          cout << ">> appended instruction to function: " << func->get_name() << " addr " << addrhex.str() << " " << address << endl;
      } else {
        if (i_func!=-1) {
          cerr << " ERROR :: could not append instruction to function : " << endl;
          //exit(0);
        }
      }
      
    } // while

  } // if (res_set==NULL)
  checkError(conn,res_set);
}
示例#14
0
void
detectVirtualTableLoad( SgProject* project )
{
    // This function detects the case of a virtual table address load at "address":
    //    mov edx, <address>
    // In the process of detecting the virtual table loads is adds attributes
    // to the section where the virtual tables are put and builds a list of
    // virtual tables.

    // This is a pointer to the ".rodata" section.
    // What happens if we process multiple DLL's where each has it's own ".rodata" section?
    // This case would suggest that we really do need to fram this as a top-down and bottom-up traversal.
    SgAsmElfSection* vTableSection = getVirtualTableSection(project);
    ROSE_ASSERT(vTableSection != NULL);

#if 0
    // This will return NULL (or generate NULL internally).
    SgAsmInterpretation* asmInterpretation = getAsmInterpretation(vTableSection);
    ROSE_ASSERT(asmInterpretation != NULL);
#endif

    // This is the base and bound of the mapped memory representing the ".rodata" section.
    // NOTE: Now that we compute the ".rodata" section, we should refactor this to be a
    // way to get the bounding addresses of the mapped memory section (and use the
    // vTableSection as a function argument).
    pair<size_t,size_t> readOnlyDataSectionAddressBoundary = getVirtualTableSectionBoundaries(project);
    printf ("Section .rodata boundary: address_base = %p address_bound = %p \n",(void*)readOnlyDataSectionAddressBoundary.first,(void*)readOnlyDataSectionAddressBoundary.second);

    // SgAsmElfSection* textSection = getSection(project,".text");
    // ROSE_ASSERT(textSection != NULL);

    // Pass the project so that we can provide for more analysis capability within the VirtualTableSection abstraction.
    VirtualTableSection* virtualTableSectionAttribute = new VirtualTableSection(vTableSection,project);
    ROSE_ASSERT(virtualTableSectionAttribute != NULL);

    // Add it to the AST (so it can be found later in another pass over the AST)
    vTableSection->addNewAttribute("VirtualFunctionTableSectionAttribute",virtualTableSectionAttribute);

    // Alternative approach using a example and searching the AST for a match against the example.
    // printf ("Alternative approach using a example and searching the AST for a match against the example. \n");

    // General template to use in matching against project.
    // Build a specific instruction to match a specific address (in .rodata, where the vitual function tables are located)
#ifdef USE_NEW_ISA_INDEPENDENT_REGISTER_HANDLING
    SgAsmInstruction* target = SageBuilderAsm::buildx86Instruction(x86_mov,
                               SageBuilderAsm::buildAsmx86RegisterReferenceExpression(x86_regclass_gpr,SgAsmx86RegisterReferenceExpression::e_edx),
                               // Note that the address value is ignored in our "equivalenceTest()" function.
                               SageBuilderAsm::buildAsmDWordValue(0x0));
    printf ("Target instruction = %s \n",unparseInstructionWithAddress(target).c_str());
#else
    // DQ (9/2/2013): This allows us to get the existing code compiled and then move to update the code seperately.
    printf ("This code needs to be updated to handle the new register handling (ISA independence) \n");
    ROSE_ASSERT(false);

    SgAsmInstruction* target = NULL;
#endif

    ROSE_ASSERT(target != NULL);

    // General function to find matching target AST in larger AST.
    std::vector<SgNode*> matchingSubtreeList = find ( project, target, equivalenceTest );

    // Use a set so that after processing all instructions we have the collection of unique entries.
    set<size_t> setOfVirtualFunctionTables;

    for (size_t i = 0; i < matchingSubtreeList.size(); i++)
    {
        // Get the SgAsmInstruction
        SgAsmInstruction* instruction = isSgAsmInstruction(matchingSubtreeList[i]);
        ROSE_ASSERT(instruction != NULL);
        ROSE_ASSERT(instruction != target);

        printf ("Processing instruction %s \n",unparseInstructionWithAddress(target).c_str());

        // Build an attribute (on the heap)
        // AstAttribute* newAttribute = new VirtualTableLoad(instruction);
        VirtualTableLoad* newAttribute = new VirtualTableLoad(instruction);
        ROSE_ASSERT(newAttribute != NULL);

        // Accumulate the set of virtual function table addresses.
        size_t virtualFunctionTableAddress = get_value(newAttribute->virtualTableAddress);
        printf ("virtualFunctionTableAddress = %p \n",(void*)virtualFunctionTableAddress);
        printf ("readOnlyDataSectionAddressBoundary.first = %p second = %p \n",(void*)readOnlyDataSectionAddressBoundary.first,(void*)readOnlyDataSectionAddressBoundary.second);

        // This absolutely needs the extra "()" around both of the inner predicates.
        bool inRange = ((virtualFunctionTableAddress > readOnlyDataSectionAddressBoundary.first) &&
                        (virtualFunctionTableAddress < readOnlyDataSectionAddressBoundary.second));

        printf ("inRange = %s \n",inRange ? "true" : "false");

        // If this is ever false then we will need to introduce a conditional to only handle the true cases.
        // ROSE_ASSERT(inRange == true); // can be false for GNU g++ 4.1.x compilers
        if (inRange == true)
        {
            // Add it to the AST (so it can be found later in another pass over the AST)
            instruction->addNewAttribute("VirtualTableLoad",newAttribute);

            // Collect the virtual table addresses into the set.
            setOfVirtualFunctionTables.insert(virtualFunctionTableAddress);
        }
        else
        {
            // If it is not used then delete the analysis attribute
            delete newAttribute;
            newAttribute = NULL;
        }

#if 0
        string comment = "Virtual Table Load: " + get_valueString(newAttribute->virtualTableAddress);

        printf ("Attaching comment = %s \n",comment.c_str());
        addComment(instruction,comment);
#endif
    }

    printf ("Number of unique virtual function tables = %zu \n",setOfVirtualFunctionTables.size());

    int counter = 0;
    for (set<size_t>::iterator i = setOfVirtualFunctionTables.begin(); i != setOfVirtualFunctionTables.end(); i++)
    {
        // This is the address of each virtual function table.
        size_t virtualFunctionTableAddress = *i;

        // These are the separate virtual function tables objects used to summarize analysis.
        ROSE_ASSERT(virtualTableSectionAttribute->tableExists(virtualFunctionTableAddress) == false);
        if (virtualTableSectionAttribute->tableExists(virtualFunctionTableAddress) == false)
        {
            VirtualFunctionTable* vt = new VirtualFunctionTable(project,vTableSection,virtualFunctionTableAddress);
            ROSE_ASSERT(vt != NULL);

            vt->name = "Class_From_vTable_" + StringUtility::numberToString(counter);

            printf ("vt->name = %s \n",vt->name.c_str());

            // This might be depricated in favor of putting the virtual function table list into globalScopeAttribute.
            virtualTableSectionAttribute->virtualFunctionTableList.push_back(vt);

            // This is the more appropriate place for the list of virtual function tables.
            ROSE_ASSERT(globalScopeAttribute != NULL);
            globalScopeAttribute->virtualFunctionTableList.push_back(vt);

            for (size_t i = 0; i < matchingSubtreeList.size(); i++)
            {
                // Get the SgAsmInstruction
                SgAsmInstruction* instruction = isSgAsmInstruction(matchingSubtreeList[i]);
                ROSE_ASSERT(instruction != NULL);

                VirtualTableLoad* attribute = dynamic_cast<VirtualTableLoad*>(instruction->getAttribute("VirtualTableLoad"));

                // This can be false for GNU g++ 4.1.x compilers
                // ROSE_ASSERT(attribute != NULL);

                if (attribute != NULL)
                {
                    size_t local_virtualFunctionTableAddress = get_value(attribute->virtualTableAddress);
                    if (local_virtualFunctionTableAddress == virtualFunctionTableAddress)
                    {
                        attribute->associatedVirtualTable = vt;
                    }
                    else
                    {
                        attribute->associatedVirtualTable = NULL;
                    }
                }
            }

            counter++;
        }

        // These are the separate virtual function tables.
        // virtualTableSectionAttribute->printOutVirtualFunctionTableInformation(virtualFunctionTableAddress);
    }

    printf ("Adding comments to the instructions \n");

    // Add comments
    for (size_t i = 0; i < matchingSubtreeList.size(); i++)
    {
        printf ("matchingSubtreeList -- i = %zu \n",i);

        // Get the SgAsmInstruction
        SgAsmInstruction* instruction = isSgAsmInstruction(matchingSubtreeList[i]);
        ROSE_ASSERT(instruction != NULL);

        printf ("Getting the VirtualTableLoad attribute \n");

        VirtualTableLoad* attribute = dynamic_cast<VirtualTableLoad*>(instruction->getAttribute("VirtualTableLoad"));

        // This can be false for GNU g++ 4.1.x compilers
        // ROSE_ASSERT(attribute != NULL);

        if (attribute != NULL)
        {
            // This can be false for GNU g++ 4.1.x compilers
            // ROSE_ASSERT(attribute->associatedVirtualTable != NULL);

            if (attribute->associatedVirtualTable != NULL)
            {
                printf ("Building a comment \n");
                printf ("attribute->virtualTableAddress = %p \n",(void*)attribute->virtualTableAddress);
                printf ("attribute->associatedVirtualTable->name = %s \n",attribute->associatedVirtualTable->name.c_str());

                string comment = "Virtual Table Load: name = " + attribute->associatedVirtualTable->name + " " + get_valueString(attribute->virtualTableAddress);

                printf ("Attaching comment = %s \n",comment.c_str());
                addComment(instruction,comment);
            }
        }
    }

    printf ("Leaving detectVirtualTableLoad() \n");
}
示例#15
0
 virtual void visit(SgNode* n) {
     SgAsmInstruction* insn = isSgAsmInstruction(n);
     if (!insn) return;
     info->addressToInstructionMap[insn->get_address()] = insn;
 }
示例#16
0
/****************************************************
 * 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;
    }
  }
}
示例#17
0
void
RoseBin_FlowAnalysis::process_jumps() {
    if (RoseBin_support::DEBUG_MODE())
      cerr << "\n >>>>>>>>> processing jumps ... " << endl;
  rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::iterator it;
  for (it=rememberInstructions.begin();it!=rememberInstructions.end();++it) {
    SgAsmx86Instruction* inst = isSgAsmx86Instruction(it->second);
    if (inst->get_kind() == x86_call) {
      //cerr << "Found call at " << std::hex << inst->get_address() << endl;
      SgAsmx86Instruction* target = isSgAsmx86Instruction(process_jumps_get_target(inst));
      if (target) {
        //cerr << "Target is " << std::hex << target->get_address() << endl;
        // inst->get_targets().push_back(target);
        // we set the sources (for each node)
        ROSE_ASSERT(g_algo->info);
        g_algo->info->incomingEdges[target].insert(inst->get_address());
        // tps: changed this algorithm so that it runs in
        // linear time!
        ROSE_ASSERT (target->get_parent());
        if (target->get_parent()) {
          // ROSE_ASSERT(target->get_parent());
          SgAsmNode* b_b = target;
          if (!db)
            b_b = isSgAsmNode(target->get_parent());
          ROSE_ASSERT(b_b);
          SgAsmFunction* b_func = isSgAsmFunction(b_b->get_parent());

          if (b_func) {
            // (16/Oct/07) tps: this is tricky, it appears that sometimes the target can
            // be just a jmp to a new location, so we should forward this information to the correct
            // function.
            // Therefore we need to check if the current function has a return statement.
            // If not, we want to forward this information.
            if (target->get_kind() == x86_jmp) {
              //cerr << " >>>>>>>> found a jmp target - number of children: " << b_func->get_traversalSuccessorContainer().size() << endl;
              if (b_func->get_numberOfTraversalSuccessors()==1) {
                SgAsmx86Instruction* target2 = isSgAsmx86Instruction(process_jumps_get_target(inst));
                if (target2) {
                  b_b = target2;
                  if (!db)
                    b_b = isSgAsmNode(target2->get_parent());
                  b_func = isSgAsmFunction(b_b->get_parent());
                }
              }
            }


            if (inst->get_parent()) {
              //cerr << "Inst has a parent" << endl;
              if (inst->get_comment()=="")
                inst->set_comment(""+b_func->get_name());
              ROSE_ASSERT(g_algo->info);
              SgAsmInstruction* inst_after = g_algo->info->getInstructionAtAddress(inst->get_address() + inst->get_raw_bytes().size()); // inst->cfgBinFlowOutEdge(info);
              if (inst_after) {
                //cerr << "Added dest " << std::hex << isSgAsmStatement(inst_after)->get_address() << " for function" << endl;
                b_func->append_dest(isSgAsmStatement(inst_after));
              }
            }
          } else {
            if (RoseBin_support::DEBUG_MODE())
            cerr << " NO FUNCTION DETECTED ABOVE BLOCK . " << endl;
          }

        } else {
          if (RoseBin_support::DEBUG_MODE())
            cerr << "   WARNING :: process_jumps: target has no parent ... i.e. no FunctionDeclaration to it " <<
            target->class_name() << endl;
        }
      } else {
        if (inst)
          if (RoseBin_support::DEBUG_MODE())
            cerr << "    WARNING :: process_jumps: No target found for node " << RoseBin_support::HexToString(inst->get_address())
                 << "   " << inst->get_mnemonic() << endl;
      }
    } else {

      // might be a jmp
      SgAsmx86Instruction* target = isSgAsmx86Instruction(process_jumps_get_target(inst));
      if (target) {
        // inst->get_targets().push_back(target);
        // we set the sources (for each node)
        ROSE_ASSERT(g_algo->info);
        g_algo->info->incomingEdges[target].insert(inst->get_address());
      }
    }
  }
  //cerr << "\n >>>>>>>>> processing jumps ... done. " << endl;

  //  cerr << "\n >>>>>>>>> resolving RET jumps ... " << endl;
  rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::iterator it2;
  for (it2=rememberInstructions.begin();it2!=rememberInstructions.end();++it2) {
    //int id = it2->first;
    SgAsmx86Instruction* target = isSgAsmx86Instruction(it2->second);
    ROSE_ASSERT (target);
#if 1
    if (target->get_kind() == x86_ret) {
      SgAsmNode* b_b = target;
      if (!db)
        b_b = isSgAsmNode(target->get_parent());
      SgAsmFunction* parent = isSgAsmFunction(b_b->get_parent());
      if (parent) {
        //ROSE_ASSERT(parent);
        std::vector <SgAsmStatement*> dest_list = parent->get_dest();
        for (size_t i = 0; i < dest_list.size(); ++i) {
          ROSE_ASSERT (isSgAsmInstruction(dest_list[i]));
          //cerr << "Adding ret target " << std::hex << dest_list[i]->get_address() << " to " << std::hex << target->get_address() << endl;
          //info->indirectJumpAndReturnTargets[target].insert(dest_list[i]->get_address());
          ROSE_ASSERT(g_algo->info);
          g_algo->info->incomingEdges[isSgAsmInstruction(dest_list[i])].insert(target->get_address());
        }

        std::vector <SgAsmStatement*>::iterator it3 = dest_list.begin();
        for (; it3!=dest_list.end();++it3) {
          SgAsmInstruction* dest = isSgAsmInstruction(*it3);
          if (dest) {
            dest->append_sources(target);
            //cerr << " appending source to " << dest->get_address() << "   target: " << target->get_address() << endl;
          }
        } // for
      } else { // if parent
        if (RoseBin_support::DEBUG_MODE())
          cerr << "   ERROR :: RET jumps :: no parent found for ret : " << target->class_name() << endl;
        //exit (0);
      }
    } // if ret
#endif
  }
  if (RoseBin_support::DEBUG_MODE())
    cerr << " >>>>>>>>> resolving RET jumps ... done." << endl;
}
/***********************************************************************
 * (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
}
示例#19
0
SgAsmInstruction*
RoseBin_FlowAnalysis::process_jumps_get_target(SgAsmx86Instruction* inst) {
  if (inst && x86InstructionIsControlTransfer(inst)) {
    //cerr << " ..................... processing jmp " << endl;
    ostringstream addrhex3;
    int addrsource = inst->get_address();
    addrhex3 << hex << setw(8) << addrsource ;
    string funcName ="";

    // get the operand and the destination address
    SgAsmOperandList* opList = inst->get_operandList();
    ROSE_ASSERT(opList);
    SgAsmExpressionPtrList ptrList = opList->get_operands();

    std::vector<SgAsmExpression*>::iterator itList= ptrList.begin();
    for (;itList!=ptrList.end();++itList) {
      SgAsmExpression* exp = *itList;
      ROSE_ASSERT(exp);
      SgAsmRegisterReferenceExpression* regRef = isSgAsmRegisterReferenceExpression(exp);

      //if (RoseBin_support::DEBUG_MODE())
      //        cout << " inst (jmp):: " << inst->get_mnemonic() << "  addr : " << addrhex3.str() << endl;
      SgAsmValueExpression* valExpr = isSgAsmValueExpression(exp);
      SgAsmMemoryReferenceExpression* memExpr = isSgAsmMemoryReferenceExpression(exp);
      string valStr = "";
      if (valExpr) {
        uint8_t byte_val=0xF;
        uint16_t word_val=0xFF;
        uint32_t double_word_val=0xFFFF;
        uint64_t quad_word_val=0xFFFFFFFFU;

        valStr =
          RoseBin_support::resolveValue(valExpr, true,
                                        byte_val,
                                        word_val,
                                        double_word_val,
                                        quad_word_val);

        //if (RoseBin_support::DEBUG_MODE())
        //cout << "   found value ....... :: " << valStr << endl;
        funcName = valExpr->get_replacement();
        //if (funcName=="")
        //  funcName="noName";
      }
      if (memExpr) {
        continue;
        // this is a jump to data ... do not handle right now!!
      }

      // convert val string to long
      uint64_t val=0;
      if(from_string<uint64_t>(val, valStr, std::hex)) {
        ostringstream addrhex2;
        addrhex2 << hex << setw(8) << val ;
        //if (RoseBin_support::DEBUG_MODE())
        //cerr << "    looking for value ("<<valStr << " ) in InstrSet: "
        //     << val << "  " << addrhex2.str() << endl;
        rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::const_iterator itc =
          rememberInstructions.find(val);
        if (itc!=rememberInstructions.end()) {
          SgAsmInstruction* target = itc->second;

          // we set the target (jump to for each control instruction)
          ROSE_ASSERT(target);


          //if (RoseBin_support::DEBUG_MODE())
          //cout << "    >>> target found! " << target << "     funcName " << funcName << endl;
          if (funcName!="") {
            SgAsmNode* block = target;
            if (!db)
              block = isSgAsmNode(target->get_parent());
            ROSE_ASSERT(block);
            SgAsmFunction* func = isSgAsmFunction(block->get_parent());

            if (func) {
              string fname = func->get_name();
              uint64_t val_f=0;
              if(from_string<uint64_t>(val_f, fname, std::hex)) {
                // func name is a hex number
                func->set_name(funcName);
                //              inst->set_comment(funcName);
              } else {
                // its a name
              }
            }
          }
          return target;
        } else {
          //if (RoseBin_support::DEBUG_MODE())
          //  cerr << "    >>>>>>>>>>>>>>> !!! OPS :: Target not found ...  \n" << endl;
        }
      }
      else{
        //      std::cerr << "FlowAnalysis ::  from_string failed .. " << std::endl;
        if (valStr!="")
          if (RoseBin_support::DEBUG_MODE())
          cerr << " WARNING: Cant convert string to long - in process_jump  :: " << regRef->class_name() <<
            " inst :: " << inst->get_mnemonic() << "  addr : " << addrhex3.str() << " target : " << valStr << endl;
      }
    }

  }
  return NULL;
}
示例#20
0
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;
}
示例#21
0
文件: Clone.C 项目: 8l/rose
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();
}
示例#22
0
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;
}
示例#23
0
void
setupVariableDeclartionAttributes ( SgProject* project, vector<SgNode*> instructionList )
   {
  // Refactored code to setup DataMemberInitializationAttribute objects.

     ROSE_ASSERT(project != NULL);

     printf ("dataMemberInitializationWithoutOffsetInMemberFunction(): instructionList.size() = %zu \n",instructionList.size());

  // Keep track of previously referenced variables to avoid redeclaring them in code generation.
  // set<size_t> usedGlobalOffsets;

     for (size_t i = 0; i < instructionList.size(); i++)
        {
       // Add another comment.
          string comment = "This is a reference to variable: ";

       // Get the SgAsmInstruction
          SgAsmInstruction* instruction = isSgAsmInstruction(instructionList[i]);
          ROSE_ASSERT(instruction != NULL);

          DataMemberInitializationAttribute* variableAttribute = dynamic_cast<DataMemberInitializationAttribute*>(instruction->getAttribute("DataMemberInitializationAttribute"));
          ROSE_ASSERT(variableAttribute != NULL);

       // Now add the analysis attribute that represents variables referenced in the binary.
          if (variableAttribute->isStackVariable == true)
             {
            // This is a stack variable reference defined in a function.

            // DQ (9/2/2013): Modified to reflect name change in SgAsmFunctionDeclaration to SgAsmFunction.
            // SgAsmFunctionDeclaration* functionDeclaration = getAsmFunctionDeclaration(instruction);
               SgAsmFunction* functionDeclaration = getAsmFunction(instruction);
               ROSE_ASSERT(functionDeclaration != NULL);

            // This can be either a FunctionAnalysisAttribute or MemberFunctionAnalysisAttribute pointer.
               FunctionAnalysisAttribute* functionAnalysisAttribute = dynamic_cast<FunctionAnalysisAttribute*>(functionDeclaration->getAttribute("FunctionAnalysisAttribute"));
               ROSE_ASSERT(functionAnalysisAttribute != NULL);

            // Add it to the AST (so it can be found later in another pass over the AST)
            // functionDeclaration->addNewAttribute("FunctionAnalysisAttribute",functionAnalysisAttribute);

            // Build an analysis attribute specific to the type of each stack variable reference.
               TypeAnalysisAttribute* asmTypeAttribute = new TypeAnalysisAttribute(variableAttribute->offset,variableAttribute->type);
               ROSE_ASSERT(asmTypeAttribute != NULL);

            // Make up a name for the variable.
            // asmTypeAttribute->name = "stackVar_" + StringUtility::numberToString(i);
               asmTypeAttribute->name = "stackVar_" + generateUniqueName ( variableAttribute->offset, functionAnalysisAttribute->usedScopeOffsets, functionAnalysisAttribute->variableCounter );

            // Improve the comments by adding the stack variable name.
               comment += " variable: " + asmTypeAttribute->name;

            // Add this variable's type to the list of variable types with addresses on the stack.
               functionAnalysisAttribute->stackTypeList.push_back(asmTypeAttribute);
             }
            else
             {
            // This is a global variable reference (used from anywhere in the program).

            // Verify we have a valid pointer (global variable).
               ROSE_ASSERT(globalScopeAttribute != NULL);

               size_t offset = variableAttribute->offset;

            // if (usedGlobalOffsets.find(offset) == usedGlobalOffsets.end())
                  {
                 // Add this entry so that it will not be reused.
                 // usedGlobalOffsets.insert(offset);

                    TypeAnalysisAttribute* asmTypeAttribute = new TypeAnalysisAttribute(offset,variableAttribute->type);
                    ROSE_ASSERT(asmTypeAttribute != NULL);

                 // Make up a name for the variable.
                 // asmTypeAttribute->name = "globalVar_" + StringUtility::numberToString(i);
                    asmTypeAttribute->name = "globalVar_" + generateUniqueName ( variableAttribute->offset, globalScopeAttribute->usedScopeOffsets, globalScopeAttribute->variableCounter );

                 // Improve the comments by adding the globald variable name.
                    comment += " variable: " + asmTypeAttribute->name;

                 // Add this variable's type to the list of variable types with addresses on the stack.
                    globalScopeAttribute->stackTypeList.push_back(asmTypeAttribute);
                  }
             }

       // string comment = "Data member initialization in member function: ";
       // printf ("Attaching comment = %s \n",comment.c_str());
          addComment(instruction,comment);
        }
   }
示例#24
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

}