跳到正文
本頁目錄

Memory & Hook(內存與鉤子)

ll/api/memory/ · 通用

概述

Memory 模塊提供了底層內存操作、帶優先級控制的函數鉤子、簽名掃描和符號解析。它使模組能夠在二進制層面攔截和修改遊戲行為。

頭文件

頭文件說明
ll/api/memory/Hook.h函數鉤子宏和註冊
ll/api/memory/Memory.h內存操作工具
ll/api/memory/Signature.h二進制模式匹配
ll/api/memory/Symbol.h符號名稱解析

核心函數

鉤子註冊

C++
namespace ll::memory {
enum class HookPriority {
    Highest = 0,
    High    = 100,
    Normal  = 200,
    Low     = 300,
    Lowest  = 400,
};

int hook(
    void* target,
    void* detour,
    void** originalFunc,
    HookPriority priority = HookPriority::Normal,
    bool suspendThreads = true
);

bool unhook(void* target, void* detour, bool suspendThreads = true);
}

鉤子宏

C++
// 静态函数钩子
LL_STATIC_HOOK(HookName, HookPriority::Normal, ReturnType, FunctionPointer, ParamTypes...) {
    // 钩子实现
    // 调用原函数: origin(args...)
}

// 实例方法钩子
LL_INSTANCE_HOOK(HookName, ClassName, HookPriority::Normal, ReturnType, &ClassName::MethodName, ParamTypes...) {
    // 钩子实现
    // 调用原函数: origin(args...)
}

// 自动钩子(自动注册)
LL_AUTO_STATIC_HOOK(HookName, ReturnType, FunctionPointer, ParamTypes...) {
    // ...
}

LL_AUTO_INSTANCE_HOOK(HookName, ClassName, ReturnType, &ClassName::MethodName, ParamTypes...) {
    // ...
}

內存工具

C++
namespace ll::memory {
// 使内存可写,执行回调,恢复保护
void modify(void* ptr, size_t len, brstd::function_ref<void()> callback);

// 调用地址处的函数
template <class R = void, class... Args>
R addressCall(void const* address, auto&&... args);

// 调用虚函数
template <class R = void, class... Args>
R virtualCall(void const* self, ptrdiff_t vIndex, auto&&... args);

// 访问偏移处的成员
template <class T>
T& dAccess(void* ptr, ptrdiff_t off);
}

使用方法

基本鉤子

C++
#include "ll/api/memory/Hook.h"
#include "mc/server/ServerInstance.h"

LL_AUTO_STATIC_HOOK(
    ServerStartHook,
    void,
    &ServerInstance::start  // 函数指针
) {
    // 原函数之前的代码
    origin();  // 调用原函数
    // 原函数之后的代码
}

實例方法鉤子

C++
#include "ll/api/memory/Hook.h"
#include "mc/world/actor/player/Player.h"

LL_AUTO_INSTANCE_HOOK(
    PlayerAttackHook,
    Player,
    void,
    &Player::attack,  // 方法指针
    Actor& target
) {
    // 'this' 是 Player 实例
    if (shouldAllowAttack(target)) {
        origin(target);  // 调用原函数
    }
}

帶優先級的鉤子

C++
LL_STATIC_HOOK(
    HighPriorityHook,
    ll::memory::HookPriority::High,
    bool,
    &SomeClass::someFunction  // 函数指针
) {
    // 在 Normal 优先级钩子之前运行
    return origin();
}

內存修改

C++
#include "ll/api/memory/Memory.h"

void patchMemory() {
    int* someValue = getValuePointer();
    
    ll::memory::modify(someValue, sizeof(int), [&] {
        *someValue = 42;  // 修改只读内存
    });
}

虛函數調用

C++
#include "ll/api/memory/Memory.h"

void callVirtual(void* obj) {
    // 调用索引为 5 的虚函数
    auto result = ll::memory::virtualCall<int>(obj, 5, arg1, arg2);
}

平臺說明

  • 使用函數指針(&ClassName::method)而不是符號名稱
  • 鉤子優先級決定執行順序(數字越小越早執行)

相關模塊