added test
This commit is contained in:
parent
ade0920e54
commit
aaad260259
4 changed files with 94 additions and 42 deletions
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "mach_detours.h"
|
||||
|
||||
#define DETOUR_DEBUG 1
|
||||
#define DETOUR_DEBUG 0
|
||||
|
||||
#ifdef __arm64__
|
||||
#define DETOURS_ARM64
|
||||
|
|
@ -141,8 +141,8 @@ static void* internal_detour_alloc_region_from_hi(const uint8_t* lo, const uint8
|
|||
}
|
||||
|
||||
static void* internal_detour_alloc_trampoline_allocate_new(const uint8_t* target,
|
||||
detour_trampoline* lo,
|
||||
detour_trampoline* hi)
|
||||
detour_trampoline* lo,
|
||||
detour_trampoline* hi)
|
||||
{
|
||||
void* try_addr = nullptr;
|
||||
|
||||
|
|
@ -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:
|
||||
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;
|
||||
|
|
@ -236,7 +235,7 @@ static detour_trampoline* internal_detour_alloc_trampoline(uint8_t* target)
|
|||
s_default_region->next = s_regions_head;
|
||||
s_regions_head = s_default_region;
|
||||
DETOUR_TRACE((" Allocated region %p..%p\n\n",
|
||||
s_default_region, ((uint8_t*)s_default_region) + DETOUR_REGION_SIZE - 1));
|
||||
s_default_region, ((uint8_t*)s_default_region) + DETOUR_REGION_SIZE - 1));
|
||||
|
||||
// Put everything but the first trampoline on the free list.
|
||||
uint8_t* free = nullptr;
|
||||
|
|
@ -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;
|
||||
|
|
@ -719,10 +717,10 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
|||
op = calloc(1, sizeof(detour_operation));
|
||||
if (!op) {
|
||||
error = KERN_RESOURCE_SHORTAGE;
|
||||
fail:
|
||||
fail:
|
||||
s_pending_error = error;
|
||||
DETOUR_BREAK();
|
||||
stop:
|
||||
stop:
|
||||
if (trampoline) {
|
||||
internal_detour_free_trampoline(trampoline);
|
||||
// ReSharper disable once CppDFAUnusedValue
|
||||
|
|
@ -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;
|
||||
|
|
@ -872,24 +872,24 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
|
|||
}
|
||||
|
||||
DETOUR_TRACE(("detours: target=%p: "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x\n",
|
||||
target,
|
||||
target[0], target[1], target[2], target[3],
|
||||
target[4], target[5], target[6], target[7],
|
||||
target[8], target[9], target[10], target[11]));
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x\n",
|
||||
target,
|
||||
target[0], target[1], target[2], target[3],
|
||||
target[4], target[5], target[6], target[7],
|
||||
target[8], target[9], target[10], target[11]));
|
||||
DETOUR_TRACE(("detours: trampoline =%p: "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x\n",
|
||||
trampoline,
|
||||
trampoline->code[0], trampoline->code[1],
|
||||
trampoline->code[2], trampoline->code[3],
|
||||
trampoline->code[4], trampoline->code[5],
|
||||
trampoline->code[6], trampoline->code[7],
|
||||
trampoline->code[8], trampoline->code[9],
|
||||
trampoline->code[10], trampoline->code[11]));
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x\n",
|
||||
trampoline,
|
||||
trampoline->code[0], trampoline->code[1],
|
||||
trampoline->code[2], trampoline->code[3],
|
||||
trampoline->code[4], trampoline->code[5],
|
||||
trampoline->code[6], trampoline->code[7],
|
||||
trampoline->code[8], trampoline->code[9],
|
||||
trampoline->code[10], trampoline->code[11]));
|
||||
|
||||
op->kind = detour_operation_kind_attach;
|
||||
op->pointer = (uint8_t**)inout_pointer;
|
||||
|
|
@ -931,10 +931,10 @@ mach_error_t detour_detach(detour_func_t* inout_pointer, detour_func_t detour)
|
|||
detour_operation* op = calloc(1, sizeof(detour_operation));
|
||||
if (!op) {
|
||||
error = KERN_RESOURCE_SHORTAGE;
|
||||
fail:
|
||||
fail:
|
||||
s_pending_error = error;
|
||||
DETOUR_BREAK();
|
||||
stop:
|
||||
stop:
|
||||
free(op);
|
||||
// ReSharper disable once CppDFAUnusedValue
|
||||
op = nullptr;
|
||||
|
|
@ -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