prefix platform specific functions clearly
This commit is contained in:
parent
db603acded
commit
848e8cc183
3 changed files with 65 additions and 63 deletions
|
|
@ -53,17 +53,17 @@ static_assert(sizeof(detour_trampoline)== 192);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DETOUR_SIZE_OF_JMP = 12
|
DETOUR_PLATFORM_SIZE_OF_JMP = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t detour_arm64_opcode_t;
|
typedef uint32_t detour_arm64_opcode_t;
|
||||||
|
|
||||||
static inline detour_arm64_opcode_t fetch_opcode(const uint8_t* code)
|
static inline detour_arm64_opcode_t detour_arm64_fetch_opcode(const uint8_t* code)
|
||||||
{
|
{
|
||||||
return *(detour_arm64_opcode_t*)code;
|
return *(detour_arm64_opcode_t*)code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void write_opcode(uint8_t** int_out_code, const detour_arm64_opcode_t opcode)
|
static inline void detour_arm64_write_opcode(uint8_t** int_out_code, const detour_arm64_opcode_t opcode)
|
||||||
{
|
{
|
||||||
uint8_t* code = *int_out_code;
|
uint8_t* code = *int_out_code;
|
||||||
*(detour_arm64_opcode_t*)code = opcode;
|
*(detour_arm64_opcode_t*)code = opcode;
|
||||||
|
|
@ -108,7 +108,7 @@ union detour_arm64_indirect_imm
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_gen_jmp_indirect(uint8_t* code, const uint64_t* jump_val)
|
static inline uint8_t* detour_arm64_gen_jmp_indirect(uint8_t* code, const uint64_t* jump_val)
|
||||||
{
|
{
|
||||||
// adrp x17, [jmpval]
|
// adrp x17, [jmpval]
|
||||||
// ldr x17, [x17, jmpval]
|
// ldr x17, [x17, jmpval]
|
||||||
|
|
@ -142,7 +142,7 @@ static inline uint8_t* internal_detour_gen_jmp_indirect(uint8_t* code, const uin
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_gen_jmp_immediate(uint8_t* code, uint8_t** inout_code_limit, uint8_t* jmp_val)
|
static inline uint8_t* detour_platform_gen_jmp_immediate(uint8_t* code, uint8_t** inout_code_limit, uint8_t* jmp_val)
|
||||||
{
|
{
|
||||||
*inout_code_limit = *inout_code_limit - 8;
|
*inout_code_limit = *inout_code_limit - 8;
|
||||||
uint8_t* literal = *inout_code_limit;
|
uint8_t* literal = *inout_code_limit;
|
||||||
|
|
@ -150,21 +150,21 @@ static inline uint8_t* internal_detour_gen_jmp_immediate(uint8_t* code, uint8_t*
|
||||||
*(uint8_t**)literal = jmp_val;
|
*(uint8_t**)literal = jmp_val;
|
||||||
const int32_t delta = (int32_t)(literal - code);
|
const int32_t delta = (int32_t)(literal - code);
|
||||||
|
|
||||||
write_opcode(&code, 0x58000011 | ((delta / 4) << 5)); // LDR X17,[PC+n]
|
detour_arm64_write_opcode(&code, 0x58000011 | ((delta / 4) << 5)); // LDR X17,[PC+n]
|
||||||
write_opcode(&code, 0xd61f0000 | (17 << 5)); // BR X17
|
detour_arm64_write_opcode(&code, 0xd61f0000 | (17 << 5)); // BR X17
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_gen_brk(uint8_t* code, const uint8_t* limit)
|
static inline uint8_t* detour_platform_gen_brk(uint8_t* code, const uint8_t* limit)
|
||||||
{
|
{
|
||||||
while (code < limit) {
|
while (code < limit) {
|
||||||
write_opcode(&code, 0xd4100000 | (0xf000 << 5));
|
detour_arm64_write_opcode(&code, 0xd4100000 | (0xf000 << 5));
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void internal_detour_find_jmp_bounds(uint8_t* code, detour_trampoline** out_lower,
|
static inline void detour_platform_find_jmp_bounds(uint8_t* code, detour_trampoline** out_lower,
|
||||||
detour_trampoline** out_upper)
|
detour_trampoline** out_upper)
|
||||||
{
|
{
|
||||||
// The encoding used by detour_gen_jmp_indirect actually enables a
|
// The encoding used by detour_gen_jmp_indirect actually enables a
|
||||||
|
|
@ -179,12 +179,12 @@ static inline void internal_detour_find_jmp_bounds(uint8_t* code, detour_trampol
|
||||||
*out_upper = (detour_trampoline*)hi;
|
*out_upper = (detour_trampoline*)hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool internal_detour_is_code_os_patched(const uint8_t* code)
|
static inline bool detour_arm64_is_code_os_patched(const uint8_t* code)
|
||||||
{
|
{
|
||||||
// Identify whether the provided code pointer is a OS patch jump.
|
// Identify whether the provided code pointer is a OS patch jump.
|
||||||
// We can do this by checking if a branch (b <imm26>) is present, and if so,
|
// We can do this by checking if a branch (b <imm26>) is present, and if so,
|
||||||
// it must be jumping to an HPAT page containing ldr <reg> [PC+PAGE_SIZE-4], br <reg>.
|
// it must be jumping to an HPAT page containing ldr <reg> [PC+PAGE_SIZE-4], br <reg>.
|
||||||
const uint32_t opcode = fetch_opcode(code);
|
const uint32_t opcode = detour_arm64_fetch_opcode(code);
|
||||||
|
|
||||||
if ((opcode & 0xfc000000) != 0x14000000) {
|
if ((opcode & 0xfc000000) != 0x14000000) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -198,8 +198,8 @@ static inline bool internal_detour_is_code_os_patched(const uint8_t* code)
|
||||||
const uint8_t* branch_target = code + delta;
|
const uint8_t* branch_target = code + delta;
|
||||||
|
|
||||||
// Now inspect the opcodes of the code we jumped to in order to determine if it's HPAT.
|
// Now inspect the opcodes of the code we jumped to in order to determine if it's HPAT.
|
||||||
const uint32_t hpat_opcode1 = fetch_opcode(branch_target);
|
const uint32_t hpat_opcode1 = detour_arm64_fetch_opcode(branch_target);
|
||||||
const uint32_t hpat_opcode2 = fetch_opcode(branch_target + 4);
|
const uint32_t hpat_opcode2 = detour_arm64_fetch_opcode(branch_target + 4);
|
||||||
|
|
||||||
if (hpat_opcode1 != 0x58008010) { // ldr <reg> [PC+PAGE_SIZE]
|
if (hpat_opcode1 != 0x58008010) { // ldr <reg> [PC+PAGE_SIZE]
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -210,12 +210,12 @@ static inline bool internal_detour_is_code_os_patched(const uint8_t* code)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool internal_detour_does_code_end_function(const uint8_t* code)
|
static inline bool detour_platform_does_code_end_function(const uint8_t* code)
|
||||||
{
|
{
|
||||||
const uint32_t opcode = fetch_opcode(code);
|
const uint32_t opcode = detour_arm64_fetch_opcode(code);
|
||||||
// When the OS has patched a function entry point, it will incorrectly
|
// When the OS has patched a function entry point, it will incorrectly
|
||||||
// appear as though the function is just a single branch instruction.
|
// appear as though the function is just a single branch instruction.
|
||||||
if (internal_detour_is_code_os_patched(code)) {
|
if (detour_arm64_is_code_os_patched(code)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((opcode & 0xffbffc1f) == 0xd61f0000 || // ret/br <reg>
|
if ((opcode & 0xffbffc1f) == 0xd61f0000 || // ret/br <reg>
|
||||||
|
|
@ -225,7 +225,7 @@ static inline bool internal_detour_does_code_end_function(const uint8_t* code)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t internal_detour_is_code_filler(const uint8_t* code)
|
static inline uint32_t detour_platform_is_code_filler(const uint8_t* code)
|
||||||
{
|
{
|
||||||
if (*(uint32_t*)code == 0xd503201f) { // nop.
|
if (*(uint32_t*)code == 0xd503201f) { // nop.
|
||||||
return 4;
|
return 4;
|
||||||
|
|
@ -236,31 +236,31 @@ static inline uint32_t internal_detour_is_code_filler(const uint8_t* code)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_skip_jmp(uint8_t* code)
|
static inline uint8_t* detour_platform_skip_jmp(uint8_t* code)
|
||||||
{
|
{
|
||||||
// nothing special implemented
|
// nothing special implemented
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_operation_get_target_ptr(detour_operation* operation)
|
static inline uint8_t* detour_platform_operation_get_target_ptr(detour_operation* operation)
|
||||||
{
|
{
|
||||||
return operation->target;
|
return operation->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_operation_get_trampoline_ptr(detour_operation* operation)
|
static inline uint8_t* detour_platform_operation_get_trampoline_ptr(detour_operation* operation)
|
||||||
{
|
{
|
||||||
return operation->trampoline->code;
|
return operation->trampoline->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t* internal_detour_operation_commit_detour(detour_operation* operation)
|
static inline uint8_t* detour_platform_operation_commit_detour(detour_operation* operation)
|
||||||
{
|
{
|
||||||
uint8_t* code = internal_detour_gen_jmp_indirect(
|
uint8_t* code = detour_arm64_gen_jmp_indirect(
|
||||||
operation->target, (uint64_t*)&(operation->trampoline->ptr_detour));
|
operation->target, (uint64_t*)&(operation->trampoline->ptr_detour));
|
||||||
code = internal_detour_gen_brk(code, operation->trampoline->ptr_remain);
|
code = detour_platform_gen_brk(code, operation->trampoline->ptr_remain);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void internal_detour_update_thread_on_commit(detour_pending_thread* thread, detour_operation* operations_head)
|
static inline void detour_platform_update_thread_on_commit(detour_pending_thread* thread, detour_operation* operations_head)
|
||||||
{
|
{
|
||||||
arm_thread_state64_t threadState;
|
arm_thread_state64_t threadState;
|
||||||
mach_msg_type_number_t threadStateCnt = ARM_THREAD_STATE64_COUNT;
|
mach_msg_type_number_t threadStateCnt = ARM_THREAD_STATE64_COUNT;
|
||||||
|
|
|
||||||
|
|
@ -37,25 +37,6 @@
|
||||||
#define UNUSED_VARIABLE(x) (void)(x)
|
#define UNUSED_VARIABLE(x) (void)(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Region reserved for system DLLs, which cannot be used for trampolines.
|
|
||||||
static void* s_system_region_lower_bound = (void*)(uintptr_t)0x70000000;
|
|
||||||
static void* s_system_region_upper_bound = (void*)(uintptr_t)0x80000000;
|
|
||||||
|
|
||||||
static inline uintptr_t internal_detour_2gb_below(const uintptr_t address)
|
|
||||||
{
|
|
||||||
return (address > 0x7ff80000) ? address - 0x7ff80000 : 0x80000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uintptr_t internal_detour_2gb_above(uintptr_t address)
|
|
||||||
{
|
|
||||||
#if defined(DETOURS_64BIT)
|
|
||||||
return (address < 0xffffffff80000000) ? address + 0x7ff80000 : 0xfffffffffff80000;
|
|
||||||
#else
|
|
||||||
return (address < 0x80000000) ? address + 0x7ff80000 : 0xfff80000;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Structs
|
// Structs
|
||||||
|
|
||||||
|
|
@ -89,10 +70,31 @@ typedef struct detour_align
|
||||||
uint8_t offset_trampoline;
|
uint8_t offset_trampoline;
|
||||||
} detour_align;
|
} detour_align;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Trampoline Memory Management Helpers
|
||||||
|
|
||||||
|
// Region reserved for system DLLs, which cannot be used for trampolines.
|
||||||
|
static void* s_system_region_lower_bound = (void*)(uintptr_t)0x70000000;
|
||||||
|
static void* s_system_region_upper_bound = (void*)(uintptr_t)0x80000000;
|
||||||
|
|
||||||
|
static inline uintptr_t internal_detour_2gb_below(const uintptr_t address)
|
||||||
|
{
|
||||||
|
return (address > 0x7ff80000) ? address - 0x7ff80000 : 0x80000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uintptr_t internal_detour_2gb_above(uintptr_t address)
|
||||||
|
{
|
||||||
|
#if defined(DETOURS_64BIT)
|
||||||
|
return (address < 0xffffffff80000000) ? address + 0x7ff80000 : 0xfffffffffff80000;
|
||||||
|
#else
|
||||||
|
return (address < 0x80000000) ? address + 0x7ff80000 : 0xfff80000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Trampoline Helpers
|
// Trampoline Helpers
|
||||||
|
|
||||||
static uint8_t internal_detour_align_from_trampoline(const detour_align align[], const size_t align_size, const uint8_t offset_trampoline)
|
static inline uint8_t internal_detour_align_from_trampoline(const detour_align align[], const size_t align_size, const uint8_t offset_trampoline)
|
||||||
{
|
{
|
||||||
for (size_t n = 0; n < align_size; n++) {
|
for (size_t n = 0; n < align_size; n++) {
|
||||||
if (align[n].offset_trampoline == offset_trampoline) {
|
if (align[n].offset_trampoline == offset_trampoline) {
|
||||||
|
|
@ -102,7 +104,7 @@ static uint8_t internal_detour_align_from_trampoline(const detour_align align[],
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t internal_detour_align_from_target(const detour_align align[], const size_t align_size, const uint8_t offset_target)
|
static inline uint8_t internal_detour_align_from_target(const detour_align align[], const size_t align_size, const uint8_t offset_target)
|
||||||
{
|
{
|
||||||
for (size_t n = 0; n < align_size; n++) {
|
for (size_t n = 0; n < align_size; n++) {
|
||||||
if (align[n].offset_target == offset_target) {
|
if (align[n].offset_target == offset_target) {
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ static detour_trampoline* internal_detour_alloc_trampoline(uint8_t* target)
|
||||||
detour_trampoline* lo;
|
detour_trampoline* lo;
|
||||||
detour_trampoline* hi;
|
detour_trampoline* hi;
|
||||||
|
|
||||||
internal_detour_find_jmp_bounds(target, &lo, &hi);
|
detour_platform_find_jmp_bounds(target, &lo, &hi);
|
||||||
|
|
||||||
// ReSharper disable once CppDFAUnusedValue
|
// ReSharper disable once CppDFAUnusedValue
|
||||||
detour_trampoline* trampoline = nullptr;
|
detour_trampoline* trampoline = nullptr;
|
||||||
|
|
@ -421,8 +421,8 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target)
|
||||||
operation->target[4], operation->target[5], operation->target[6], operation->target[7],
|
operation->target[4], operation->target[5], operation->target[6], operation->target[7],
|
||||||
operation->target[8], operation->target[9], operation->target[10], operation->target[11]));
|
operation->target[8], operation->target[9], operation->target[10], operation->target[11]));
|
||||||
|
|
||||||
internal_detour_operation_commit_detour(operation);
|
detour_platform_operation_commit_detour(operation);
|
||||||
*operation->pointer = internal_detour_operation_get_trampoline_ptr(operation)
|
*operation->pointer = detour_platform_operation_get_trampoline_ptr(operation)
|
||||||
|
|
||||||
DETOUR_TRACE(("detours: target=%p: "
|
DETOUR_TRACE(("detours: target=%p: "
|
||||||
"%02x %02x %02x %02x "
|
"%02x %02x %02x %02x "
|
||||||
|
|
@ -449,7 +449,7 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target)
|
||||||
case detour_operation_kind_detach: {
|
case detour_operation_kind_detach: {
|
||||||
memcpy(operation->target, operation->trampoline->restore_code,
|
memcpy(operation->target, operation->trampoline->restore_code,
|
||||||
operation->trampoline->restore_code_size);
|
operation->trampoline->restore_code_size);
|
||||||
*operation->pointer = internal_detour_operation_get_target_ptr(operation);
|
*operation->pointer = detour_platform_operation_get_target_ptr(operation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -457,7 +457,7 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target)
|
||||||
|
|
||||||
// Update any suspended threads.
|
// Update any suspended threads.
|
||||||
for (detour_pending_thread* thread = s_pending_threads_head; thread != nullptr; thread = thread->next) {
|
for (detour_pending_thread* thread = s_pending_threads_head; thread != nullptr; thread = thread->next) {
|
||||||
internal_detour_update_thread_on_commit(thread, s_pending_operations_head);
|
detour_platform_update_thread_on_commit(thread, s_pending_operations_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore all the page permissions
|
// Restore all the page permissions
|
||||||
|
|
@ -606,8 +606,8 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
detour_trampoline* trampoline = nullptr;
|
detour_trampoline* trampoline = nullptr;
|
||||||
detour_operation* op = nullptr;
|
detour_operation* op = nullptr;
|
||||||
|
|
||||||
uint8_t* target = internal_detour_skip_jmp(*inout_pointer);
|
uint8_t* target = detour_platform_skip_jmp(*inout_pointer);
|
||||||
detour = internal_detour_skip_jmp(detour);
|
detour = detour_platform_skip_jmp(detour);
|
||||||
|
|
||||||
// Don't follow a jump if its destination is the target function.
|
// Don't follow a jump if its destination is the target function.
|
||||||
// This happens when the detour does nothing other than call the target.
|
// This happens when the detour does nothing other than call the target.
|
||||||
|
|
@ -678,7 +678,7 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
uint32_t offset_target = 0;
|
uint32_t offset_target = 0;
|
||||||
uint32_t align_idx = 0;
|
uint32_t align_idx = 0;
|
||||||
|
|
||||||
while (offset_target < DETOUR_SIZE_OF_JMP) {
|
while (offset_target < DETOUR_PLATFORM_SIZE_OF_JMP) {
|
||||||
const uint8_t* curr_op = src;
|
const uint8_t* curr_op = src;
|
||||||
uint32_t extra_len = 0;
|
uint32_t extra_len = 0;
|
||||||
|
|
||||||
|
|
@ -695,14 +695,14 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internal_detour_does_code_end_function(curr_op)) {
|
if (detour_platform_does_code_end_function(curr_op)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume, but don't duplicate padding if it is needed and available.
|
// Consume, but don't duplicate padding if it is needed and available.
|
||||||
while (offset_target < DETOUR_SIZE_OF_JMP) {
|
while (offset_target < DETOUR_PLATFORM_SIZE_OF_JMP) {
|
||||||
const uint32_t len_filler = internal_detour_is_code_filler(src);
|
const uint32_t len_filler = detour_platform_is_code_filler(src);
|
||||||
if (len_filler == 0) {
|
if (len_filler == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -725,7 +725,7 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (offset_target < DETOUR_SIZE_OF_JMP || align_idx > ARRAYSIZE(trampoline->align)) {
|
if (offset_target < DETOUR_PLATFORM_SIZE_OF_JMP || align_idx > ARRAYSIZE(trampoline->align)) {
|
||||||
// Too few instructions.
|
// Too few instructions.
|
||||||
error = detour_err_too_small;
|
error = detour_err_too_small;
|
||||||
if (s_ignore_too_small) {
|
if (s_ignore_too_small) {
|
||||||
|
|
@ -744,7 +744,7 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
trampoline->restore_code_size = (uint8_t)offset_target;
|
trampoline->restore_code_size = (uint8_t)offset_target;
|
||||||
memcpy(trampoline->restore_code, target, offset_target);
|
memcpy(trampoline->restore_code, target, offset_target);
|
||||||
|
|
||||||
if (offset_target > sizeof(trampoline->code) - DETOUR_SIZE_OF_JMP) {
|
if (offset_target > sizeof(trampoline->code) - DETOUR_PLATFORM_SIZE_OF_JMP) {
|
||||||
// Too many instructions.
|
// Too many instructions.
|
||||||
error = detour_err_too_large;
|
error = detour_err_too_large;
|
||||||
DETOUR_BREAK();
|
DETOUR_BREAK();
|
||||||
|
|
@ -757,8 +757,8 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
||||||
trampoline_code = trampoline->code + trampoline->code_size;
|
trampoline_code = trampoline->code + trampoline->code_size;
|
||||||
|
|
||||||
trampoline_code =
|
trampoline_code =
|
||||||
internal_detour_gen_jmp_immediate(trampoline_code, &trampoline_code_limit, trampoline->ptr_remain);
|
detour_platform_gen_jmp_immediate(trampoline_code, &trampoline_code_limit, trampoline->ptr_remain);
|
||||||
trampoline_code = internal_detour_gen_brk(trampoline_code, trampoline_code_limit);
|
trampoline_code = detour_platform_gen_brk(trampoline_code, trampoline_code_limit);
|
||||||
UNUSED_VARIABLE(trampoline_code);
|
UNUSED_VARIABLE(trampoline_code);
|
||||||
|
|
||||||
const mach_port_t port = mach_task_self();
|
const mach_port_t port = mach_task_self();
|
||||||
|
|
@ -856,8 +856,8 @@ mach_error_t detour_detach(detour_func_t* inout_pointer, detour_func_t detour)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
detour_trampoline* trampoline = (detour_trampoline*)internal_detour_skip_jmp(*inout_pointer);
|
detour_trampoline* trampoline = (detour_trampoline*)detour_platform_skip_jmp(*inout_pointer);
|
||||||
detour = internal_detour_skip_jmp(detour);
|
detour = detour_platform_skip_jmp(detour);
|
||||||
|
|
||||||
// Verify that Trampoline is in place.
|
// Verify that Trampoline is in place.
|
||||||
const int32_t restore_code_size = trampoline->restore_code_size;
|
const int32_t restore_code_size = trampoline->restore_code_size;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue