jp9000 a6aa2f9204 win-capture: Add 64bit bounce to func_hook
When hooking 64bit functions, sometimes the offset between the function
being hooked and the hook itself can be large enough to where it
requires a 64bit offset to be used.  However, because a 64bit jump
requires overwriting so many code instructions in the function, it can
sometimes overwrite code in to an adjacent function, thereby causing a
crash.

The 64bit hook bounce (created by R1CH) is designed to prevent using
very long jumps in the target by creating executable memory within a
32bit offset of that target, and then writing it with the 64bit long
jump instruction instead.  Then in the target function, it will jump to
that memory instead, thus forcing the actual hooked function to use a
32bit hook instead of a 64bit hook, and using at most 5 bytes for the
actual hook, preventing any likelihood of it overwriting an adjacent
function.
2015-07-03 12:17:25 -07:00

55 lines
1.2 KiB
C

#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#else
#if defined(_MSC_VER) && !defined(inline)
#define inline __inline
#endif
#endif
enum hook_type {
HOOKTYPE_FORWARD_OVERWRITE,
HOOKTYPE_FORWARD_CHAIN,
HOOKTYPE_REVERSE_CHAIN
};
struct func_hook {
void *call_addr;
uintptr_t func_addr; /* function being hooked to */
uintptr_t hook_addr; /* hook function itself */
void *bounce_addr;
const char *name;
enum hook_type type;
bool is_64bit_jump;
bool hooked;
bool started;
bool attempted_bounce;
uint8_t unhook_data[14];
uint8_t rehook_data[14];
};
extern void hook_init(struct func_hook *hook,
void *func_addr, void *hook_addr, const char *name);
extern void hook_start(struct func_hook *hook);
extern void do_hook(struct func_hook *hook, bool force);
extern void unhook(struct func_hook *hook);
static inline void rehook(struct func_hook *hook)
{
do_hook(hook, false);
}
static inline void force_rehook(struct func_hook *hook)
{
do_hook(hook, true);
}
#ifdef __cplusplus
}
#endif