diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/darwin/execmem.c | 7 | ||||
-rw-r--r-- | lib/execmem.h | 7 | ||||
-rw-r--r-- | lib/hook-functions.c | 22 | ||||
-rw-r--r-- | lib/substitute.h | 2 | ||||
-rw-r--r-- | lib/vita/execmem.c | 9 |
5 files changed, 28 insertions, 19 deletions
diff --git a/lib/darwin/execmem.c b/lib/darwin/execmem.c index 540cb8e..44b26ae 100644 --- a/lib/darwin/execmem.c +++ b/lib/darwin/execmem.c @@ -63,7 +63,8 @@ static execmem_pc_patch_callback g_pc_patch_callback; static void *g_pc_patch_callback_ctx; static mach_port_t g_suspending_thread; -int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, size_t *size_p) { +int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, + size_t *size_p, UNUSED void *opt) { *size_p = PAGE_SIZE; *page_p = mmap((void *) hint, *size_p, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); @@ -73,13 +74,13 @@ int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, size return SUBSTITUTE_OK; } -int execmem_seal(void *page) { +int execmem_seal(void *page, UNUSED void *opt) { if (mprotect(page, PAGE_SIZE, PROT_READ | PROT_EXEC)) return SUBSTITUTE_ERR_VM; return SUBSTITUTE_OK; } -void execmem_free(void *page) { +void execmem_free(void *page, UNUSED void *opt) { munmap(page, PAGE_SIZE); } diff --git a/lib/execmem.h b/lib/execmem.h index 8817f38..07e9fa4 100644 --- a/lib/execmem.h +++ b/lib/execmem.h @@ -1,9 +1,9 @@ #pragma once #include <sys/types.h> /* For allocating trampolines - this is just a mmap wrapper. */ -int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, size_t *size_p); -int execmem_seal(void *page); -void execmem_free(void *page); +int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, size_t *size_p, void *opt); +int execmem_seal(void *page, void *opt); +void execmem_free(void *page, void *opt); /* Write to "foreign" (i.e. owned by another library, not out-of-process) pages * which are already RX or have unknown permissions. @@ -15,6 +15,7 @@ struct execmem_foreign_write { void *dst; const void *src; size_t len; + void *opt; }; typedef uintptr_t (*execmem_pc_patch_callback)(void *ctx, uintptr_t pc); int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, diff --git a/lib/hook-functions.c b/lib/hook-functions.c index 4fc61e0..996e781 100644 --- a/lib/hook-functions.c +++ b/lib/hook-functions.c @@ -72,7 +72,8 @@ static int check_intro_trampoline(void **trampoline_ptr_p, int *patch_size_p, bool *need_intro_trampoline_p, void **trampoline_page_p, - struct arch_dis_ctx arch) { + struct arch_dis_ctx arch, + void *opt) { void *trampoline_ptr = *trampoline_ptr_p; uintptr_t trampoline_addr = *trampoline_addr_p; size_t trampoline_size_left = *trampoline_size_left_p; @@ -98,7 +99,7 @@ static int check_intro_trampoline(void **trampoline_ptr_p, /* Allocate new trampoline - try after pc. If this fails, we can try * before pc before giving up. */ int ret = execmem_alloc_unsealed(pc, &trampoline_ptr, &trampoline_addr, - &trampoline_size_left); + &trampoline_size_left, opt); if (!ret) { *patch_size_p = jump_patch_size(pc, trampoline_addr, arch, false); if (*patch_size_p != -1) { @@ -106,13 +107,13 @@ static int check_intro_trampoline(void **trampoline_ptr_p, goto end; } - execmem_free(trampoline_ptr); + execmem_free(trampoline_ptr, opt); } /* Allocate new trampoline - try before pc (xxx only meaningful on arm64) */ uintptr_t start_address = pc - 0x80000000; ret = execmem_alloc_unsealed(start_address, &trampoline_ptr, &trampoline_addr, - &trampoline_size_left); + &trampoline_size_left, opt); if (!ret) { *patch_size_p = jump_patch_size(pc, trampoline_addr, arch, false); if (*patch_size_p != -1) { @@ -120,7 +121,7 @@ static int check_intro_trampoline(void **trampoline_ptr_p, goto end; } - execmem_free(trampoline_ptr); + execmem_free(trampoline_ptr, opt); ret = SUBSTITUTE_ERR_OUT_OF_RANGE; } @@ -190,7 +191,8 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, &trampoline_size_left, pc_patch_start, (uintptr_t) hook->replacement, &patch_size, &need_intro_trampoline, - &hi->trampoline_page, arch))) + &hi->trampoline_page, arch, + hook->opt))) goto end; uint_tptr pc_patch_end = pc_patch_start + patch_size; @@ -217,7 +219,8 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, /* Not enough space left in our existing block... */ if ((ret = execmem_alloc_unsealed(0, &trampoline_ptr, &trampoline_addr, - &trampoline_size_left))) + &trampoline_size_left, + hook->opt))) goto end; /* NOTE: We assume that each page is large enough (min 0x1000) * so we don't lose a reference by having one hook allocate two @@ -273,10 +276,11 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, struct hook_internal *hi = &his[i]; void *page = hi->trampoline_page; if (page) - execmem_seal(page); + execmem_seal(page, hooks[i].opt); fws[i].dst = hi->code; fws[i].src = hi->jump_patch; fws[i].len = hi->jump_patch_size; + fws[i].opt = hooks[i].opt; } struct pc_callback_info info = {his, nhooks, false}; @@ -296,7 +300,7 @@ end: for (size_t i = 0; i < nhooks; i++) { void *page = his[i].trampoline_page; if (page) - execmem_free(page); + execmem_free(page, hooks[i].opt); } end_dont_free: return ret; diff --git a/lib/substitute.h b/lib/substitute.h index 9a8d9ba..4e4f7f9 100644 --- a/lib/substitute.h +++ b/lib/substitute.h @@ -100,6 +100,8 @@ struct substitute_function_hook { int options; /* If not zero, then assume the actual address of function is func_addr */ uintptr_t func_addr; + /* Any platform specific auxiliary data */ + void *opt; }; /* substitute_hook_functions options */ diff --git a/lib/vita/execmem.c b/lib/vita/execmem.c index c0fba65..6bfb2ba 100644 --- a/lib/vita/execmem.c +++ b/lib/vita/execmem.c @@ -2,20 +2,21 @@ #include "execmem.h" #include "substitute.h" -int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, size_t *size_p) { +int execmem_alloc_unsealed(uintptr_t hint, void **page_p, uintptr_t *vma_p, + size_t *size_p, void *opt) { return 0; } -int execmem_seal(void *page) { +int execmem_seal(void *page, void *opt) { return SUBSTITUTE_OK; } -void execmem_free(void *page) { +void execmem_free(void *page, void *opt) { } int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, size_t nwrites, execmem_pc_patch_callback callback, - void *callback_ctx) { + void *callback_ctx, void *opt) { return 0; } |