예제 #1
0
SgAsmExpressionPtrList&
getOperands(SgAsmInstruction* insn)
{
    SgAsmOperandList* ol = insn->get_operandList();
    SgAsmExpressionPtrList& operands = ol->get_operands();
    return operands;
}
예제 #2
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;
}
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;
}
예제 #4
0
string unparseX86InstructionToHTMLWithAddress(SgAsmX86Instruction* insn) {
  if (insn == NULL) return "BOGUS:NULL";
  string result = "<font color=\"green\">" + htmlEscape(StringUtility::intToHex(insn->get_address())) + "</font>:";
  result += "<font color=\"red\">" + htmlEscape(insn->get_mnemonic());
  switch (insn->get_branchPrediction()) {
    case x86_branch_prediction_none: break;
    case x86_branch_prediction_taken: result += ",pt"; break;
    case x86_branch_prediction_not_taken: result += ",pn"; break;
    default: ROSE_ASSERT (!"Bad branch prediction");
  }
  result += "</font>";
  result += std::string((result.size() >= 7 ? 1 : 7 - result.size()), ' ');
  SgAsmOperandList* opList = insn->get_operandList();
  const SgAsmExpressionPtrList& operands = opList->get_operands();
  for (size_t i = 0; i < operands.size(); ++i) {
    if (i != 0) result += ", ";
    result += "<font color=\"blue\">" + htmlEscape(unparseExpression(operands[i], NULL, NULL)) + "</font>";
  }
  return result;
}
예제 #5
0
SgAsmX86Instruction*
buildX86MultibyteNopInstruction(size_t nBytes) {
    ASSERT_require(nBytes > 0);
    ASSERT_require(nBytes <= 9);

    SgAsmX86Instruction *instruction = new SgAsmX86Instruction(0, "nop", x86_nop,
                                                               x86_insnsize_32, x86_insnsize_32, x86_insnsize_32);

    // Build a simple version of multi-byte nop using repeated prefixes.
    SgUnsignedCharList insnbuf;
    for (size_t i = 1; i < nBytes; i++)
        insnbuf.push_back(0x66);
    insnbuf.push_back(0x90);

    instruction->set_raw_bytes(insnbuf);
    instruction->set_lockPrefix(false);
    instruction->set_repeatPrefix(x86_repeat_none);

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

    return instruction;
}
예제 #6
0
SgAsmInstruction*
SageBuilderAsm::buildMultibyteNopInstruction(int n)
   {
  // DQ (5/1/2010): Support for building multi-byte NOP instructions.
  // this is x86 specific which is OK for now.
  // SgAsmInstruction* instruction = NULL;

     ROSE_ASSERT(n > 0);
     ROSE_ASSERT(n <= 9);

     uint64_t ip                             = 0; /* Virtual address for start of instruction */
     std::string mnemonic                    = "nop";
     X86InstructionKind kind                 = x86_nop;
     X86InstructionSize insnSize             = x86_insnsize_32; /* Default size of instructions, based on architecture; see init() */
     X86InstructionSize effectiveOperandSize = x86_insnsize_32;
     X86InstructionSize effectiveAddressSize = x86_insnsize_32;

     bool lock                               = false;
     X86RepeatPrefix repeatPrefix            = x86_repeat_none;
     bool branchPredictionEnabled            = false;
     X86BranchPrediction branchPrediction    = x86_branch_prediction_none;

  // SgUnsignedCharList insnbuf(0x90);
     SgUnsignedCharList insnbuf;
     size_t insnbufat                        = size_t(n);  /* Index of next byte to be read from or write to insnbuf */

     SgAsmx86Instruction *instruction = NULL;

     instruction = new SgAsmx86Instruction(ip, mnemonic, kind, insnSize, effectiveOperandSize, effectiveAddressSize);
     ROSE_ASSERT(instruction != NULL);

  // Here we are building a simpler version of multi-byte nop using repeated prefixes.
     for (int i = 1; i < n; i++)
        {
          insnbuf.push_back(0x66);
        }

     insnbuf.push_back(0x90);

#if 0
  // This switch will implement proper multi-byte NOPs (not implemented yet).
     switch(n)
        {
          case 1:
             {
            // instruction->set_raw_bytes(SgUnsignedCharList(&(insnbuf[0]), &(insnbuf[0])+insnbufat));
               insnbuf.push_front(0x66);
               break;
             }

       // case 2: instruction = makeInstruction(x86_nop, "nop", modrm); break;

          default:
             {
               printf ("Error: SageBuilderAsm::buildMultibyteNopInstruction(n=%d) not supported \n",n);
               ROSE_ASSERT(false);
             }
        }
#endif

     instruction->set_raw_bytes(SgUnsignedCharList(&(insnbuf[0]), &(insnbuf[0])+insnbufat));
     ROSE_ASSERT(instruction != NULL);

     instruction->set_lockPrefix(lock);
     instruction->set_repeatPrefix(repeatPrefix);

     if (branchPredictionEnabled)
          instruction->set_branchPrediction(branchPrediction);

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

     return instruction;
   }
예제 #7
0
/****************************************************
 * process all instructions in the DB
 * add the instructions to the blocks
 ****************************************************/
void RoseBin_DB_IDAPRO::process_instruction_query(MYSQL* conn, MYSQL_RES* res_set) {
  rememberInstructions.clear();
  // get the functions
  //  char* q = (char*)"SELECT * FROM instructions_1";
  char *q = (char*)"select *,     (select parent_function from basic_blocks_1 where id = i.basic_block_id      and (i.address - parent_function) >= 0     and (i.address - parent_function) =     (select min(i.address - parent_function) from basic_blocks_1 where id = i.basic_block_id       and (i.address - parent_function) >= 0)     ) as i_f from instructions_1 i order by i.address"; 

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

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

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

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

      ROSE_ASSERT(instruction);

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

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


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

        ROSE_ASSERT(instruction->get_parent());

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

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

  } // if (res_set==NULL)
  checkError(conn,res_set);
}
예제 #8
0
void
InitPointerToNull::visit(SgNode* node) {
  if (isSgAsmFunction(node)) {
    memoryWrites.clear();
    memoryRead.clear();
  } else

  if (isSgAsmx86Instruction(node) && isSgAsmx86Instruction(node)->get_kind() == x86_mov) {
    // this is the address of the mov instruction prior to the call
    //rose_addr_t resolveAddr=0;
    SgAsmx86Instruction* inst = isSgAsmx86Instruction(node);
    SgNode* instBlock = NULL;
    if (project) 
      instBlock= isSgAsmBlock(inst->get_parent());
    else //we run IDA, this is different
      instBlock=inst;

    if (instBlock==NULL)
      return;
    SgAsmFunction* instFunc = isSgAsmFunction(instBlock->get_parent());
    if (instFunc==NULL)
      return;

    // we have found a mov instruction
    // we need to check if it is a   mov mem, (value or reg) // assignment of variable // forgot mov mem, mem
    // or we find a                  mov reg, mem // usage of variable
    // make sure a variable is assigned before used
    SgAsmOperandList * ops = inst->get_operandList();
    SgAsmExpressionPtrList& opsList = ops->get_operands();
    SgAsmExpressionPtrList::iterator itOP = opsList.begin();
    SgAsmMemoryReferenceExpression* memL=NULL;
    SgAsmMemoryReferenceExpression* memR=NULL;
    SgAsmRegisterReferenceExpression* regL=NULL;
    SgAsmRegisterReferenceExpression* regR=NULL;
    SgAsmValueExpression* Val = NULL;
    int iteration=0;
    for (;itOP!=opsList.end();++itOP) {
      SgAsmExpression* exp = *itOP;
      ROSE_ASSERT(exp);
      if (iteration==1) {
	// right hand side
	memR = isSgAsmMemoryReferenceExpression(exp);
	regR = isSgAsmRegisterReferenceExpression(exp);
	Val = isSgAsmValueExpression(exp);
      }
      if (iteration==0) {
	// left hand side
	memL = isSgAsmMemoryReferenceExpression(exp);
	regL = isSgAsmRegisterReferenceExpression(exp);
	iteration++;
      }
    } //for
    if ((memL && regR) || (memL && Val) || (memL && memR)) {
      // could be assignment to address
      rose_addr_t addr=BinQSupport::evaluateMemoryExpression(inst,memL);      
      // apparently the reference to memory does not always have to be BP but
      // can also be IP if it is a static variable. How will we handle global variables?
      //bool containsBP = BinQSupport::memoryExpressionContainsRegister(x86_regclass_gpr,x86_gpr_bp, memL);
      //if (containsBP) {
	// this is memory write with offset to BP
	// remember this memory location as a write
	if (debug)
	cerr << "found a memory write (REG) : " << RoseBin_support::HexToString(inst->get_address())<<" "<<unparseInstruction(inst)<<endl;
	memoryWrites.insert(addr);
	//}
    } else if (regL && memR) {
      // could be usage of address
      rose_addr_t addr=BinQSupport::evaluateMemoryExpression(inst,memR);      
      bool containsBP = BinQSupport::memoryExpressionContainsRegister(x86_regclass_gpr,x86_gpr_bp, memR);
      if (containsBP) {
	// this is memory read with offset to BP
	// did we see a write for this? If not, it is not initialized!
	std::set<rose_addr_t>::const_iterator it = memoryWrites.find(addr);
	if (it!=memoryWrites.end()) {
	  // found write, everything is good
	if (debug)
	  cerr << "found a read with matching write : " << RoseBin_support::HexToString(inst->get_address())<<" "<<unparseInstruction(inst)<<endl;
	} else {
	  std::set<rose_addr_t>::const_iterator it2 = memoryRead.find(addr);
	  if (it2!=memoryRead.end()) {
	    // found this case before
	  } else {
	if (debug)
	    cerr << " This variable might not be initialized : " << RoseBin_support::HexToString(inst->get_address())<<" "<< unparseInstruction(inst) << endl;
	    string res = "Possibly uninitialized variable: ";
	    string funcname="";
	    SgAsmBlock* b = isSgAsmBlock(inst->get_parent());
	    SgAsmFunction* func = NULL;
	    if (b)
	      func=isSgAsmFunction(b->get_parent()); 
	    if (func)
	      funcname = func->get_name();
	    res+=" ("+RoseBin_support::HexToString(inst->get_address())+") : "+unparseInstruction(inst)+
	      " <"+inst->get_comment()+">  in function: "+funcname;
	    result[inst]= res;
	    memoryRead.insert(addr);
	  }
	}
      }
    }
  }
}
예제 #9
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;
}
예제 #10
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;
}
예제 #11
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;
}
예제 #12
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;
}