Exemplo n.º 1
0
CFWidget::CFWidget(InstructionAPI::Instruction::Ptr insn, Address addr)  :
   isCall_(false), 
   isConditional_(false), 
   isIndirect_(false),
   gap_(0),
   insn_(insn),
   addr_(addr),
   origTarget_(0)
{
   
   // HACK to be sure things are parsed...
   insn->format();

   for (Instruction::cftConstIter iter = insn->cft_begin(); iter != insn->cft_end(); ++iter) {
      if (iter->isCall) isCall_ = true;
      if (iter->isIndirect) isIndirect_ = true;
      if (iter->isConditional) isConditional_ = true;
   }

#if 0
   // Old way
   if (insn->getCategory() == c_CallInsn) {
      // Calls have a fallthrough but are not conditional.
      // TODO: conditional calls work how?
      isCall_ = true;
   } else if (insn->allowsFallThrough()) {
      isConditional_ = true;
   }
#endif

   // This whole next section is obsolete, but IAPI's CFT interface doesn't say
   // what a "return" is (aka, they don't include "indirect"). So I'm using it
   // so that things work. 


   // TODO: IAPI is recording all PPC64 instructions as PPC32. However, the
   // registers they use are still PPC64. This is a pain to fix, and therefore
   // I'm working around it here and in Movement-adhoc.C by checking _both_
   // 32- and 64-bit. 

   Architecture fixme = insn_->getArch();
   if (fixme == Arch_ppc32) fixme = Arch_ppc64;

   Expression::Ptr thePC(new RegisterAST(MachRegister::getPC(insn_->getArch())));
   Expression::Ptr thePCFixme(new RegisterAST(MachRegister::getPC(fixme)));

   Expression::Ptr exp = insn_->getControlFlowTarget();

   exp->bind(thePC.get(), Result(u64, addr_));
   exp->bind(thePCFixme.get(), Result(u64, addr_));
   Result res = exp->eval();
   if (!res.defined) {
      if (!isIndirect_) {
         isIndirect_ = true;
      }
   }

}
Exemplo n.º 2
0
bool SymEval::expandInsn(const InstructionAPI::Instruction::Ptr insn,
                         const uint64_t addr,
                         Result_t &res)
{

    SymEvalPolicy policy(res, addr, insn->getArch(), insn);

    SgAsmInstruction *roseInsn;
    switch(insn->getArch()) {
    case Arch_x86:  {
        RoseInsnX86Factory fac;
        roseInsn = fac.convert(insn, addr);

        SymbolicExpansion exp;
        exp.expandX86(roseInsn, policy);
        break;
    }
    case Arch_ppc32: {
        RoseInsnPPCFactory fac;
        roseInsn = fac.convert(insn, addr);

        SymbolicExpansion exp;
        exp.expandPPC(roseInsn, policy);
        break;
    }
    default:
        assert(0 && "Unimplemented symbolic expansion architecture");
        break;
    }

    if (policy.failedTranslate()) {
        cerr << "Warning: failed semantic translation of instruction " << insn->format() << endl;
        return false;
    }
    return true;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}