-
Notifications
You must be signed in to change notification settings - Fork 14
2.5 Hook: Cave Hook
DK edited this page Sep 20, 2023
·
2 revisions
Branch to hook function in the body of execution from target function.
-
address
: address of the target function -
offsets
: pair containing the {begin, end} offsets of target instruction to patch -
funcInfo
: FUNC_INFO wrapper of hook function -
prolog
: memory patch before detouring to hook function -
epilog
: memory patch after returning from hook function -
flag
: specifies special operation on cave hook
CaveHookHandle AddCaveHook(
std::uintptr_t a_address,
std::pair<std::ptrdiff_t, std::ptrdiff_t> a_offset,
FuncInfo a_funcInfo,
Patch* a_prolog,
Patch* a_epilog,
HookFlag a_flag = HookFlag::kSkipNOP
) noexcept
enum class HookFlag : std::uint32_t
{
kNoFlag,
kSkipNOP, // skip NOPs
kRestoreBeforeProlog, // apply original bytes before prolog
kRestoreAfterProlog, // apply original bytes after prolog
kRestoreBeforeEpilog, // apply original bytes before epilog
kRestoreAfterEpilog, // apply original bytes after epilog
};
using namespace DKUtil::Alias;
// hook function
float __cdecl Hook_MyAwesomeFunc(int a_awesomeInt) {
// do awesome stuff
return static_cast<float>(a_awesomeInt);
}
std::uintptr_t funcAddr = 0x7FF712345678;
// or offset from module base
std::uintptr_t funcAddr = dku::Hook::Module::get().base() + 0x345678;
// mark the begin and the end of target code to patch
// starts at funcAddr + 0x120
// ends at funcAddr + 0x130
auto offset = std::make_pair(0x120, 0x130);
// this is DKUtil::Hook::Patch, you can also use xbyak or raw patch
// move return value to xmm3
DKUtil::Hook::Patch Epilog = {
"\x0F\x10\xD8", // movups xmm3, xmm0
0x3 // size of patch
};
auto _Hook_MAF = DKUtil::Hook::AddCaveHook(funcAddr, offset, FUNC_INFO(Hook_MyAwesomeFunc), nullptr, &Epilog, DKUtil::Hook::HookFlag::kRestoreAfterEpilog);
_Hook_MAF->Enable();
This example under the hood it'll NO-OP all bytes from funcAddr + 0x120 to funcAddr + 0x130, set a branch call to Hook_MyAwesomeFunc, apply custom epilog patch, apply original bytes taken from 0x120 to 0x130(
kRestoreAfterEpilog
), then finally return to 0x130.
When composing arguments for custom cave functions, do follow x64 calling convention