Beispiel #1
0
void IndirectControlFlowAnalyzer::FindAllThunks() {
    // Enumuerate every block to find thunk
    for (auto bit = reachable.begin(); bit != reachable.end(); ++bit) {
        // We intentional treat a getting PC call as a special case that does not
	// end a basic block. So, we need to check every instruction to find all thunks
        ParseAPI::Block *b = *bit;
	const unsigned char* buf =
            (const unsigned char*)(b->region()->getPtrToInstruction(b->start()));
	if( buf == NULL ) {
	    parsing_printf("%s[%d]: failed to get pointer to instruction by offset\n",FILE__, __LINE__);
	    return;
	}
	InstructionDecoder dec(buf, b->end() - b->start(), b->obj()->cs()->getArch());
	InsnAdapter::IA_IAPI* block = InsnAdapter::IA_IAPI::makePlatformIA_IAPI(b->obj()->cs()->getArch(), dec, b->start(), b->obj() , b->region(), b->obj()->cs(), b);
	Address cur = b->start();
	while (cur < b->end()) {
	    if (block->getInstruction().getCategory() == c_CallInsn && block->isThunk()) {
	        bool valid;
		Address addr;
		boost::tie(valid, addr) = block->getCFT();
		const unsigned char *target = (const unsigned char *) b->region()->getPtrToInstruction(addr);
		InstructionDecoder targetChecker(target, InstructionDecoder::maxInstructionLength, b->obj()->cs()->getArch());
		Instruction thunkFirst = targetChecker.decode();
		set<RegisterAST::Ptr> thunkTargetRegs;
		thunkFirst.getWriteSet(thunkTargetRegs);
		
		for (auto curReg = thunkTargetRegs.begin(); curReg != thunkTargetRegs.end(); ++curReg) {
		    ThunkInfo t;
		    t.reg = (*curReg)->getID();
		    t.value = block->getAddr() + block->getInstruction().size();
		    t.value += ThunkAdjustment(t.value, t.reg, b);
		    t.block = b;
		    thunks.insert(make_pair(block->getAddr(), t));
		    parsing_printf("\tfind thunk at %lx, storing value %lx to %s\n", block->getAddr(), t.value , t.reg.name().c_str());
		}
	    }
	    cur += block->getInstruction().size();
	    if (cur < b->end()) block->advance();
	}
	delete block;
    }
}
Beispiel #2
0
// Find all blocks that reach the block containing the indirect jump
void IndirectControlFlowAnalyzer::GetAllReachableBlock() {
    reachable.clear();
    queue<Block*> q;
    q.push(block);
    while (!q.empty()) {
        ParseAPI::Block *cur = q.front();
	q.pop();
	if (reachable.find(cur) != reachable.end()) continue;
	reachable.insert(cur);
    boost::lock_guard<Block> g(*cur);
	for (auto eit = cur->sources().begin(); eit != cur->sources().end(); ++eit)
	    if ((*eit)->intraproc()) {
	        if ((*eit)->src() == NULL) {
		    fprintf(stderr, "edge type = %d, target block [%lx, %lx)\n", (*eit)->type(), cur->start(), cur->end());
		}
	        q.push((*eit)->src());
	    }
    }

}
Beispiel #3
0
void 
DICFG::insert_functions_and_bbs(const CodeObject::funclist& funcs)
{
	CodeObject::funclist::iterator 	funcs_iter;
	PARSE_API_RET_BLOCKLIST::iterator blocks_iter;
	ParseAPI::Function *fun; 
	ParseAPI::Block *block; 
	ArmsFunction *arms_fun, *cf;
	ArmsBasicBlock *arms_block; 
	
	/* Create objects representing individual functions */  
	for(funcs_iter = funcs.begin(); funcs_iter != funcs.end(); funcs_iter++) {
		fun = *funcs_iter;
		if (find_function((address_t)fun->addr())) continue; 
		arms_fun = new ArmsFunction((address_t)fun->addr(), fun->name(), this);
		store_function(arms_fun); 
	} 

	/* Insert their basic blocks; mark their start and end address, plus set 
	 * all containing functions. */
	for(funcs_iter = funcs.begin(); funcs_iter != funcs.end(); funcs_iter++) {
		fun = *funcs_iter;
		arms_fun = find_function((address_t)fun->addr());

		ParseAPI::Function::blocklist blocks = fun->blocks();
		for(blocks_iter = blocks.begin(); blocks_iter != blocks.end(); blocks_iter++) {
			block = *blocks_iter; 

//			fprintf(stderr, "handling bb 0x%lx\n", block->start());

			/* don't handle shared blocks multiple times */
			if (find_bb((address_t) block->start())) continue; 

			fprintf(stderr, "adding new bb 0x%lx\n", block->start());

			arms_block = new ArmsBasicBlock((address_t) block->start(), (address_t) block->end(),
				(address_t) block->last(), this); 
			store_bb(arms_block); 

			/* add the containing functions */
			std::vector<ParseAPI::Function *> containing_funcs; 
			block->getFuncs(containing_funcs); 
			std::vector<ParseAPI::Function *>::iterator cf_iter = containing_funcs.begin();
			for ( ; cf_iter != containing_funcs.end(); cf_iter++) {
				cf = find_function((address_t)((*cf_iter)->addr()));
				arms_block->add_containing_function(cf);
				cf->add_bb(arms_block);
			} 
		} 
	} 

	/* Mark entry bbs and exit bbs */  
	for(funcs_iter = funcs.begin(); funcs_iter != funcs.end(); funcs_iter++) {
		fun = *funcs_iter;
		arms_fun = find_function((address_t)fun->addr());
		
		Block *entry_block = fun->entry(); 
		assert(entry_block); 
		ArmsBasicBlock *arms_entry_block = find_bb((address_t)entry_block->start());
		arms_entry_block->set_is_entry_block(); 
		arms_fun->add_entry_block(arms_entry_block);

		PARSE_API_RET_BLOCKLIST return_blocks = fun->returnBlocks();
		for(blocks_iter = return_blocks.begin(); blocks_iter != return_blocks.end(); blocks_iter++) {
			ArmsBasicBlock *arms_exit_block = find_bb((address_t)(*blocks_iter)->start());
			arms_exit_block->set_is_exit_block(); 
			arms_fun->add_exit_block(arms_exit_block);
		}   
	}
}