mirror of
https://github.com/geode-sdk/geode.git
synced 2024-12-17 19:32:28 -05:00
191 lines
4.6 KiB
C
191 lines
4.6 KiB
C
|
#ifndef dobby_h
|
||
|
#define dobby_h
|
||
|
|
||
|
// obfuscated interface
|
||
|
#if 0
|
||
|
#define DobbyBuildVersion c343f74888dffad84d9ad08d9c433456
|
||
|
#define DobbyHook c8dc3ffa44f22dbd10ccae213dd8b1f8
|
||
|
#define DobbyInstrument b71e27bca2c362de90c1034f19d839f9
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
void log_set_level(int level);
|
||
|
void log_switch_to_syslog();
|
||
|
void log_switch_to_file(const char *path);
|
||
|
|
||
|
typedef enum {
|
||
|
kMemoryOperationSuccess,
|
||
|
kMemoryOperationError,
|
||
|
kNotSupportAllocateExecutableMemory,
|
||
|
kNotEnough,
|
||
|
kNone
|
||
|
} MemoryOperationError;
|
||
|
|
||
|
#define PLATFORM_INTERFACE_CODE_PATCH_TOOL_H
|
||
|
MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size);
|
||
|
|
||
|
typedef uintptr_t addr_t;
|
||
|
typedef uint32_t addr32_t;
|
||
|
typedef uint64_t addr64_t;
|
||
|
|
||
|
#if defined(__arm64__) || defined(__aarch64__)
|
||
|
|
||
|
#define ARM64_TMP_REG_NDX_0 17
|
||
|
|
||
|
// float register
|
||
|
typedef union _FPReg {
|
||
|
__int128_t q;
|
||
|
struct {
|
||
|
double d1;
|
||
|
double d2;
|
||
|
} d;
|
||
|
struct {
|
||
|
float f1;
|
||
|
float f2;
|
||
|
float f3;
|
||
|
float f4;
|
||
|
} f;
|
||
|
} FPReg;
|
||
|
|
||
|
// register context
|
||
|
typedef struct _RegisterContext {
|
||
|
uint64_t dmmpy_0; // dummy placeholder
|
||
|
uint64_t sp;
|
||
|
|
||
|
uint64_t dmmpy_1; // dummy placeholder
|
||
|
union {
|
||
|
uint64_t x[29];
|
||
|
struct {
|
||
|
uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22,
|
||
|
x23, x24, x25, x26, x27, x28;
|
||
|
} regs;
|
||
|
} general;
|
||
|
|
||
|
uint64_t fp;
|
||
|
uint64_t lr;
|
||
|
|
||
|
union {
|
||
|
FPReg q[32];
|
||
|
struct {
|
||
|
FPReg q0, q1, q2, q3, q4, q5, q6, q7;
|
||
|
// [!!! READ ME !!!]
|
||
|
// for Arm64, can't access q8 - q31, unless you enable full floating-point register pack
|
||
|
FPReg q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29,
|
||
|
q30, q31;
|
||
|
} regs;
|
||
|
} floating;
|
||
|
} RegisterContext;
|
||
|
#elif defined(__arm__)
|
||
|
typedef struct _RegisterContext {
|
||
|
uint32_t dummy_0;
|
||
|
uint32_t dummy_1;
|
||
|
|
||
|
uint32_t dummy_2;
|
||
|
uint32_t sp;
|
||
|
|
||
|
union {
|
||
|
uint32_t r[13];
|
||
|
struct {
|
||
|
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12;
|
||
|
} regs;
|
||
|
} general;
|
||
|
|
||
|
uint32_t lr;
|
||
|
} RegisterContext;
|
||
|
#elif defined(_M_IX86) || defined(__i386__)
|
||
|
typedef struct _RegisterContext {
|
||
|
uint32_t dummy_0;
|
||
|
uint32_t esp;
|
||
|
|
||
|
uint32_t dummy_1;
|
||
|
uint32_t flags;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
uint32_t eax, ebx, ecx, edx, ebp, esp, edi, esi;
|
||
|
} regs;
|
||
|
} general;
|
||
|
|
||
|
} RegisterContext;
|
||
|
#elif defined(_M_X64) || defined(__x86_64__)
|
||
|
typedef struct _RegisterContext {
|
||
|
uint64_t dummy_0;
|
||
|
uint64_t rsp;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
uint64_t rax, rbx, rcx, rdx, rbp, rsp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15;
|
||
|
} regs;
|
||
|
} general;
|
||
|
|
||
|
uint64_t dummy_1;
|
||
|
uint64_t flags;
|
||
|
} RegisterContext;
|
||
|
#endif
|
||
|
|
||
|
#define RT_FAILED -1
|
||
|
#define RT_SUCCESS 0
|
||
|
typedef enum _RetStatus { RS_FAILED = -1, RS_SUCCESS = 0 } RetStatus;
|
||
|
|
||
|
typedef struct _HookEntryInfo {
|
||
|
int hook_id;
|
||
|
union {
|
||
|
void *target_address;
|
||
|
void *function_address;
|
||
|
void *instruction_address;
|
||
|
};
|
||
|
} HookEntryInfo;
|
||
|
|
||
|
// DobbyWrap <==> DobbyInstrument, so use DobbyInstrument instead of DobbyWrap
|
||
|
#if 0
|
||
|
// wrap function with pre_call and post_call
|
||
|
typedef void (*PreCallTy)(RegisterContext *ctx, const HookEntryInfo *info);
|
||
|
typedef void (*PostCallTy)(RegisterContext *ctx, const HookEntryInfo *info);
|
||
|
int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call);
|
||
|
#endif
|
||
|
|
||
|
// return dobby build date
|
||
|
const char *DobbyBuildVersion();
|
||
|
|
||
|
// replace function
|
||
|
int DobbyHook(void *address, void *replace_call, void **origin_call);
|
||
|
|
||
|
// dynamic binary instrument for instruction
|
||
|
// [!!! READ ME !!!]
|
||
|
// for Arm64, can't access q8 - q31, unless you enable full floating-point register pack
|
||
|
typedef void (*DBICallTy)(RegisterContext *ctx, const HookEntryInfo *info);
|
||
|
int DobbyInstrument(void *address, DBICallTy dbi_call);
|
||
|
|
||
|
// destory and restore hook
|
||
|
int DobbyDestroy(void *address);
|
||
|
|
||
|
// iterate symbol table and find symbol
|
||
|
void *DobbySymbolResolver(const char *image_name, const char *symbol_name);
|
||
|
|
||
|
// global offset table
|
||
|
int DobbyGlobalOffsetTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func);
|
||
|
|
||
|
// [!!! READ ME !!!]
|
||
|
// for arm, Arm64, dobby will use b xxx instead of ldr absolute indirect branch
|
||
|
// for x64, dobby always use absolute indirect jump
|
||
|
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__)
|
||
|
void dobby_enable_near_branch_trampoline();
|
||
|
void dobby_disable_near_branch_trampoline();
|
||
|
#endif
|
||
|
|
||
|
// register linker load image callback
|
||
|
typedef void (*linker_load_callback_t)(const char *image_name, void *handle);
|
||
|
void dobby_register_image_load_callback(linker_load_callback_t func);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif
|