跳到正文
本頁目錄

Hook API

作用

Hook API 用於在當前進程中安裝函數 detour。

頭文件

C++
#include <pl/memory/Hook.hpp>

類型

C++
namespace pl::memory {
using FuncPtr = void *;

enum class HookPriority : int {
  Highest = 0,
  High = 100,
  Normal = 200,
  Low = 300,
  Lowest = 400,
};
}

優先級數值越小,hook 鏈中越早執行。

函數

C++
int hook(FuncPtr target, FuncPtr detour, FuncPtr *originalFunc,
         HookPriority priority = HookPriority::Normal);

bool unhook(FuncPtr target, FuncPtr detour);

hook() 成功返回 0,參數無效或安裝失敗返回 -1。originalFunc 接收 detour 中繼續調用鏈所需的函數指針。

RAII 句柄

如果 hook 應在 disable() 或對象析構時自動移除,請使用 pl::memory::HookHandle。

C++
#include <pl/memory/Hook.hpp>

using UpdateFn = void (*)(void *);

class MyMod {
public:
  bool enable();
  bool disable();

private:
  static void updateHook(void *self);

  UpdateFn mOriginalUpdate{};
  pl::memory::HookHandle mUpdateHook;
};

bool MyMod::enable() {
  void *target = /* resolved target address */;
  mUpdateHook = pl::memory::HookHandle(
      target, reinterpret_cast<void *>(&updateHook),
      reinterpret_cast<void **>(&mOriginalUpdate),
      pl::memory::HookPriority::Normal);
  return mUpdateHook.installed();
}

bool MyMod::disable() {
  mUpdateHook.reset();
  return true;
}

常見錯誤

  • target、detour 或 originalFunc 傳入 nullptr。
  • detour 簽名沒有和目標函數完全一致。
  • 在 detour 中直接調用目標地址,導致遞歸。
  • 目標模塊和地址尚不可用時就安裝 hook。