Exemple #1
0
bool IA_IAPI::savesFP() const
{
	std::vector<Instruction::Ptr> insns;
	insns.push_back(curInsn());
#if defined(os_windows)
	// Windows functions can start with a noop...
	InstructionDecoder tmp(dec);
	insns.push_back(tmp.decode());
#endif
	for (unsigned i = 0; i < insns.size(); ++i) {
		InstructionAPI::Instruction::Ptr ci = insns[i];
	    if(ci->getOperation().getID() == e_push)
		{
			if (ci->isRead(framePtr[_isrc->getArch()])) {
				return true;
			}
			else return false;
		}
	}	
	return false;
}
Exemple #2
0
bool IA_x86Details::isMovAPSTable(std::vector<std::pair< Address, EdgeTypeEnum > >& outEdges)
{
    /**
    * AMD-64 gcc emits a re-accuring idiom of:
     *         jmpq   *%r8
     *         movaps %xmm7,-0xf(%rax)
     *         movaps %xmm6,-0x1f(%rax)
     *         movaps %xmm5,-0x2f(%rax)
     *         movaps %xmm4,-0x3f(%rax)
     *         movaps %xmm3,-0x4f(%rax)
     *         movaps %xmm2,-0x5f(%rax)
     *         movaps %xmm1,-0x6f(%rax)
     *         movaps %xmm0,-0x7f(%rax)
     *         <other>
     *
     * The jump register is calculated in such a way that it'll be difficult
     * for our analysis to figure it out.  Instead we'll recognize the pattern
     * of the 'movaps'.  Note that the following instruction is also a valid jump
     * target
     **/
    parsing_printf("\tChecking for movaps table at 0x%lx...\n", currentBlock->current);
    std::set<Address> found;
    const unsigned char *bufferBegin =
            (const unsigned char *)currentBlock->_isrc->getPtrToInstruction(currentBlock->current);
    if( bufferBegin == NULL ) {
        parsing_printf("%s[%d]: failed to get pointer to instruction by offset\n",
                       FILE__, __LINE__);
        return false;
    }

    unsigned int size = (currentBlock->_cr->offset() + currentBlock->_cr->length()) - currentBlock->current;
    InstructionDecoder d(bufferBegin, size, currentBlock->_isrc->getArch());
    Address cur = currentBlock->current;
    unsigned last_insn_size = 0;
    InstructionAPI::Instruction::Ptr i = d.decode();
    cur += i->size();
    InstructionAPI::Instruction::Ptr insn;
    while (NULL != (insn = d.decode())) {
        //All insns in sequence are movaps
        parsing_printf("\t\tChecking instruction %s\n", insn->format().c_str());
        if (insn->getOperation().getID() != e_movapd &&
            insn->getOperation().getID() != e_movaps)
        {
            break;
        }
        //All insns are same size
        if (last_insn_size == 0)
            last_insn_size = insn->size();
        else if (last_insn_size != insn->size())
            break;

        found.insert(cur);

        cur += insn->size();
    }
    if (found.size() == 8) {
        found.insert(cur);
        //It's a match
        for (std::set<Address>::iterator i=found.begin(); i != found.end(); i++) {
            outEdges.push_back(std::make_pair(*i, INDIRECT));
        }
        parsing_printf("\tfound\n");
        return true;
    }
    parsing_printf("\tnot found (%d insns)\n", found.size());
    return false;
}
Exemple #3
0
bool IA_powerDetails::scanForAdjustOrBase(IA_IAPI::allInsns_t::const_iterator start,
					  IA_IAPI::allInsns_t::const_iterator end,
					  RegisterAST::Ptr &jumpAddrReg) {
  std::set<RegisterAST::Ptr> scratchRegs;
  std::set<RegisterAST::Ptr> loadRegs;
  loadRegs.insert(jumpAddrReg);
  for (; start != end; --start) {
    InstructionAPI::Instruction::Ptr insn = start->second;
    parsing_printf("\t\t Examining 0x%lx / %s\n",
		   start->first, start->second->format().c_str());

    if ((insn->getOperation().getID() == power_op_ld ||
	 insn->getOperation().getID() == power_op_ldx) &&
	insn->isWritten(jumpAddrReg)) {
      scratchRegs.clear();
      insn->getReadSet(scratchRegs);
      loadRegs.insert(scratchRegs.begin(), scratchRegs.end());
      parsing_printf("Found a load; now have %d load regs\n", loadRegs.size());
    }
    else if(insn->getOperation().getID() == power_op_addi &&
	    !foundAdjustEntry) {
      parsing_printf("Found add immediate (%d load regs)...\n", loadRegs.size());
      scratchRegs.clear();
      insn->getWriteSet(scratchRegs);
      
      bool found = false;
      // This is apparently broken
      for (std::set<RegisterAST::Ptr>::iterator iter = loadRegs.begin(); iter != loadRegs.end(); ++iter) {
	RegisterAST *tmp = (*iter).get();
	RegisterAST *cmp = (*(scratchRegs.begin())).get();
	if (*tmp == *cmp) {
	  found = true;
	  break;
	}
      }
      if (!found) continue;

      parsing_printf("... that adds to a load reg\n");
      foundAdjustEntry = true;
      toc_visitor->clear();
      parsing_printf("... with operand %s\n", insn->getOperand(1).format(insn->getArch(), start->first).c_str());
      insn->getOperand(1).getValue()->apply(toc_visitor.get());
      adjustEntry = toc_visitor->result;
      if (!adjustEntry)
      insn->getOperand(2).getValue()->apply(toc_visitor.get());
      adjustEntry = toc_visitor->result;
    }
    else if((insn->getOperation().getID() == power_op_lwz ||
	     insn->getOperation().getID() == power_op_ld) &&
	    insn->isRead(toc_reg) &&
	    insn->isWritten(jumpAddrReg))
      {
	parsing_printf("\t found TOC load at %s\n", insn->format().c_str());
	toc_visitor->clear();
	insn->getOperand(1).getValue()->apply(toc_visitor.get());
	tableStartAddress = toc_visitor->result;
	break;
      }
  }
  return true;
}
Exemple #4
0
void AbsRegionConverter::convertAll(InstructionAPI::Instruction::Ptr insn,
				    Address addr,
				    ParseAPI::Function *func,
                                    ParseAPI::Block *block,
				    std::vector<AbsRegion> &used,
				    std::vector<AbsRegion> &defined) {
                        
                        if (!usedCache(addr, func, used)) {
    std::set<RegisterAST::Ptr> regsRead;
    insn->getReadSet(regsRead);


    for (std::set<RegisterAST::Ptr>::const_iterator i = regsRead.begin();
	 i != regsRead.end(); ++i) {
      used.push_back(AbsRegionConverter::convert(*i));
    }
    
    if (insn->readsMemory()) {
      std::set<Expression::Ptr> memReads;
      insn->getMemoryReadOperands(memReads);
      for (std::set<Expression::Ptr>::const_iterator r = memReads.begin();
	   r != memReads.end();
	   ++r) {
         used.push_back(AbsRegionConverter::convert(*r, addr, func, block));
      }
    }
  }
  if (!definedCache(addr, func, defined)) {
    // Defined time
    std::set<RegisterAST::Ptr> regsWritten;
    insn->getWriteSet(regsWritten);
    
    for (std::set<RegisterAST::Ptr>::const_iterator i = regsWritten.begin();
	 i != regsWritten.end(); ++i) {
      defined.push_back(AbsRegionConverter::convert(*i));
    }

    // special case for repeat-prefixed instructions on x86
    // may disappear if Dyninst's representation of these instructions changes
    if (insn->getArch() == Arch_x86) {
      prefixEntryID insnPrefix = insn->getOperation().getPrefixID();
      if ( (prefix_rep == insnPrefix) || (prefix_repnz == insnPrefix) ) {
        defined.push_back(AbsRegionConverter::convert(RegisterAST::Ptr(
          new RegisterAST(MachRegister::getPC(Arch_x86)))));
      }
    }
    
    if (insn->writesMemory()) {
      std::set<Expression::Ptr> memWrites;
      insn->getMemoryWriteOperands(memWrites);
      for (std::set<Expression::Ptr>::const_iterator r = memWrites.begin();
	   r != memWrites.end();
	   ++r) {
         defined.push_back(AbsRegionConverter::convert(*r, addr, func, block));
      }
    }
  }

  if (cacheEnabled_) {
    used_cache_[func][addr] = used;
    defined_cache_[func][addr] = defined;
  }
}