From b648c2e6e3b0a4d38c2c58674df013d61488bbec Mon Sep 17 00:00:00 2001 From: whh8b <whh8b@git.zephyr-software.com> Date: Sat, 2 Apr 2016 16:28:32 +0000 Subject: [PATCH] Add support for retargeting callbacks through the SDK. --- include/plugin_man.h | 1 + include/zipr_impl.h | 2 +- src/plugin_man.cpp | 15 +++++++++++++++ src/zipr.cpp | 39 +++++++++++++++++++++++++++------------ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/plugin_man.h b/include/plugin_man.h index 24a216a40..86c404f7e 100644 --- a/include/plugin_man.h +++ b/include/plugin_man.h @@ -43,6 +43,7 @@ class ZiprPluginManager_t : public ZiprPluginInterface_t virtual bool DoesPluginPlop(libIRDB::Instruction_t*,DLFunctionHandle_t&); virtual bool DoesPluginAddress(const Dollop_t *, const RangeAddress_t &, Range_t &, bool &coalesce, DLFunctionHandle_t &); + virtual bool DoesPluginRetargetCallback(const RangeAddress_t &, const DollopEntry_t *, RangeAddress_t &, DLFunctionHandle_t &) ; virtual bool DoesPluginRetargetPin(const RangeAddress_t &, const Dollop_t *, RangeAddress_t &, DLFunctionHandle_t &) ; private: diff --git a/include/zipr_impl.h b/include/zipr_impl.h index 91d4b0889..7a41705fb 100644 --- a/include/zipr_impl.h +++ b/include/zipr_impl.h @@ -397,7 +397,7 @@ class ZiprImpl_t : public Zipr_t std::map<RangeAddress_t,libIRDB::Instruction_t*> m_InsnAtAddrs; // unpatched callbacks - std::set<std::pair<libIRDB::Instruction_t*,RangeAddress_t> > unpatched_callbacks; + std::set<std::pair<Zipr_SDK::DollopEntry_t*,RangeAddress_t> > unpatched_callbacks; std::map<std::string,RangeAddress_t> callback_addrs; diff --git a/src/plugin_man.cpp b/src/plugin_man.cpp index 58bea1eef..ee5ed1b37 100644 --- a/src/plugin_man.cpp +++ b/src/plugin_man.cpp @@ -111,6 +111,21 @@ bool ZiprPluginManager_t::DoesPluginPlop(Instruction_t *insn, DLFunctionHandle_t return false; } +bool ZiprPluginManager_t::DoesPluginRetargetCallback(const RangeAddress_t &callback_addr, const DollopEntry_t *callback_entry, RangeAddress_t &target_address, DLFunctionHandle_t &patcher) +{ + DLFunctionHandleSet_t::iterator it=m_handleList.begin(); + for(m_handleList.begin();it!=m_handleList.end();++it) + { + ZiprPluginInterface_t* zpi=(ZiprPluginInterface_t*)*it; + if(Must==zpi->RetargetCallback(callback_addr,callback_entry,target_address)) + { + patcher = zpi; + return true; + } + } + return false; +} + bool ZiprPluginManager_t::DoesPluginRetargetPin(const RangeAddress_t &patch_addr, const Dollop_t *target_dollop, RangeAddress_t &target_address, DLFunctionHandle_t &patcher) { DLFunctionHandleSet_t::iterator it=m_handleList.begin(); diff --git a/src/zipr.cpp b/src/zipr.cpp index 38a1fae40..b039f2476 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -1413,7 +1413,7 @@ void ZiprImpl_t::PlaceDollops() continue; minimum_valid_req_size = std::min( - _DetermineWorstCaseInsnSize(to_place-> front()-> Instruction()), + _DetermineWorstCaseInsnSize(to_place->front()->Instruction()), Utils::DetermineWorstCaseDollopSizeInclFallthrough(to_place)); /* * Ask the plugin manager if there are any plugins @@ -1535,7 +1535,7 @@ void ZiprImpl_t::PlaceDollops() last_de_fits = (std::next(dit,1)==dit_end) /* last */ && (placement.GetEnd()>=(cur_addr+ /* fits */ _DetermineWorstCaseInsnSize(dollop_entry->Instruction(), - to_place->FallthroughDollop() != NULL)) + to_place->FallthroughDollop()!=NULL)) /* with or without fallthrough */ ); @@ -2267,7 +2267,7 @@ RangeAddress_t ZiprImpl_t::PlopDollopEntryWithCallback( { char bytes[]={(char)0xe8,(char)0,(char)0,(char)0,(char)0}; // call rel32 memory_space.PlopBytes(at, bytes, sizeof(bytes)); - unpatched_callbacks.insert(pair<Instruction_t*,RangeAddress_t>(insn,at)); + unpatched_callbacks.insert(pair<DollopEntry_t*,RangeAddress_t>(entry,at)); at+=sizeof(bytes); } @@ -2860,24 +2860,39 @@ RangeAddress_t ZiprImpl_t::FindCallbackAddress(RangeAddress_t end_of_new_space, void ZiprImpl_t::UpdateCallbacks() { - // first byte of this range is the last used byte. - RangeSet_t::iterator it=memory_space.FindFreeRange((RangeAddress_t) -1); - assert(memory_space.IsValidRange(it)); + // first byte of this range is the last used byte. + RangeSet_t::iterator range_it=memory_space.FindFreeRange((RangeAddress_t) -1); + assert(memory_space.IsValidRange(range_it)); - RangeAddress_t end_of_new_space=it->GetStart(); + RangeAddress_t end_of_new_space=range_it->GetStart(); RangeAddress_t start_addr=GetCallbackStartAddr(); - for( std::set<std::pair<libIRDB::Instruction_t*,RangeAddress_t> >::iterator it=unpatched_callbacks.begin(); - it!=unpatched_callbacks.end(); - ++it + set<std::pair<DollopEntry_t*,RangeAddress_t> >::iterator it, it_end; + + for(it=unpatched_callbacks.begin(), it_end=unpatched_callbacks.end(); + it!=it_end; + it++ ) { - Instruction_t *insn=it->first; + DollopEntry_t *entry=it->first; + Instruction_t *insn = entry->Instruction(); RangeAddress_t at=it->second; RangeAddress_t to=FindCallbackAddress(end_of_new_space,start_addr,insn->GetCallback()); + DLFunctionHandle_t patcher = NULL; + + if (plugman.DoesPluginRetargetCallback(at, entry, to, patcher)) + { + if (m_verbose) + { + cout << "Patching retargeted callback at " << std::hex << at << " to " + << patcher->ToString() << "-assigned address: " + << std::hex << to << endl; + } + } + if(to) { - cout<<"Patching callback "<< insn->GetCallback()<<"at "<<std::hex<<at<<" to jump to "<<to<<endl; + cout<<"Patching callback "<< insn->GetCallback()<<" at "<<std::hex<<at<<" to jump to "<<to<<endl; PatchCall(at,to); } else -- GitLab