bool
RoseBin_DataFlowAnalysis::exceptionCall(SgAsmX86Instruction* call) {
  // this function returns true, if the function that is being called is the _malloc function
  // this is good to know, so that the malloc analysis can be performed even if there is no ret

  // (tps - 05/23/08): Since the new disassembler does not know function names, this analysis
  // does not work.
  // todo : as long as there are no function names -- the malloc analysis will not work.
  bool exception=false;
  if (call==NULL)
    return exception;
  if (call->get_kind() != x86_call)
    return exception;
  SgAsmOperandList* opList = call->get_operandList();
  ROSE_ASSERT(opList);
  SgAsmExpressionPtrList ptrList = opList->get_operands();
  // get the first (and only) element
  string comment = call->get_comment();
  if (ptrList.size()!=0) {
    SgAsmExpression* expr = *(ptrList.begin());
    string replace = expr->get_replacement();
    if (replace=="_malloc" || replace=="malloc@plt"
        || comment=="malloc")
      exception=true;
  }
  //  cerr << "Found call --- comment = " << comment << "  exception = " << exception << endl;
  return exception;
}
예제 #2
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;

  }







};
예제 #3
0
파일: 115-syscall-usage.C 프로젝트: 8l/rose
/** Add edges to graph from functions that call system calls to system calls.
 *
 *  The first 1000 vertexes (0 to 999) in the graph is reserved for system calls, which is many more than the actual system
 *  calls in linux.  */
void
add_syscall_edges(DirectedGraph* G, std::vector<SgAsmFunction*>& all_functions)
{
    // Detect all system calls and add an edge from the function to the function to the system call
    for (unsigned int caller_id = 0; caller_id < all_functions.size(); ++caller_id) {
        SgAsmFunction *func = all_functions[caller_id];

        std::vector<SgAsmInstruction*> insns = SageInterface::querySubTree<SgAsmInstruction>(func);

        for (std::vector<SgAsmInstruction*>::iterator inst_it = insns.begin(); inst_it != insns.end(); ++inst_it) {
            SgAsmX86Instruction *insn = isSgAsmX86Instruction(*inst_it);
            if (insn == NULL)
                continue;

            SgAsmBlock *block = SageInterface::getEnclosingNode<SgAsmBlock>(insn);

            // On linux system calls are always interrups and all interrupts are system calls
            if (insn && block && insn->get_kind()==x86_int) {

                const SgAsmExpressionPtrList &opand_list = insn->get_operandList()->get_operands();
                SgAsmExpression *expr = opand_list.size()==1 ? opand_list[0] : NULL;

                //semantically execute the basic block to find out which sytem call was called
                if (expr && expr->variantT()==V_SgAsmIntegerValueExpression &&
                    0x80==isSgAsmIntegerValueExpression(expr)->get_value()) {

                    const SgAsmStatementPtrList &stmts = block->get_statementList();
                    size_t int_n;
                    for (int_n=0; int_n<stmts.size(); int_n++) {
                        if (isSgAsmInstruction(stmts[int_n])==insn)
                            break;
                    }

                    typedef PartialSymbolicSemantics::Policy<PartialSymbolicSemantics::State,
                                                             PartialSymbolicSemantics::ValueType> Policy;
                    typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
                    Policy policy;
                    Semantics semantics(policy);

                    try {
                        semantics.processBlock(stmts, 0, int_n);
                        if (policy.readRegister<32>("eax").is_known()) {
                            int nr = policy.readRegister<32>("eax").known_value();
                            boost::add_edge(caller_id, nr, *G);
                        }
                    } catch (const Semantics::Exception&) {
                    } catch (const Policy::Exception&) {
                    }
                }
            }
        }
    }
}
예제 #4
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);
}
예제 #5
0
/* Helper function for unparseArmExpression(SgAsmExpression*)
 * 
 * If this function is called for an EXPR node that cannot appear at the top of an ARM instruction operand tree then the node
 * might create two strings: the primary expression return value and an additional string returned through the SUFFIX
 * argument. What to do with the additional string depends on layers higher up in the call stack.
 * 
 * The sign will be prepended to the result if EXPR is a value expression of some sort. */
static std::string unparseArmExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
                                        ArmSignForExpressionUnparsing sign, std::string *suffix=NULL)
{
    std::string result, extra;
    if (!isSgAsmValueExpression(expr)) {
        result += unparseArmSign(sign);
    }
    switch (expr->variantT()) {
        case V_SgAsmBinaryMultiply:
            ROSE_ASSERT (isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs()));
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + "*" +
                     StringUtility::numberToString(isSgAsmByteValueExpression(isSgAsmBinaryExpression(expr)->get_rhs()));
            break;
        case V_SgAsmBinaryLsl:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsl " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryLsr:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", lsr " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryAsr:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", asr " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmBinaryRor:
            result = unparseArmExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, arm_sign_none) + ", ror " +
                     unparseArmExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, arm_sign_none);
            break;
        case V_SgAsmUnaryRrx:
            result = unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + ", rrx";
            break;
        case V_SgAsmUnaryArmSpecialRegisterList:
            result += unparseArmExpression(isSgAsmUnaryExpression(expr)->get_operand(), labels, arm_sign_none) + "^";
            break;
        case V_SgAsmExprListExp: {
            SgAsmExprListExp* el = isSgAsmExprListExp(expr);
            const std::vector<SgAsmExpression*>& exprs = el->get_expressions();
            result += "{";
            for (size_t i = 0; i < exprs.size(); ++i) {
                if (i != 0) result += ", ";
                result += unparseArmExpression(exprs[i], labels, arm_sign_none);
            }
            result += "}";
            break;
        }


        case V_SgAsmBinaryAdd: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            break;
        }

        case V_SgAsmBinarySubtract: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            break;
        }

        case V_SgAsmBinaryAddPreupdate: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            extra = "!";
            break;
        }
            
        case V_SgAsmBinarySubtractPreupdate: {
            /* This node cannot appear at the top of an ARM instruction operand tree */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + ", " +
                      unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            extra = "!";
            break;
        }

        case V_SgAsmBinaryAddPostupdate: {
            /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            if (suffix) {
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none);
                extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_plus);
            } else {
                /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */
                result = unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!";
            }
            break;
        }
            
        case V_SgAsmBinarySubtractPostupdate: {
            /* Two styles of syntax depending on whether this is at top-level or inside a memory reference expression. */
            SgAsmBinaryExpression *e = isSgAsmBinaryExpression(expr);
            if (suffix) {
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none);
                extra = ", " + unparseArmExpression(e->get_rhs(), labels, arm_sign_minus);
            } else {
                /* Used by LDM* and STM* instructions outside memory reference expressions. RHS is unused. */
                result += unparseArmExpression(e->get_lhs(), labels, arm_sign_none) + "!";
            }
            break;
        }

        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            SgAsmExpression* addr = mr->get_address();
            switch (addr->variantT()) {
                case V_SgAsmRegisterReferenceExpression:
                case V_SgAsmBinaryAdd:
                case V_SgAsmBinarySubtract:
                case V_SgAsmBinaryAddPreupdate:
                case V_SgAsmBinarySubtractPreupdate:
                case V_SgAsmBinaryAddPostupdate:
                case V_SgAsmBinarySubtractPostupdate:
                    break;
                default: ROSE_ASSERT (!"Bad addressing mode");
            }

            std::string suffix;
            result += "[" + unparseArmExpression(addr, labels, arm_sign_none, &suffix) + "]";
            result += suffix;
            break;
        }

        case V_SgAsmArmRegisterReferenceExpression:
            result += unparseArmRegister(isSgAsmArmRegisterReferenceExpression(expr));
            break;
        case V_SgAsmByteValueExpression:
        case V_SgAsmWordValueExpression:
        case V_SgAsmDoubleWordValueExpression: {
            SgAsmValueExpression *ve = isSgAsmValueExpression(expr);
            assert(ve!=NULL);
            uint64_t v = SageInterface::getAsmConstant(ve);
            result += "#" + unparseArmSign(sign) + StringUtility::numberToString(v);
            if (labels && v!=0) {
                AsmUnparser::LabelMap::const_iterator li=labels->find(v);
                if (li!=labels->end())
                    result += "<" + li->second + ">";
            }
            break;
        }

        default: {
            std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl;
            ROSE_ASSERT (false);
        }
    }

    /* The extra data should be passed back up the call stack so it can be inserted into the ultimate return string. We can't
     * insert it here because the string can't be generated strictly left-to-right. If "suffix" is the null pointer then the
     * caller isn't expecting a suffix and we'll have to just do our best -- the result will not be valid ARM assembly. */
    if (extra.size()>0 && !suffix)
        result = "\"" + result + "\" and \"" + extra + "\"";
    if (suffix)
        *suffix = extra;

    if (expr->get_replacement() != "") {
        result += " <" + expr->get_replacement() + ">";
    }
    return result;
}
예제 #6
0
/* Helper for unparsePowerpcExpression(SgAsmExpression*) */
static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
                                            const RegisterDictionary *registers, bool useHex) {
    std::string result = "";
    if (expr == NULL) return "BOGUS:NULL";
    switch (expr->variantT()) {
        case V_SgAsmBinaryAdd:
            result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
                     unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
            break;
        case V_SgAsmMemoryReferenceExpression: {
            SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
            SgAsmExpression* addr = mr->get_address();
            switch (addr->variantT()) {
                case V_SgAsmBinaryAdd: {
                    SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr);
                    std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false);
                    if (isSgAsmValueExpression(a->get_rhs())) {
                        // Sign-extend from 16 bits
                        SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs());
                        ASSERT_not_null(ve);
                        result = boost::lexical_cast<std::string>(
                                   (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve)));
                        result += "(" + lhs + ")";
                    } else {
                        result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false);
                    }
                    break;
                }
                default:
                    result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")";
                    break;
            }
            break;
        }
        case V_SgAsmDirectRegisterExpression: {
            SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
            SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
            result = unparsePowerpcRegister(insn, rr->get_descriptor(), registers);
            break;
        }
        case V_SgAsmIntegerValueExpression: {
            uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absoluteValue();
            if (useHex) {
                result = StringUtility::intToHex(v);
            } else {
                result = StringUtility::numberToString(v);
            }
            if (expr->get_comment().empty() && labels) {
                AsmUnparser::LabelMap::const_iterator li = labels->find(v);
                if (li!=labels->end())
                    result = StringUtility::appendAsmComment(result, li->second);
            }
            break;
        }
        default: {
            ASSERT_not_reachable("invalid PowerPC expression: " + expr->class_name());
        }
    }
    result = StringUtility::appendAsmComment(result, expr->get_replacement());
    result = StringUtility::appendAsmComment(result, expr->get_comment());
    return result;
}
예제 #7
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;
}
예제 #8
0
/************************************************************
 * checks if an instruction has a RegisterReference on the
 * right (bool) or left side
 ***********************************************************/
int64_t
RoseBin_DataFlowAbstract::check_isRegister(SgGraphNode* node,
                                           SgAsmx86Instruction* inst,
                                           std::pair<X86RegisterClass, int>  codeSearch,
                                           bool rightSide,
                                           vector<std::pair<X86RegisterClass, int> >& regsOfInterest,
                                           bool& cantTrack
                                           ) {
  // bool rightSide specifies
  // true = checking the right side (of instruction operands) for a registerReference
  // false = checking the left side (of instruction operands) for a registerReference
  int64_t res = 0xFFFFFFFF;
  SgAsmOperandList* opList = inst->get_operandList();
  ROSE_ASSERT(opList);

  SgAsmx86RegisterReferenceExpression* refExpr =NULL;
  std::pair<X86RegisterClass, int>  code ;
  //SgAsmx86RegisterReferenceExpression::x86_position_in_register_enum pos ;
  //SgAsmMemoryReferenceExpression* memRef = NULL;
  int counter=0;
  if (rightSide)
    counter =-1;
  else
    counter = 2;

  string operands="";
  bool foundECX = false;
  int64_t newVal = 0xFFFFFFFF;
  // iterate through the operands (for x86 = 2 operands)
  SgAsmExpressionPtrList ptrList = opList->get_operands();
  for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) {
    SgAsmExpression* expr = *it;
    ROSE_ASSERT(expr);
    if (rightSide)
      counter++;
    else
      counter--;
    if (counter==0) {
      // left hand side if rightSide=true *************************************************************
      // right hand side if rightSide=false *************************************************************
      SgAsmValueExpression* valExp = isSgAsmValueExpression(expr);
      refExpr = isSgAsmx86RegisterReferenceExpression(expr);

      // ****** 1. valueExpression
      if (valExp) {
        // value expr
        newVal = getValueInExpression(valExp);
        operands += " <<left :: value " +RoseBin_support::HexToString(newVal)+">>";
      }

      // ****** 2. referenceExpression
      else if (refExpr) {
        // ****** 2. referenceExpression
        // the right hand side is also a register or memory location
        code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor());
        operands += " << left ::  refExpr >> ";


        // we need to track the value of the register in order to find out its value
        vector<std::pair<X86RegisterClass, int> >::iterator it = regsOfInterest.begin();
        for (;it!=regsOfInterest.end();++it) {
          std::pair<X86RegisterClass, int>  codeI = *it;
          if (codeI==codeSearch) {
            newVal = trackValueForRegister(node, codeSearch, cantTrack, refExpr);
            break;
          }
        }


      } else {
        cerr << " unhandled case in checkVariables " << expr->class_name() << endl;
        exit(0);
      }


    } else {
      // right hand side if rightSide=true  ************************************************************
      // left hand side if rightSide=false  ************************************************************
      SgAsmx86RegisterReferenceExpression* refExprR = isSgAsmx86RegisterReferenceExpression(expr);
      if (refExprR) {
          code = std::make_pair((X86RegisterClass)refExprR->get_descriptor().get_major(), refExprR->get_descriptor().get_minor());
        operands += " <<right :: refExpr>> ";
        if (code==codeSearch)
          foundECX=true;
      }
    }
  }
  if (foundECX)
    res = newVal;
  /*
  if (RoseBin_support::DEBUG_MODE())
    cout << "   >> checkRegister : " << RoseBin_support::HexToString(res) <<
      " -- " << operands << "  foundReg: " << RoseBin_support::resBool(foundECX) << endl;
  */
  return res;
}