Esempio n. 1
0
bool IA_IAPI::isIPRelativeBranch() const
{
            // These don't exist on IA32...
#if !defined(arch_x86_64)
    return false;
#endif
    Instruction ci = curInsn();

    bool valid;
    Address target;
    boost::tie(valid, target) = getCFT();
    
    if(ci.getCategory() == c_BranchInsn &&
       !valid) {
       Expression::Ptr cft = ci.getControlFlowTarget();
       if(cft->isUsed(thePC[_isrc->getArch()]))
       {
          parsing_printf("\tIP-relative indirect jump to %s at 0x%lx\n",
                         cft->format(ci.getArch()).c_str(), current);
          return true;
       }
    }
    return false;
    
}
Esempio n. 2
0
void IA_x86Details::computeTableAddress()
{
    // Extract displacement from table insn
    Expression::Ptr displacementSrc;
    if(tableInsn.insn->getCategory() == c_BranchInsn)
    {
        Expression::Ptr op = tableInsn.insn->getOperand(0).getValue();
        std::vector<Expression::Ptr> tmp;
        op->getChildren(tmp);
        if(tmp.empty())
        {
            displacementSrc = op;
        }
        else
        {
            displacementSrc = tmp[0];
        }
    }
    else
    {
        parsing_printf("\tcracking table instruction %s\n", tableInsn.insn->format().c_str());
        std::vector<Expression::Ptr> tmp;
        Expression::Ptr op = tableInsn.insn->getOperand(1).getValue();
        if(!op)
        {
            parsing_printf("\ttable insn BAD! (no second operand)\n");
            return;
        }
        if(tableInsn.insn->getOperation().getID() != e_lea)
        {
            op->getChildren(tmp);
            if(tmp.empty())
            {
                parsing_printf("\ttable insn BAD! (not LEA, second operand not a deref)\n");
                return;
            }
            displacementSrc = tmp[0];
        }
        else
        {
            displacementSrc = op;
        }
    }
    
    zeroAllGPRegisters z(tableInsn.addrOfInsn + tableInsn.insn->size());
    displacementSrc->apply(&z);
    
    if(!z.isDefined())
    {
      parsing_printf("\ttable insn: %s, displacement %s, bind of all GPRs FAILED\n",
		     tableInsn.insn->format().c_str(), displacementSrc->format().c_str());
      return;
    }
    else
    {
        tableInsn.addrFromInsn = z.getResult();
    }
    parsing_printf("\ttableInsn.addrFromInsn set to 0x%lx\n",tableInsn.addrFromInsn);
}
Esempio n. 3
0
bool IA_x86Details::isTableInsn(Instruction::Ptr i) 
{
  Expression::Ptr jumpExpr = currentBlock->curInsn()->getControlFlowTarget();
  parsing_printf("jumpExpr for table insn is %s\n", jumpExpr->format().c_str());
  if(i->getOperation().getID() == e_mov && i->readsMemory() && i->isWritten(jumpExpr))
  {
    return true;
  }
  if(i->getOperation().getID() == e_lea && i->isWritten(jumpExpr))
  {
    return true;
  }
  return false;
}
Esempio n. 4
0
std::pair<bool, Address> IA_IAPI::getCFT() const
{
   if(validCFT) return cachedCFT;
    Expression::Ptr callTarget = curInsn().getControlFlowTarget();
	if (!callTarget) return make_pair(false, 0);
       // FIXME: templated bind(),dammit!
    callTarget->bind(thePC[_isrc->getArch()].get(), Result(s64, current));
    parsing_printf("%s[%d]: binding PC %s in %s to 0x%x...", FILE__, __LINE__,
                   thePC[_isrc->getArch()]->format(curInsn().getArch()).c_str(), curInsn().format().c_str(), current);

    Result actualTarget = callTarget->eval();
#if defined(os_vxworks)

    int reloc_target = current;
#if defined(arch_x86)
    ++reloc_target;
#endif

    if (actualTarget.convert<Address>() == reloc_target) {
        // We have a zero offset branch.  Consider relocation information.
        SymtabCodeRegion *scr = dynamic_cast<SymtabCodeRegion *>(_cr);
        SymtabCodeSource *scs = dynamic_cast<SymtabCodeSource *>(_obj->cs());

        if (!scr && scs) {
            set<CodeRegion *> regions;
            assert( scs->findRegions(reloc_target, regions) == 1 );
            scr = dynamic_cast<SymtabCodeRegion *>(*regions.begin());
        }

        SymtabAPI::Symbol *sym = NULL;
        if (scr) {
            std::vector<SymtabAPI::relocationEntry> relocs =
                scr->symRegion()->getRelocations();

            for (unsigned i = 0; i < relocs.size(); ++i) {
                if (relocs[i].rel_addr() == reloc_target) {
                    sym = relocs[i].getDynSym();
                    if (sym && sym->getOffset()) {
                        parsing_printf(" <reloc hit> ");
                        actualTarget = Result(s64, sym->getOffset());
                    }
                    break;
                }
            }
        }

        if (sym && sym->getOffset() == 0) {
            // VxWorks external call.
            // Need some external means to find the target.
            Address found;
            const std::string &sym_name = sym->getMangledName();
            if (wtxFindFunction(sym_name.c_str(), 0x0, found)) {
                parsing_printf(" <wtx search hit> ");
                actualTarget = Result(s64, found);

                // We've effectively found a plt call.  Update linkage table.
                _obj->cs()->linkage()[found] = sym_name;

            } else {
                parsing_printf(" <wtx fail %s> ", sym_name.c_str());
                actualTarget.defined = false;
            }
        }
    }
#endif

    if(actualTarget.defined)
    {
       cachedCFT = std::make_pair(true, actualTarget.convert<Address>());
       parsing_printf("SUCCESS (CFT=0x%x)\n", cachedCFT.second);
    }
    else
    {
       cachedCFT = std::make_pair(false, 0); 
        parsing_printf("FAIL (CFT=0x%x), callTarget exp: %s\n",
                       cachedCFT.second,callTarget->format(curInsn().getArch()).c_str());
    }
    validCFT = true;

    if(isLinkerStub()) {
        parsing_printf("Linker stub detected: Correcting CFT.  (CFT=0x%x)\n",
                       cachedCFT.second);
    }

    return cachedCFT;
}