예제 #1
0
파일: CAinst.cpp 프로젝트: sirmc/XnRmor
bool overwriteInstruction(PatchBlock *block, uint64_t addr, uint8_t* val, size_t nbytes)
{
	ParseAPI::Block *b = block->block();
	ParseAPI::SymtabCodeRegion *r = dynamic_cast<ParseAPI::SymtabCodeRegion*>(b->region());
	if (r == NULL) return false;
	Offset region_off = (Offset)r->getPtrToInstruction(addr) - (Offset)r->symRegion()->getPtrToRawData();
	bool success;
	success = r->symRegion()->patchData(region_off++, (void*)val, nbytes);
	return success;
}
예제 #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);
	for (auto eit = cur->sources().begin(); eit != cur->sources().end(); ++eit)
	    if ((*eit)->intraproc()) 
	        q.push((*eit)->src());
    }

}
예제 #3
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());
	    }
    }

}
예제 #4
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->obj()->cs()->getPtrToInstruction(b->start()));
	if( buf == NULL ) {
	    parsing_printf("%s[%d]: failed to get pointer to instruction by offset\n",FILE__, __LINE__);
	    return;
	}
	parsing_printf("Looking for thunk in block [%lx,%lx).", b->start(), b->end());
	InstructionDecoder dec(buf, b->end() - b->start(), b->obj()->cs()->getArch());
	InsnAdapter::IA_IAPI block(dec, b->start(), b->obj() , b->region(), b->obj()->cs(), b);
	while (block.getAddr() < 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->obj()->cs()->getPtrToInstruction(addr);
		InstructionDecoder targetChecker(target, InstructionDecoder::maxInstructionLength, b->obj()->cs()->getArch());
		Instruction::Ptr 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());
		}
	    }
	    block.advance();
	}
    }
}
예제 #5
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);
		}   
	}
}