예제 #1
0
void normalizeInstructionInSubTree(SgNode* topNode ){
  vector<SgAsmx86Instruction*> insns;
  FindInstructionsVisitor vis;
  AstQueryNamespace::querySubTree(topNode, std::bind2nd( vis, &insns ));

  for(std::vector<SgAsmx86Instruction*>::iterator iItr = insns.begin(); iItr !=  insns.end();
      ++iItr)
  {
      SgAsmx86Instruction* insn = *iItr;
       SgAsmExpressionPtrList& operands = getOperands(insn);
      // Add to total for this variant
      // Add to total for each kind of operand
      size_t operandCount = operands.size();

      for (size_t i = 0; i < operandCount; ++i) {
        SgAsmExpression* operand = operands[i];
        SgAsmExpression* newOperand;
        if( isSgAsmMemoryReferenceExpression(operand) )
        {
          SgAsmMemoryReferenceExpression* memRefExp = new SgAsmMemoryReferenceExpression;
          SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression;
          wordVal->set_value(0);

          memRefExp->set_segment(wordVal);
          memRefExp->set_address(wordVal);
          memRefExp->set_type(new SgAsmTypeWord);
          newOperand = memRefExp;
        }else if(isSgAsmRegisterReferenceExpression(operand) ){
          SgAsmx86RegisterReferenceExpression* regRef = new SgAsmx86RegisterReferenceExpression;
          regRef->get_descriptor().set_major(x86_regclass_mm);
          regRef->get_descriptor().set_minor(0);

          newOperand = regRef;

        }else{
          SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression;
          wordVal->set_value(0);
          newOperand = wordVal;
          
        }

        newOperand->set_parent(operand->get_parent());

        DeleteSgTree(operands[i]);
        operands[i]=newOperand;
      }
        //std::cout << "Unparsed: " <<unparseX86Instruction(insn)<< std::endl;

  }







};
예제 #2
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);
}
예제 #3
0
/****************************************************
 * create a BinaryNode
 ****************************************************/
SgAsmExpression* RoseBin_IDAPRO_buildTree::convertBinaryNode(exprTreeType* expt, 
                                                             list<SgAsmExpression*> *children, 
                                                             const string& typeOfOperandIn) {
  string typeOfOperand = typeOfOperandIn;
  SgAsmExpression* binNode=NULL;
  int sizeOfList = children->size();
  bool isLeaf = false;
  if (sizeOfList==0)
    isLeaf = true;
  if (RoseBin_support::DEBUG_MODE()) {
    ostringstream addrhex;
    addrhex << hex << setw(8) << expt->immediate ;

    cout << "\n>> convert binNode: expr_id: " << expt->id << endl;
    cout << "   isLeaf: " << RoseBin_support::resBool(isLeaf) << 
      "  symbol: " << expt->symbol << 
      "  immedi: " << expt->immediate << " hex: " << addrhex.str() << endl;
  }

  if (expt->expr_type==4) {
    // this is a operator
    if (RoseBin_support::DEBUG_MODE())
      cout << " its a operator ... " << expt->symbol << endl;

    string symbol = RoseBin_support::str_to_upper(expt->symbol);
    if (symbol=="CS" || symbol=="DS" || symbol=="SS" || symbol=="ES"
        || symbol == "FS" || symbol=="GS") {
      // we need the child information to build this
      if (sizeOfList!=1) {
        //cerr << " a reference expression can only take one child! " <<endl;
        list<SgAsmExpression*>::iterator childList = children->begin();
        for (; childList!=children->end();++childList) {
          SgAsmExpression* child = *childList;
          exprTreeType exprTree =  debugHelpMap[child];
          //cout << " children are : " << child << " -- " << exprTree.symbol << endl;
        }
        
        abort();
      }
      SgAsmExpression* child = *(children->begin());
      ROSE_ASSERT(RoseAssemblyLanguage==x86);
      RegisterDescriptor regDesc;
      resolveRegisterX86(symbol, &regDesc);
      if (isSgAsmMemoryReferenceExpression(child)) {
        binNode = new SgAsmx86RegisterReferenceExpression(regDesc);
        isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc));
        isSgAsmMemoryReferenceExpression(child)->set_segment(binNode);
        binNode->set_parent(child);
        binNode=child;

      } else {
        binNode = child;
        // do nothing
        // if we have a jump case, we have a value only and no RegRef
      }
#if 0
      // resolve the register information
      if (RoseAssemblyLanguage==x86) {
        SgAsmRegisterReferenceExpression::x86_register_enum registerSg = 
          SgAsmRegisterReferenceExpression::undefined_general_register;
        SgAsmRegisterReferenceExpression::x86_position_in_register_enum regSize =  
          SgAsmRegisterReferenceExpression::undefined_position_in_register;
        resolveRegisterX86(symbol, &registerSg, &regSize);
        //      binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize);
        binNode = new SgAsmRegisterReferenceExpression();
        (isSgAsmRegisterReferenceExpression(binNode))->set_x86_register_code(registerSg);
        (isSgAsmRegisterReferenceExpression(binNode))->set_x86_position_in_register_code(regSize);
      } else if (RoseAssemblyLanguage==arm) {
        SgAsmRegisterReferenceExpression::arm_register_enum registerSg = 
          SgAsmRegisterReferenceExpression::undefined_arm_register;
        SgAsmRegisterReferenceExpression::arm_position_in_register_enum regSize =  
          SgAsmRegisterReferenceExpression::undefined_arm_position_in_register;
        resolveRegisterX86(symbol, &registerSg, &regSize);
        //      binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize);
        binNode = new SgAsmRegisterReferenceExpression();
        (isSgAsmRegisterReferenceExpression(binNode))->set_arm_register_code(registerSg);
        (isSgAsmRegisterReferenceExpression(binNode))->set_arm_position_in_register_code(regSize);
      }
      // the child could be the expression to an address,  e.g. ss:[ebp]
      
      // todo : dont know how to change this right now. Affected by AST structure change
      //isSgAsmRegisterReferenceExpression(binNode)->set_segment(child); 
      rememberOffset = isSgAsmRegisterReferenceExpression(binNode);
      if (child==NULL) {
        cerr << "adding no child to RegisterReference " << endl;
      }
      child->set_parent(binNode);
#endif
    }
    else if (expt->symbol=="+") {
      list<SgAsmExpression*>::iterator childList = children->begin();
      int count=0;
      if (children->size()==1) {
        // the add has only one child
        SgAsmExpression* child = *(children->begin());
        if (child) {
          binNode = child;
          // child->set_parent(previousExp);
          // if (isSgAsmMemoryReferenceExpression(previousExp)) 
          //   isSgAsmMemoryReferenceExpression(previousExp)->set_address(child);
          // changed on 16Jan08
          //if (isSgAsmRegisterReferenceExpression(previousExp))
          //  isSgAsmRegisterReferenceExpression(previousExp)->set_offset(child);
        }
      } else {
        binNode = new SgAsmBinaryAdd();        
        for (; childList!=children->end();++childList) {
          SgAsmExpression* child = *childList;
          if (child) {
            if (count==0)
              isSgAsmBinaryAdd(binNode)->set_lhs(child);
            else
              isSgAsmBinaryAdd(binNode)->set_rhs(child);
            child->set_parent(binNode);
          }
          count++;
        }
      }
    } 
    else if (expt->symbol=="-") {
      binNode = new SgAsmBinarySubtract();
      list<SgAsmExpression*>::iterator childList = children->begin();
      int count=0;
      for (; childList!=children->end();++childList) {
        SgAsmExpression* child = *childList;
        if (count==0)
          isSgAsmBinarySubtract(binNode)->set_lhs(child);
        else
          isSgAsmBinarySubtract(binNode)->set_rhs(child);
        count++;
        child->set_parent(binNode);
      }
    } 
    else if (expt->symbol=="*") {
      binNode = new SgAsmBinaryMultiply();
      list<SgAsmExpression*>::iterator childList = children->begin();
      int count=0;
      for (; childList!=children->end();++childList) {
        SgAsmExpression* child = *childList;
        if (count==0)
          isSgAsmBinaryMultiply(binNode)->set_lhs(child);
        else
          isSgAsmBinaryMultiply(binNode)->set_rhs(child);
        count++;
        child->set_parent(binNode);
      }
    } 
    else if (expt->symbol=="/") {
      binNode = new SgAsmBinaryDivide();
      list<SgAsmExpression*>::iterator childList = children->begin();
      int count=0;
      for (; childList!=children->end();++childList) {
        SgAsmExpression* child = *childList;
        if (count==0)
          isSgAsmBinaryDivide(binNode)->set_lhs(child);
        else
          isSgAsmBinaryDivide(binNode)->set_rhs(child);
        count++;
        child->set_parent(binNode);
      }
    } 
    else if (expt->symbol=="[") {
      // the child is the expression that constitutes the address , e.g. [ebp]
      SgAsmExpression* child = *(children->begin());
      // the child is another expression, like +, - , ...
      ROSE_ASSERT(child);
      binNode = new SgAsmMemoryReferenceExpression();
      isSgAsmMemoryReferenceExpression(binNode)->set_type(SgAsmTypeQuadWord::createType());
      ROSE_ASSERT (binNode->get_type());

      isSgAsmMemoryReferenceExpression(binNode)->set_address(child);
      child->set_parent(binNode);
      //      isSgAsmMemoryReferenceExpression(binNode)->set_offset(rememberOffset);
      //rememberOffset->set_parent(binNode);
      //rememberOffset=NULL;
    } 
    
    else if (expt->symbol=="b4" || expt->symbol=="b2" || expt->symbol=="b1" || expt->symbol=="b6" || expt->symbol=="b8") {
      // since b4, b2, b1 are types and no nodes,
      // we return the binNode of the child
      binNode = *(children->begin());
      if (isSgAsmMemoryReferenceExpression(binNode)) {
        SgAsmMemoryReferenceExpression* memRefT = isSgAsmMemoryReferenceExpression(binNode);
        if (expt->symbol=="b1") 
          memRefT->set_type(SgAsmTypeByte::createType());
        else if (expt->symbol=="b2") 
          memRefT->set_type(SgAsmTypeWord::createType());
        else if (expt->symbol=="b4") 
          memRefT->set_type(SgAsmTypeDoubleWord::createType());
        else if (expt->symbol=="b6") 
          memRefT->set_type(SgAsmTypeByte::createType()); // FIXME
        else if (expt->symbol=="b8") 
          memRefT->set_type(SgAsmTypeQuadWord::createType());
        ROSE_ASSERT (memRefT->get_type());
      } 
    }

    else {
      cerr << "ERROR:: FIXME:: symbol not resolved " << expt->symbol << endl;
      // temp solution for arm. tps (09/17/07)
      binNode = new SgAsmIntegerValueExpression('5', 8); // ascii for 5

      //      exit(0);
    }
  } 

  else if (expt->expr_type==2) {
    // its a value
    if (RoseBin_support::DEBUG_MODE())
      cout << " its a value... resolving type: --- " << typeOfOperand << " --- " ;
    // fixme .. temporary fix for DB issue
    if (typeOfOperand=="BYTE") typeOfOperand="WORD";
    if (typeOfOperand=="WORD") typeOfOperand="DWORD";

    if (typeOfOperand=="BYTE") {
        binNode = SageBuilderAsm::makeByteValue(expt->immediate);
    } else 
      if (typeOfOperand=="WORD") {
        binNode = SageBuilderAsm::makeWordValue(expt->immediate);
      } else 
        if (typeOfOperand=="DWORD") {
          binNode = SageBuilderAsm::makeDWordValue(expt->immediate);
        } else
          if (typeOfOperand=="QWORD") {
            binNode = SageBuilderAsm::makeQWordValue(expt->immediate);
          } else 
            if (typeOfOperand=="SFLOAT") {
              binNode = new SgAsmSingleFloatValueExpression();
              isSgAsmSingleFloatValueExpression(binNode)->set_value(expt->immediate);
            } else 
              if (typeOfOperand=="DFLOAT") {
                binNode = SageBuilderAsm::makeQWordValue(expt->immediate);
              } else {
                cerr << "ERROR :: unhandled type of value: " << typeOfOperand << " val: " << 
                  RoseBin_support::ToString(expt->immediate) << endl;
                //              exit(0);
                // creating defualt for now
                binNode = SageBuilderAsm::makeDWordValue(expt->immediate);
              }
    
    if (RoseBin_support::DEBUG_MODE())
      cout <<  typeOfOperand << endl;
    //printExprNode(*expt);
  }
 
  else if (expt->expr_type==1) {
    // register
    if (RoseBin_support::DEBUG_MODE())
      cout << " its a register .... " << endl;

    if (RoseAssemblyLanguage==x86) {
      RegisterDescriptor regDesc;
      string symbol = RoseBin_support::str_to_upper(expt->symbol);
      
      resolveRegisterX86(symbol, &regDesc);
      //binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize);
      binNode = new SgAsmx86RegisterReferenceExpression(regDesc);
      isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc));
    } else if (RoseAssemblyLanguage==arm) {
      RegisterDescriptor regDesc;
      string symbol = RoseBin_support::str_to_upper(expt->symbol);
      
      resolveRegisterX86(symbol, &regDesc);
      //      binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize);
      binNode = new SgAsmArmRegisterReferenceExpression(regDesc);
      // todo : find out types for ARM
    }
  } else {
    cerr << " ERROR ... buildTree ... wrong type " << endl;
    RoseBin_support::printExprNode(*expt);
    exit(0);
  }
  return binNode;
}