mirror of
https://git.recroomarchive.org/Radium/libradhook.git
synced 2026-08-07 09:10:59 +00:00
initial commit
This commit is contained in:
298
include/radhook/api.h
Normal file
298
include/radhook/api.h
Normal file
@@ -0,0 +1,298 @@
|
||||
#ifndef __LIBRADHOOK_API_H__
|
||||
#define __LIBRADHOOK_API_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef RADHOOK_API
|
||||
# define RADHOOK_API
|
||||
#endif // RADHOOK_API
|
||||
|
||||
enum class RadHookResult : int {
|
||||
Success = 0,
|
||||
AlreadyInstalled,
|
||||
NotInstalled,
|
||||
AlreadyEnabled,
|
||||
AlreadyDisabled,
|
||||
MemoryAllocFailed,
|
||||
MemoryProtectFailed,
|
||||
DisassemblyFailed,
|
||||
InvalidTarget,
|
||||
InvalidDetour,
|
||||
InvalidHandle,
|
||||
TrampolineTooFar,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a human readable name for a status code.
|
||||
*
|
||||
* @param result Status code returned by a RadHook API function.
|
||||
* @return Null-terminated string describing the status code.
|
||||
*/
|
||||
RADHOOK_API
|
||||
const char*
|
||||
RadHookResultToString(
|
||||
RadHookResult result
|
||||
);
|
||||
|
||||
struct RadHookOpaque;
|
||||
using RadHookHandle = RadHookOpaque*;
|
||||
|
||||
/**
|
||||
* @brief Creates and installs a hook.
|
||||
*
|
||||
* Redirects execution from @p target to @p detour and enables the hook
|
||||
* immediately upon successful creation.
|
||||
*
|
||||
* @param target Function or address to hook.
|
||||
* @param detour Replacement function to execute.
|
||||
* @param outHandle Receives the created hook handle on success. Set to
|
||||
* nullptr on failure.
|
||||
*
|
||||
* @return Operation result.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookCreate(
|
||||
void* target,
|
||||
void* detour,
|
||||
RadHookHandle* outHandle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Creates and installs a hook from a function pointer.
|
||||
*
|
||||
* Convenience overload that accepts a typed function pointer for the target.
|
||||
*
|
||||
* @tparam TargetFn Target function pointer type.
|
||||
* @param target Function to hook.
|
||||
* @param detour Replacement function.
|
||||
* @param outHandle Receives the created hook handle on success.
|
||||
*
|
||||
* @return Operation result.
|
||||
*/
|
||||
template <typename TargetFn>
|
||||
requires std::is_function_v<std::remove_pointer_t<TargetFn>>
|
||||
RadHookResult
|
||||
RadHookCreate(
|
||||
TargetFn target,
|
||||
void* detour,
|
||||
RadHookHandle* outHandle
|
||||
) {
|
||||
return RadHookCreate(
|
||||
reinterpret_cast<void*>(target),
|
||||
detour,
|
||||
outHandle
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables an installed hook.
|
||||
*
|
||||
* Re-applies the jump from the target function to its detour.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return RadHookResult::AlreadyEnabled if the hook is already enabled;
|
||||
* otherwise the result of the operation.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookEnable(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Disables an installed hook.
|
||||
*
|
||||
* Restores the original bytes at the target function.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return RadHookResult::AlreadyDisabled if the hook is already disabled;
|
||||
* otherwise the result of the operation.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookDisable(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Destroys a hook.
|
||||
*
|
||||
* Disables the hook if necessary, releases any allocated resources,
|
||||
* and invalidates the handle.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return Operation result.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookDestroy(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Enables every registered hook.
|
||||
*
|
||||
* Hooks that are already enabled are left unchanged.
|
||||
*
|
||||
* @return Operation result.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookEnableAll();
|
||||
|
||||
/**
|
||||
* @brief Disables every registered hook.
|
||||
*
|
||||
* Hooks that are already disabled are left unchanged.
|
||||
*
|
||||
* @return Operation result.
|
||||
*/
|
||||
RADHOOK_API
|
||||
RadHookResult
|
||||
RadHookDisableAll();
|
||||
|
||||
/**
|
||||
* @brief Returns the number of currently registered hooks.
|
||||
*
|
||||
* Destroyed hooks are not included.
|
||||
*
|
||||
* @return Number of registered hooks.
|
||||
*/
|
||||
RADHOOK_API
|
||||
size_t
|
||||
RadHookGetCount();
|
||||
|
||||
/**
|
||||
* @brief Retrieves registered hook handles.
|
||||
*
|
||||
* Copies up to @p maxCount currently registered hook handles into
|
||||
* @p outHandles.
|
||||
*
|
||||
* @param outHandles Destination buffer.
|
||||
* @param maxCount Maximum number of handles to copy.
|
||||
*
|
||||
* @return Number of handles copied.
|
||||
*/
|
||||
RADHOOK_API
|
||||
size_t
|
||||
RadHookGetHandles(
|
||||
RadHookHandle* outHandles,
|
||||
size_t maxCount
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Checks whether a hook handle is valid.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return true if the handle refers to a registered hook; otherwise false.
|
||||
*/
|
||||
RADHOOK_API
|
||||
bool
|
||||
RadHookIsValid(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Checks whether a hook is currently enabled.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return true if the hook is enabled; otherwise false.
|
||||
*/
|
||||
RADHOOK_API
|
||||
bool
|
||||
RadHookIsEnabled(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the hooked target function.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return Pointer to the original target function, or nullptr if the handle
|
||||
* is invalid.
|
||||
*/
|
||||
RADHOOK_API
|
||||
void*
|
||||
RadHookGetTarget(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the detour function.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return Pointer to the detour function, or nullptr if the handle is
|
||||
* invalid.
|
||||
*/
|
||||
RADHOOK_API
|
||||
void*
|
||||
RadHookGetDetour(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the trampoline containing the relocated original code.
|
||||
*
|
||||
* Calling the returned function executes the original implementation while
|
||||
* bypassing the installed hook.
|
||||
*
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return Pointer to the trampoline, or nullptr if unavailable.
|
||||
*/
|
||||
RADHOOK_API
|
||||
void*
|
||||
RadHookGetOriginal(
|
||||
RadHookHandle handle
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Returns the trampoline cast to a function pointer type.
|
||||
*
|
||||
* @tparam FnPtr Desired function pointer type.
|
||||
* @param handle Hook handle.
|
||||
*
|
||||
* @return Trampoline cast to @p FnPtr.
|
||||
*/
|
||||
template <typename FnPtr>
|
||||
FnPtr
|
||||
RadHookGetOriginalAs(
|
||||
RadHookHandle handle
|
||||
) {
|
||||
return reinterpret_cast<FnPtr>(RadHookGetOriginal(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enumerates currently registered hooks.
|
||||
*
|
||||
* Copies up to @p maxCount active hook handles into @p out.
|
||||
* Handles are written in no particular order.
|
||||
*
|
||||
* This function only returns hooks that are currently registered
|
||||
* and not destroyed.
|
||||
*
|
||||
* @param out Destination buffer for hook handles.
|
||||
* @param maxCount Maximum number of handles to copy.
|
||||
*
|
||||
* @return Number of hook handles written into @p out.
|
||||
*/
|
||||
RADHOOK_API
|
||||
size_t
|
||||
RadHookEnumerate(
|
||||
RadHookHandle* out,
|
||||
size_t maxCount
|
||||
);
|
||||
|
||||
#endif // __LIBRADHOOK_API_H__
|
||||
48
include/radhook/radhook.h
Normal file
48
include/radhook/radhook.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __LIBRADHOOK_HPP__
|
||||
#define __LIBRADHOOK_HPP__
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// platform detection
|
||||
#if !defined(RADIUM_PLATFORM_WINDOWS) && !defined(RADIUM_PLATFORM_ANDROID)
|
||||
# if defined(_WIN32) || defined(_WIN64)
|
||||
# define RADIUM_PLATFORM_WINDOWS 1
|
||||
# elif defined(__ANDROID__)
|
||||
# define RADIUM_PLATFORM_ANDROID 1
|
||||
# else
|
||||
# error "radhook: unsupported platform -- define RADIUM_PLATFORM_WINDOWS or RADIUM_PLATFORM_ANDROID"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// architecture detection
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
# define RADHOOK_ARCH_X64 1
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
# define RADHOOK_ARCH_ARM64 1
|
||||
#else
|
||||
# error "radhook: unsupported architecture -- need x86-64 or aarch64"
|
||||
#endif
|
||||
|
||||
// api macros
|
||||
#if defined(_WIN32)
|
||||
# if defined(RADHOOK_BUILD)
|
||||
# define RADHOOK_API __declspec(dllexport)
|
||||
# elif defined(RADHOOK_SHARED)
|
||||
# define RADHOOK_API __declspec(dllimport)
|
||||
# else
|
||||
# define RADHOOK_API
|
||||
# endif
|
||||
#else
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define RADHOOK_API __attribute__((visibility("default")))
|
||||
# else
|
||||
# define RADHOOK_API
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "api.h"
|
||||
|
||||
#endif // __LIBRADHOOK_HPP__
|
||||
Reference in New Issue
Block a user