added test
This commit is contained in:
parent
ade0920e54
commit
aaad260259
4 changed files with 94 additions and 42 deletions
|
|
@ -14,7 +14,15 @@ add_library(mach_detours SHARED
|
|||
src/arm64/detours_arm64.h
|
||||
src/arm64/detours_arm64_disasm.cpp
|
||||
)
|
||||
|
||||
target_include_directories(mach_detours
|
||||
PUBLIC "include"
|
||||
PRIVATE "src")
|
||||
PUBLIC include
|
||||
PRIVATE src
|
||||
)
|
||||
|
||||
|
||||
add_executable(mach_detours_sample
|
||||
sample/main.cpp
|
||||
)
|
||||
target_link_libraries(mach_detours_sample
|
||||
PRIVATE mach_detours
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#ifndef MACH_DETOURS_H
|
||||
#define MACH_DETOURS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <mach/error.h>
|
||||
#include <mach/mach_types.h>
|
||||
|
||||
|
|
@ -31,4 +35,8 @@ bool detour_set_retain_regions(bool value);
|
|||
void* detour_set_system_region_lower_bound(void* value);
|
||||
void* detour_set_system_region_upper_bound(void* value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MACH_DETOURS_H
|
||||
|
|
|
|||
34
sample/main.cpp
Normal file
34
sample/main.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) Lysann Tranvouez. All rights reserved.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "mach_detours.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
char* (*real_strerror)(int errno) = strerror;
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
char* my_strerror(const int errno)
|
||||
{
|
||||
counter++;
|
||||
return real_strerror(errno);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
counter = 0;
|
||||
strerror(0);
|
||||
assert(counter == 0);
|
||||
|
||||
detour_transaction_begin();
|
||||
detour_attach(reinterpret_cast<detour_func_t*>(&real_strerror), reinterpret_cast<detour_func_t>(my_strerror));
|
||||
detour_transaction_commit();
|
||||
|
||||
assert(counter == 0);
|
||||
strerror(0);
|
||||
assert(counter == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "mach_detours.h"
|
||||
|
||||
#define DETOUR_DEBUG 1
|
||||
#define DETOUR_DEBUG 0
|
||||
|
||||
#ifdef __arm64__
|
||||
#define DETOURS_ARM64
|
||||
|
|
@ -200,12 +200,11 @@ static detour_trampoline* internal_detour_alloc_trampoline(uint8_t* target)
|
|||
// First check the default region for a valid free block.
|
||||
if (s_default_region && s_default_region->free_list_head &&
|
||||
s_default_region->free_list_head >= lo && s_default_region->free_list_head <= hi) {
|
||||
|
||||
found_region:
|
||||
trampoline = s_default_region->free_list_head;
|
||||
// do a last sanity check on region.
|
||||
if (trampoline < lo || trampoline > hi) {
|
||||
raise(SIGTRAP);
|
||||
DETOUR_BREAK();
|
||||
return nullptr;
|
||||
}
|
||||
s_default_region->free_list_head = (detour_trampoline*)trampoline->ptr_remain;
|
||||
|
|
@ -522,9 +521,8 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target)
|
|||
if (pc >= targetAddr && pc < targetAddr + op->trampoline->restore_code_size) {
|
||||
uintptr_t new_pc = (uintptr_t)op->trampoline;
|
||||
new_pc += internal_detour_align_from_target(op->trampoline, pc - targetAddr);
|
||||
printf("detours: thread %u was at 0x%" PRIXPTR ", moved to 0x%" PRIXPTR "\n", thread->thread,
|
||||
pc,
|
||||
new_pc);
|
||||
DETOUR_TRACE(("detours: thread %u was at 0x%" PRIXPTR ", moved to 0x%" PRIXPTR "\n",
|
||||
thread->thread, pc, new_pc));
|
||||
arm_thread_state64_set_pc_fptr(threadState, new_pc);
|
||||
thread_set_state(thread->thread, ARM_THREAD_STATE64, (thread_state_t)&threadState,
|
||||
ARM_THREAD_STATE64_COUNT);
|
||||
|
|
@ -536,9 +534,8 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target)
|
|||
if (pc >= trampAddr && pc < trampAddr + sizeof(*op->trampoline)) {
|
||||
uintptr_t new_pc = (uintptr_t)op->target;
|
||||
new_pc += internal_detour_align_from_trampoline(op->trampoline, pc - trampAddr);
|
||||
printf("detours: thread %u was at 0x%" PRIXPTR ", moved to 0x%" PRIXPTR "\n", thread->thread,
|
||||
pc,
|
||||
new_pc);
|
||||
DETOUR_TRACE(("detours: thread %u was at 0x%" PRIXPTR ", moved to 0x%" PRIXPTR "\n",
|
||||
thread->thread, pc, new_pc));
|
||||
arm_thread_state64_set_pc_fptr(threadState, new_pc);
|
||||
thread_set_state(thread->thread, ARM_THREAD_STATE64, (thread_state_t)&threadState,
|
||||
ARM_THREAD_STATE64_COUNT);
|
||||
|
|
@ -648,7 +645,8 @@ mach_error_t detour_attach(detour_func_t* inout_pointer, detour_func_t detour)
|
|||
return detour_attach_ex(inout_pointer, detour, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour, detour_func_t* out_real_trampoline, detour_func_t* out_real_target, detour_func_t* out_real_detour)
|
||||
mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour, detour_func_t* out_real_trampoline,
|
||||
detour_func_t* out_real_target, detour_func_t* out_real_detour)
|
||||
{
|
||||
if (out_real_trampoline) {
|
||||
*out_real_trampoline = nullptr;
|
||||
|
|
@ -844,7 +842,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 = internal_detour_gen_jmp_immediate(trampoline_code, &trampoline_code_limit, trampoline->ptr_remain);
|
||||
trampoline_code =
|
||||
internal_detour_gen_jmp_immediate(trampoline_code, &trampoline_code_limit, trampoline->ptr_remain);
|
||||
trampoline_code = internal_detour_gen_brk(trampoline_code, trampoline_code_limit);
|
||||
UNUSED_VARIABLE(trampoline_code);
|
||||
|
||||
|
|
@ -857,7 +856,8 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
|||
mach_vm_size_t region_size = 0;
|
||||
natural_t nesting_depth = 99999;
|
||||
mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
|
||||
error = mach_vm_region_recurse(port, ®ion_addr, ®ion_size, &nesting_depth, (vm_region_recurse_info_t)®ion_info, &count);
|
||||
error = mach_vm_region_recurse(port, ®ion_addr, ®ion_size, &nesting_depth,
|
||||
(vm_region_recurse_info_t)®ion_info, &count);
|
||||
if (error != err_none) {
|
||||
DETOUR_BREAK();
|
||||
goto fail;
|
||||
|
|
@ -976,7 +976,8 @@ mach_error_t detour_detach(detour_func_t* inout_pointer, detour_func_t detour)
|
|||
mach_vm_size_t region_size = 0;
|
||||
natural_t nesting_depth = 99999;
|
||||
mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
|
||||
error = mach_vm_region_recurse(port, ®ion_addr, ®ion_size, &nesting_depth, (vm_region_recurse_info_t)®ion_info, &count);
|
||||
error = mach_vm_region_recurse(port, ®ion_addr, ®ion_size, &nesting_depth,
|
||||
(vm_region_recurse_info_t)®ion_info, &count);
|
||||
if (error != err_none) {
|
||||
DETOUR_BREAK();
|
||||
goto fail;
|
||||
|
|
@ -984,7 +985,8 @@ mach_error_t detour_detach(detour_func_t* inout_pointer, detour_func_t detour)
|
|||
}
|
||||
const vm_prot_t old_perm = region_info.protection;
|
||||
|
||||
error = mach_vm_protect(port, (mach_vm_address_t)target, PAGE_SIZE, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
|
||||
error = mach_vm_protect(port, (mach_vm_address_t)target, PAGE_SIZE, false,
|
||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
|
||||
if (error != err_none) {
|
||||
DETOUR_BREAK();
|
||||
goto fail;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue