예제 #1
0
IA_IAPI::allInsns_t::const_iterator IA_x86Details::findTableInsn() 
{
    // Check whether the jump is our table insn!
    Expression::Ptr cft = currentBlock->curInsn()->getControlFlowTarget();
    if(cft)
    {
        std::vector<Expression::Ptr> tmp;
        cft->getChildren(tmp);
        if(tmp.size() == 1)
        {
            Expression::Ptr cftAddr = tmp[0];
            zeroAllGPRegisters z(currentBlock->current);
            cftAddr->apply(&z);
            parsing_printf("\tChecking indirect jump %s for table insn\n", currentBlock->curInsn()->format().c_str());
            if(z.isDefined() && z.getResult())
            {
                parsing_printf("\tAddress in jump\n");
                return currentBlock->curInsnIter;
            }
        }
    }
    IA_IAPI::allInsns_t::const_iterator c = currentBlock->curInsnIter;
    while(!isTableInsn(c->second) && c != currentBlock->allInsns.begin())
    {
        --c;
    }
    if(isTableInsn(c->second))
    {
        return c;
    }
    return currentBlock->allInsns.end();
}
예제 #2
0
bool IA_x86Details::handleAdd(IA_IAPI& block)
{
  parsing_printf("\t found add insn %s without obvious thunk\n",
		 block.getInstruction()->format().c_str());
  // Check table insn and bail if it's not of the mov eax, [eax] form
  // We do this indirectly: if there was already a displacment that we
  // could find in the table insn, we have a "table address"; otherwise, check adds
  if(tableInsn.addrFromInsn != 0) 
  {
    return false;
  }
  
  // Use the add operand as our table base; we're handling tables of the form:
  // <reg = index>
  // add reg, $base
  // mov reg, [reg]
  // jmp *reg
  Expression::Ptr addExpr = block.getInstruction()->getOperand(1).getValue();
  zeroAllGPRegisters z(block.getAddr());
  addExpr->apply(&z);
  thunkInsn.insn = block.getInstruction();
  thunkInsn.addrFromInsn = z.getResult();
  thunkInsn.addrOfInsn = block.getAddr();
  
  parsing_printf("\t setting thunk offset to 0x%lx (EXPERIMENTAL!)\n", thunkInsn.addrFromInsn);
  
  return thunkInsn.addrFromInsn != 0;
}
예제 #3
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);
}
예제 #4
0
void
dyninst_analyze_address_taken(BPatch_addressSpace *handle, DICFG *cfg)
{
	/* XXX: this is the most naive address-taken analysis that can be used by the
         * lbr_analysis_pass. More sophisticated ones can be (and are) plugged in in the pass.
         * This naive solution is provided only for comparison with more sophisticated ones.
	 * 
         * This analysis looks for instruction operands that correspond to known function addresses,
         * and then marks these functions as having their address taken. In particular, we
         * do /not/ look for function pointers stored in (static) memory, or for function
         * pointers that are computed at runtime. 
         */

	SymtabCodeSource *sts;
	CodeObject *co;

	std::vector<BPatch_object*> objs;
	handle->getImage()->getObjects(objs);
	assert(objs.size() > 0);
	const char *bin = objs[0]->pathName().c_str();

	// Create a new binary object 
	sts 	= new SymtabCodeSource((char*)bin);
	co 	= new CodeObject(sts);

	// Parse the binary 
	co->parse(); 

	BPatch_image *image = handle->getImage();
	std::vector<BPatch_module *> *mods = image->getModules();
	std::vector<BPatch_module *>::iterator mods_iter; 
	for (mods_iter = mods->begin(); mods_iter != mods->end(); mods_iter++) {
		std::vector<BPatch_function *> *funcs = (*mods_iter)->getProcedures(false); 
		std::vector<BPatch_function *>::iterator funcs_iter = funcs->begin();
		for(; funcs_iter != funcs->end(); funcs_iter++) {
			co->parse((Address)(*funcs_iter)->getBaseAddr(), true);
			BPatch_flowGraph *fg = (*funcs_iter)->getCFG();
			std::set<BPatch_basicBlock*> blocks;
			fg->getAllBasicBlocks(blocks);
			std::set<BPatch_basicBlock*>::iterator block_iter;
			for (block_iter = blocks.begin(); block_iter != blocks.end(); ++block_iter) {
				BPatch_basicBlock *block = (*block_iter);
				std::vector<Instruction::Ptr> insns;
				block->getInstructions(insns);
				std::vector<Instruction::Ptr>::iterator insn_iter;
				for (insn_iter = insns.begin(); insn_iter != insns.end(); ++insn_iter) {
					Instruction::Ptr ins = *insn_iter;
					std::vector<Operand> ops;
					ins->getOperands(ops);
					std::vector<Operand>::iterator op_iter;
					for (op_iter = ops.begin(); op_iter != ops.end(); ++op_iter) {
						Expression::Ptr expr = (*op_iter).getValue();

						struct OperandAnalyzer : public Dyninst::InstructionAPI::Visitor {
							virtual void visit(BinaryFunction* op) {};
							virtual void visit(Dereference* op) {}
							virtual void visit(Immediate* op) {
								address_t addr;
								ArmsFunction *func;
								switch(op->eval().type) {
								case s32:
									addr = op->eval().val.s32val;
									break;
								case u32:
									addr = op->eval().val.u32val;
									break;
								case s64:
									addr = op->eval().val.s64val;
									break;
								case u64:
									addr = op->eval().val.u64val;
									break;
								default:
									return;
								}
								func = cfg_->find_function(addr);
								if(func) {
									printf("Instruction [%s] references function 0x%jx\n", ins_->format().c_str(), addr);
									func->set_addr_taken();
								}
							}
							virtual void visit(RegisterAST* op) {}
							OperandAnalyzer(DICFG *cfg, Instruction::Ptr ins) {
								cfg_ = cfg;
								ins_ = ins;
							};
							DICFG *cfg_;
							Instruction::Ptr ins_;
						};

						OperandAnalyzer oa(cfg, ins);
						expr->apply(&oa);
					}
				}
			}
		} 
	}
}