2.5 Hook: Cave Hook - gottyduke/DKUtil GitHub Wiki

API

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

Example

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

⚠️ **GitHub.com Fallback** ⚠️