예제 #1
0
파일: PStatistics.C 프로젝트: Root-nix/rose
 void visit(SgNode *node) {
     SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(node);
     if (rre) {
         size_t nbits = rre->get_descriptor().get_nbits();
         double v = log(nbits) / M_LN2;
         sum += do_variance ? (v-mean)*(v-mean) : v;
         ++n;
     }
 }
예제 #2
0
// see base class
bool
SgAsmMipsInstruction::is_function_return(const std::vector<SgAsmInstruction*> &insns)
{
    if (insns.empty())
        return false;
    SgAsmMipsInstruction *last = isSgAsmMipsInstruction(insns.back());
    if (!last)
        return false;
    if (last->get_kind()!=mips_jr)
        return false;
    const SgAsmExpressionPtrList &args = last->get_operandList()->get_operands();
    if (args.size()<1)
        return false;
    SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(args[0]);
    if (!rre)
        return false;
    if (rre->get_descriptor().get_major()!=mips_regclass_gpr || rre->get_descriptor().get_minor()!=31)
        return false;
    return true; // this is a "JR ra" instruction.
}
예제 #3
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;
         }
     }    
 }
예제 #4
0
void AST_BIN_Traversal::visit(SgNode* n) {
    if (n) {
      nrOfInstructions++;
      std::string name = "";
      if (isSgAsmInstruction(n))
        name = unparseInstruction(isSgAsmInstruction(n));
      SgNode* parent = n->get_parent();
      // node
      std::string add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=yellow,fontname=\"7x13bold\",fontcolor=black,style=filled";
      if (isSgAsmFunction(n)) { 
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=purple,fontname=\"7x13bold\",fontcolor=black,style=filled";
        name = isSgAsmFunction(n)->get_name();
      }
      if (isSgAsmX86Instruction(n) && isSgAsmX86Instruction(n)->get_kind() == x86_call)
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=red,fontname=\"7x13bold\",fontcolor=black,style=filled";
      if (isSgAsmValueExpression(n))
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=lightgreen,fontname=\"7x13bold\",fontcolor=black,style=filled";
      if (isSgAsmMemoryReferenceExpression(n))
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=lightblue,fontname=\"7x13bold\",fontcolor=black,style=filled";
      if (isSgAsmBinaryExpression(n))
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=orange,fontname=\"7x13bold\",fontcolor=black,style=filled";
      if (isSgAsmRegisterReferenceExpression(n)) {
        SgAsmRegisterReferenceExpression* rr = isSgAsmRegisterReferenceExpression(n);
        std::string exprName = unparseX86Register(rr->get_descriptor(), NULL);
        name += " "+exprName;
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=green,fontname=\"7x13bold\",fontcolor=black,style=filled";
      }
      if (isSgAsmOperandList(n))
        add = ",shape=ellipse,regular=0, sides=5,peripheries=1,color=\"Black\",fillcolor=white,fontname=\"7x13bold\",fontcolor=black,style=filled";
      myfile << "\"" << n << "\"[label=\"" << name << "\\n" << n->class_name() << "\"" << add << " ];\n"; 
      if (parent) {
        // edge
        myfile << "\"" << parent << "\" -> \"" << n << "\" [label=\"" << n->class_name() << "\" ];\n"; 
      }
    }
}
예제 #5
0
/** Return control flow successors. See base class for full documentation. */
BinaryAnalysis::Disassembler::AddressSet
SgAsmArmInstruction::getSuccessors(bool *complete) {
    BinaryAnalysis::Disassembler::AddressSet retval;
    const std::vector<SgAsmExpression*> &exprs = get_operandList()->get_operands();
    *complete = true; /*assume retval is the complete set of successors for now*/

    switch (get_kind()) {
        case arm_b:
        case arm_bl:
        case arm_blx:
        case arm_bx: {
            /* Branch target */
            ROSE_ASSERT(exprs.size()==1);
            SgAsmExpression *dest = exprs[0];
            if (isSgAsmValueExpression(dest)) {
                rose_addr_t target_va = SageInterface::getAsmConstant(isSgAsmValueExpression(dest));
                retval.insert(target_va);
            } else {
                /* Could also be a register reference expression, but we don't know the successor in that case. */
                *complete = false;
            }
            
            /* Fall-through address */
            if (get_condition()!=arm_cond_al)
                retval.insert(get_address()+4);
            break;
        }

        case arm_bxj: {
            /* First argument is the register that holds the next instruction pointer value to use in the case that Jazelle is
             * not available. We only know the successor if the register is the instruction pointer, in which case the
             * successor is the fall-through address. */
            ROSE_ASSERT(exprs.size()==1);
            SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(exprs[0]);
            ROSE_ASSERT(rre);
            if (rre->get_descriptor().get_major()==arm_regclass_gpr && rre->get_descriptor().get_minor()==15) {
                retval.insert(get_address()+4);
            } else {
                *complete = false;
            }
            break;
        }
            
        case arm_cmn:
        case arm_cmp:
        case arm_teq:
        case arm_tst:
            /* Comparison and test instructions don't ever affect the instruction pointer; they only fall through */
            retval.insert(get_address()+4);
            break;

        case arm_bkpt:
        case arm_swi:
        case arm_undefined:
        case arm_unknown_instruction:
            /* No known successors for interrupt-generating instructions */
            break;

        default:
            if (!modifies_ip(this) || get_condition()!=arm_cond_al) {
                retval.insert(get_address()+4);
            } else {
                *complete = false;
            }
            break;
    }
    return retval;
}
예제 #6
0
/* Returns true if the instruction modifies the instruction pointer (r15). */
static bool modifies_ip(SgAsmArmInstruction *insn) 
{
    switch (insn->get_kind()) {

        /* Branch instructions */
        case arm_b:
        case arm_bl:
        case arm_blx:
        case arm_bx:
        case arm_bxj:
            return true;

        /* Comparison instructions */
        case arm_cmn:
        case arm_cmp:
        case arm_teq:
        case arm_tst:
            return false;

        /* Load multiple registers instructions. Second argument is the set of registers to load.  If the instruction
         * pointer (r15) can be one of them. */
        case arm_ldm:
        case arm_ldmda:
        case arm_ldmdb:
        case arm_ldmia:
        case arm_ldmib: {
            const std::vector<SgAsmExpression*> &exprs = insn->get_operandList()->get_operands();
            ROSE_ASSERT(exprs.size()>=2);
            SgAsmExprListExp *elist = isSgAsmExprListExp(exprs[1]);
            if (!elist) {
                SgAsmUnaryArmSpecialRegisterList *rlist = isSgAsmUnaryArmSpecialRegisterList(exprs[1]);
                ROSE_ASSERT(rlist);
                elist = isSgAsmExprListExp(rlist->get_operand());
                ROSE_ASSERT(elist);
            }
            for (size_t i=0; i<elist->get_expressions().size(); i++) {
                SgAsmRegisterReferenceExpression *reg = isSgAsmRegisterReferenceExpression(elist->get_expressions()[i]);
                ROSE_ASSERT(reg);
                if (reg->get_descriptor().get_major()==arm_regclass_gpr && reg->get_descriptor().get_minor()==15) {
                    return true;
                }
            }
            return false;
        }

        /* Interrupt-causing instructions */
        case arm_bkpt:
        case arm_swi:
        case arm_undefined:
            return true;

        /* Other instructions modify the instruction pointer if it's the first (destination) argument. */
        default: {
            const std::vector<SgAsmExpression*> &exprs = insn->get_operandList()->get_operands();
            if (exprs.size()>=1) {
                SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(exprs[0]);
                if (rre &&
                    rre->get_descriptor().get_major()==arm_regclass_gpr && rre->get_descriptor().get_minor()==15) {
                    return true;
                }
            }
        }
    }
    return false;
}
예제 #7
0
// Constructor
DataMemberInitializationAttribute::DataMemberInitializationAttribute ( SgAsmInstruction* instruction, SgProject* p )
   {
     ROSE_ASSERT(instruction != NULL);
     printf ("Building a DataMemberInitializationAttribute object for instruction = %s \n",unparseInstructionWithAddress(instruction).c_str());

  // Identify the offset and if this is a stack reference or a global reference.
     SgAsmMemoryReferenceExpression* memoryReferenceExpression = isSgAsmMemoryReferenceExpression(instruction->get_operandList()->get_operands()[0]);
     ROSE_ASSERT(memoryReferenceExpression != NULL);

     SgAsmRegisterReferenceExpression* segmentRegister = isSgAsmRegisterReferenceExpression(memoryReferenceExpression->get_segment());
     ROSE_ASSERT(segmentRegister != NULL);

#ifdef USE_NEW_ISA_INDEPENDENT_REGISTER_HANDLING
  // This is a data member
     isStackVariable  = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ss);

  // This is to test if there is another register being referenced.
     bool isGlobalVariable = (segmentRegister->get_register_number() == SgAsmRegisterReferenceExpression::e_ds);

  // This should be either a stack or global variable (no other allowed).
     ROSE_ASSERT(isStackVariable == true  || isGlobalVariable == true);
     ROSE_ASSERT(isStackVariable == false || isGlobalVariable == false);

     SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(memoryReferenceExpression->get_address());
     if (binaryAdd != NULL)
        {
       // Case of a non-zero offset into the global scope or the stack frame. 
          ROSE_ASSERT(binaryAdd->get_rhs() != NULL);
          SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(binaryAdd->get_rhs());
          ROSE_ASSERT(offsetExpression != NULL);
          offset = get_value(offsetExpression);
        }
       else
        {
       // Case of zero offset from stack frame (first variable in the stack) 
       // or a global variable with immediate address.
          offset = 0;
          if (isGlobalVariable == true)
             {
             // Handle the case of a global variable.
                ROSE_ASSERT(memoryReferenceExpression != NULL);

                SgAsmValueExpression* offsetExpression = isSgAsmValueExpression(memoryReferenceExpression->get_address());
                if (offsetExpression != NULL)
                   {
                     offset = get_value(offsetExpression);
                   }

#if 0
             // ... finish me ...
                printf ("... finish me ... offset = %p \n",(void*)offset);
                ROSE_ASSERT(false);
#else
                printf ("isGlobalVariable == true: offset = %p \n",(void*)offset);
#endif
             }
        }

     SgAsmValueExpression* valueExpression = isSgAsmValueExpression(instruction->get_operandList()->get_operands()[1]);
     ROSE_ASSERT(valueExpression != NULL);

     value = get_value(valueExpression);

     type = valueExpression->get_type();
     ROSE_ASSERT(type != NULL);

     printf ("   isStackVariable  = %s \n",isStackVariable ? "true" : "false");
     printf ("   isGlobalVariable = %s \n",isGlobalVariable ? "true" : "false");
     printf ("   offset           = %zu \n",offset);
     printf ("   value            = %zu = %p \n",value,(void*)value);
     printf ("   type             = %p = %s \n",type,type->class_name().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);
#endif

#if 0
     printf ("Exiting as a test... \n");
     ROSE_ASSERT(false);
#endif
   }
예제 #8
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;
}