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; }
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; } }