Exemplo n.º 1
0
/************************************************************
 * gets the value of the right (bool=true) hand side
 * or left hand side of the instruction
 ***********************************************************/
uint64_t
RoseBin_DataFlowAbstract::getValueOfInstr( SgAsmx86Instruction* inst,
                                           bool rightSide ) {
  // 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
  SgAsmOperandList* opList = inst->get_operandList();
  ROSE_ASSERT(opList);

  uint64_t val = 0xffffffff;
  int counter=0;
  int endCounter=0;
  if (rightSide)
    endCounter=1;

  // 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);
    // skip the iteration if we do not evaluate the correct side
    // counter ==0 (left side) counter==1 (right side)
    if (counter!=endCounter) {
      counter++;
      continue;
    } else
      counter++;

    SgAsmValueExpression* valExpr = isSgAsmValueExpression(expr);
    if (valExpr) {
      val = getValueInExpression(valExpr);
    }
  }
  return val;
}
Exemplo n.º 2
0
/************************************************************
 * checks if an instruction has a RegisterReference on the
 * right (bool) or left side.
 * Return value is meaningless if registerReference return value is false.
 ***********************************************************/
std::pair<X86RegisterClass, int>
RoseBin_DataFlowAbstract::check_isRegister(SgGraphNode* node,
                                           SgAsmx86Instruction* inst,
                                           bool rightSide, bool& memoryReference, bool& registerReference ) {
  // 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
  registerReference = false;
  SgAsmOperandList* opList = inst->get_operandList();
  ROSE_ASSERT(opList);


  SgAsmx86RegisterReferenceExpression* refExpr =NULL;
  std::pair<X86RegisterClass, int>  code = std::make_pair(x86_regclass_gpr, 0); // meaningless
  int counter=0;
  int endCounter=0;
  if (rightSide)
    endCounter=1;

  string operands="";
  // 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);
    // skip the iteration if we do not evaluate the correct side
    // counter ==0 (left side) counter==1 (right side)
    if (counter!=endCounter) {
      counter++;
      continue;
    } else
      counter++;

    SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(expr);
    if (mem) {
      memoryReference = true;
      SgAsmExpression* memOff = mem->get_address();
        if (isSgAsmx86RegisterReferenceExpression(memOff)) {
          SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff);
          code = std::make_pair((X86RegisterClass)memRegRef->get_descriptor().get_major(), memRegRef->get_descriptor().get_minor());
          registerReference = true;
        }
    }
    refExpr = isSgAsmx86RegisterReferenceExpression(expr);
    if (refExpr) {
      code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor());
      registerReference = true;
    }
  }

#if 0
    refExpr = isSgAsmx86RegisterReferenceExpression(expr);
    if (refExpr) {
      // check if it could be a memory reference
      // changed by tps on 16Jan08

      SgAsmExpression* offset = refExpr->get_offset();
      if (isSgAsmMemoryReferenceExpression(offset)) {
        // is a memory reference
        memoryReference = true;
        SgAsmMemoryReferenceExpression* mem = isSgAsmMemoryReferenceExpression(offset);
        SgAsmExpression* memOff = mem->get_address();
        if (isSgAsmx86RegisterReferenceExpression(memOff)) {
          SgAsmx86RegisterReferenceExpression* memRegRef = isSgAsmx86RegisterReferenceExpression(memOff);
          code = memRegRef->get_identifier();
          registerReference = true;
        }
      } else {
        // is a register reference
        code = refExpr->get_identifier();
        registerReference = true;
        //      }
      }
    }
#endif

  return code;
}
Exemplo n.º 3
0
bool
RoseBin_Emulate::evaluateInstruction( SgAsmx86Instruction* binInst, string& operands) {
  SgAsmOperandList* opList = binInst->get_operandList();
  ROSE_ASSERT(opList);
  //string operands = "";
  bool success = true;

  // ***************************************************************
  // handle special cases
  // handle function calls to cpuid and int
  if (binInst->get_kind() == x86_cpuid) {
    operands += " :: specialOp cpuid";
    //clearRegisters();
    rbx = getRandomValue(100); // example return value
    rcx = getRandomValue(100); // example return value
    rdx = getRandomValue(100); // example return value
    return success;
  }
  else if (binInst->get_kind() == x86_int) {
    operands += " :: specialOp Int";
    //clearRegisters();
    getRegister_val(std::make_pair(x86_regclass_gpr, x86_gpr_ax), RoseBin_support::x86_regpos_qword, rax);
    // should get the values from memory!
    string values = "";
    rose_hash::unordered_map <uint64_t, uint64_t>::iterator it = memory.begin();
    for (;it!=memory.end();++it) {
      uint64_t loc = it->first;
      uint64_t val = it->second;
      string loc_s = RoseBin_support::HexToString(loc);
      string val_s = RoseBin_support::HexToString(val);
      values+= "("+loc_s+":"+val_s+")-";
    }

    //uint64_t rbx_v = getMemory(0x1c);
    //uint64_t rcx_v = getMemory(0x20);
    //uint64_t rdx_v = getMemory(0x24);
    if (rax==4) {
      // sys_write
      //string values = "" + RoseBin_support::HexToString(rbx_v);
      //values += "-" + RoseBin_support::HexToString(rcx_v);
      //values += "-" + RoseBin_support::HexToString(rdx_v);
      operands += " :: syswrite : "+values;
    } else {
      success = false;
    }
    return success;
  }
  // handle call to rdtsc
  else if (binInst->get_kind() == x86_rdtsc) {
    // simulate timer function
    operands += " :: specialOp rdtsc";
    rdx = 0x0ULL;
    rax = getRandomValue(10);
    return success;
  }
  // **************************************************************


  int counter=0;
  SgAsmx86RegisterReferenceExpression* refExpr =NULL;
  std::pair<X86RegisterClass, int>  code ;
  RoseBin_support::X86PositionInRegister pos ;

  // iterate through the operands (for x86 = 2 operands)
  SgAsmExpressionPtrList ptrList = opList->get_operands();
  SgAsmMemoryReferenceExpression* memRef = NULL;
  for (SgAsmExpressionPtrList::iterator it=ptrList.begin(); it!=ptrList.end(); ++it) {
    SgAsmExpression* expr = *it;
    ROSE_ASSERT(expr);
    //string type = "DWORD";
    //string result = unparser->resolveOperand(expr,&type);
    if (counter==0) {
      // left hand side *************************************************************
      refExpr = isSgAsmx86RegisterReferenceExpression(expr);

      // check what it could be
      // ******** 1. its a RegisterReferenceExpression on the left side
      if (refExpr) {
        code = std::make_pair((X86RegisterClass)refExpr->get_descriptor().get_major(), refExpr->get_descriptor().get_minor());
        pos = get_position_in_register(refExpr->get_descriptor());
        operands = "\\nleft :: refExpr ";
        //SgAsmExpression* expression = refExpr->get_offset();
        //memRef = isSgAsmMemoryReferenceExpression(expression);
        //if (memRef)
        //  operands += " :: memoryRefExp ";
        operands += "\\n";
      }

      // ******** 2. Its a BitAndByteInstruction
      else  {
        switch (binInst->get_kind()) {
          case x86_sete: {
            // if the instruction is a sete, then we want to check ZF and set the
            // proper register to 1
            if (ZF) {
              uint64_t qw_val=1;
              assignRegister(code, qw_val);
              ZF=false;
            }
            break;
          }
          case x86_dec: {
            uint64_t left = getRegister(code);
            assignRegister(code, --left);
            break;
          }
          default: {
            success = false;
          }
        }
      }

    } else {
      // right hand side ************************************************************
      SgAsmValueExpression* valExp = isSgAsmValueExpression(expr);
      SgAsmx86RegisterReferenceExpression* refExprR = isSgAsmx86RegisterReferenceExpression(expr);
      uint8_t b_val=0xF;
      uint16_t w_val=0xFF;
      uint32_t dw_val=0xFFFF;
      uint64_t qw_val=0xFFFFFFFF;

      // check what it could be
      // ****** 1. valueExpression
      if (valExp) {
        // value expr
        operands += "right :: valExp ";
        RoseBin_support::resolveValue(valExp, false,
                                      b_val,
                                      w_val,
                                      dw_val,
                                      qw_val);
        uint64_t val = 0xFFFFFFFF;
        if (b_val!=0xF)
          val = uint64_t(b_val);
        else if (w_val!=0xFF)
          val = uint64_t(w_val);
        else if (dw_val!=0xFFFF)
          val = uint64_t(dw_val);
        else if (qw_val!=0xFFFFFFFF)
          val = uint64_t(qw_val);

        if (refExpr) {
          switch (binInst->get_kind()) {
            // mov instruction
            case x86_mov: {
              operands += " :: DataTrans :: Mov ";
              assignRegister(code, pos, b_val,
                             w_val, dw_val,
                             qw_val);
              uint64_t addr_value=0;
              getRegister_val(code, RoseBin_support::x86_regpos_qword, addr_value);
              //string str="";
              //string var = createVariable(addr_value, str, type, description, length);
              //string varHex = RoseBin_support::HexToString(addr_value) ;
              //operands += "\\nVariable : " + var + "("+varHex+")";
              break;
            }

            case x86_and: {
              operands += " :: Logical :: And";
              uint64_t reg = getRegister(code);
              operands+=printRegister("reg",reg);
              operands+=printRegister("val",val);
              reg &= val;
              assignRegister(code, reg);
              if (reg==0)
                ZF = true;
              else ZF=false;
              break;
            }

            case x86_add: {
              operands += " :: Arithm :: Add";
              uint64_t left = getRegister(code);
              uint64_t sum = left+val;
              assignRegister(code, sum);
              break;
            }

            default:
              success = false;
          }

        } // refExp
        else { success = false;}
      } // valExp
      else if (refExprR) {
        // ****** 2. referenceExpression
        // the right hand side is also a register or memory location
        std::pair<X86RegisterClass, int>  codeR ;
        RoseBin_support::X86PositionInRegister posR ;
        codeR = std::make_pair((X86RegisterClass)refExprR->get_descriptor().get_major(), refExprR->get_descriptor().get_minor());
        posR = get_position_in_register(refExprR->get_descriptor());

        operands += "right ::  refExpr ";

        switch (binInst->get_kind()) {
          case x86_mov: {
            operands += " :: DataTrans :: Mov";
            if (memRef) {
              operands += " :: MemRef ";
              SgAsmExpression* mem_loc = memRef->get_address();
              string res = unparseExpression(mem_loc);
              uint64_t pos = 0;
              RoseBin_support::from_string<uint64_t>(pos, res, std::hex);
              uint64_t value = getRegister(codeR);
              assignMemory(pos, value);
              operands += "["+res+"] "+" ("+RoseBin_support::HexToString(pos)+":"+RoseBin_support::HexToString(value)+")";
            } else {
              operands += " :: RegRef ";
              // copy value in right register to left register
              getRegister_val(codeR, posR, b_val,
                              w_val, dw_val,
                              qw_val);
              assignRegister(code, pos, b_val,
                             w_val, dw_val,
                             qw_val);
            }
            break;
          } //mov instruction

          case x86_cmp: {
            operands += " :: Arith :: Cmp";
            uint64_t left = getRegister(code);
            uint64_t right = getRegister(codeR);
            if (left==right)
              ZF=true;
            break;
          }

          default: {
            success =false;
          }
        }

      } //refExprR
      else { success =false;}
    }
    counter++;
  }
  operands += "\\n";
  return success;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}