diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | lib/darwin/execmem.c | 22 | ||||
-rwxr-xr-x | script/gen-manual-mach.sh | 2 | ||||
-rw-r--r-- | test/test-hook-functions.c | 11 |
4 files changed, 26 insertions, 13 deletions
@@ -38,7 +38,7 @@ $(eval $(call do_prefix,thumb,-n _thumb,ARM)) $(eval $(call do_prefix,arm,-n _arm,ARM)) $(eval $(call do_prefix,arm64,,AArch64)) -HEADERS := lib/*.h lib/*/*.h +HEADERS := lib/*.h lib/*/*.h generated/manual-mach.inc.h out/%.o: lib/%.c Makefile $(HEADERS) @mkdir -p $(dir $@) @@ -141,7 +141,7 @@ $(eval $(call define_test,interpose,interpose,$(CC) -std=c11 -lsubstitute)) $(eval $(call define_test,inject,inject,$(CC) -std=c11 -lsubstitute out/darwin/inject.o out/darwin/read.o)) $(eval $(call define_test,pc-patch,pc-patch,$(CC) -std=c11 out/darwin/execmem.o)) $(eval $(call define_test,execmem,execmem,$(CC) -std=c11 out/darwin/execmem.o -segprot __TEST rwx rx)) -$(eval $(call define_test,hook-functions,hook-functions,$(CC) -std=c11 -lsubstitute)) +$(eval $(call define_test,hook-functions,hook-functions,$(CC) -std=c11 -lsubstitute -segprot __TEST rwx rx)) $(eval $(call define_test,posixspawn-hook,posixspawn-hook,$(CC) -std=c11)) $(eval $(call define_test,htab,htab,$(CC) -std=c11)) diff --git a/lib/darwin/execmem.c b/lib/darwin/execmem.c index 7d8e802..666fa8a 100644 --- a/lib/darwin/execmem.c +++ b/lib/darwin/execmem.c @@ -45,6 +45,8 @@ static void manual_memcpy(void *restrict dest, const void *src, size_t len) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" +#define __MachMsgErrorWithTimeout(_R_) +#define __MachMsgErrorWithoutTimeout(_R_) #include "../generated/manual-mach.inc.h" #pragma GCC diagnostic pop @@ -298,8 +300,8 @@ static int compare_dsts(const void *a, const void *b) { return dst_a < dst_b ? -1 : dst_a > dst_b ? 1 : 0; } -static kern_return_t get_page_prot(uintptr_t ptr, vm_prot_t *prot, - vm_inherit_t *inherit) { +static kern_return_t get_page_info(uintptr_t ptr, vm_prot_t *prot_p, + vm_inherit_t *inherit_p) { vm_address_t region = (vm_address_t) ptr; vm_size_t region_len = 0; @@ -310,8 +312,8 @@ static kern_return_t get_page_prot(uintptr_t ptr, vm_prot_t *prot, &max_depth, (vm_region_recurse_info_t) &info, &info_count); - *prot = info.protection & (PROT_READ | PROT_WRITE | PROT_EXEC); - *inherit = info.inheritance; + *prot_p = info.protection & (PROT_READ | PROT_WRITE | PROT_EXEC); + *inherit_p = info.inheritance; return kr; } @@ -369,7 +371,7 @@ int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, /* Assume that a single patch region will be pages of all the same * protection, since the alternative is probably someone doing * something wrong. */ - kern_return_t kr = get_page_prot(page_start, &prot, &inherit); + kern_return_t kr = get_page_info(page_start, &prot, &inherit); if (kr) { /* Weird; this probably means the region doesn't exist, but we should * have already read from the memory in order to generate the patch. */ @@ -427,16 +429,16 @@ int execmem_foreign_write_with_pc_patch(struct execmem_foreign_write *writes, } /* Protect new like the original, and move it into place. */ - vm_address_t target = page_start; if (manual_mprotect(new, len, prot)) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; } vm_prot_t c, m; - printf("new=%p\n", new); - kr = manual_vm_remap(task_self, &target, len, 0, VM_FLAGS_OVERWRITE, - task_self, (vm_address_t) new, /*copy*/ FALSE, - &c, &m, inherit, reply_port); + mach_vm_address_t target = page_start; + kr = manual_mach_vm_remap(mach_task_self(), &target, len, 0, + VM_FLAGS_OVERWRITE, task_self, + (mach_vm_address_t) new, /*copy*/ TRUE, + &c, &m, inherit, reply_port); if (kr) { ret = SUBSTITUTE_ERR_VM; goto fail_unmap; diff --git a/script/gen-manual-mach.sh b/script/gen-manual-mach.sh index 02f7eda..b740af9 100755 --- a/script/gen-manual-mach.sh +++ b/script/gen-manual-mach.sh @@ -1,6 +1,6 @@ #!/bin/bash out=generated/manual-mach.inc.h -(mig -user /dev/stdout -server /dev/null -header /dev/null /usr/include/mach/{thread_act,vm_map}.defs | +(mig -user /dev/stdout -server /dev/null -header /dev/null /usr/include/mach/{thread_act,mach_vm}.defs | unifdef -U__MigTypeCheck | grep -v '#define USING_VOUCHERS' | sed -E 's/(mach_msg|memcpy)\(/manual_\1(/g; diff --git a/test/test-hook-functions.c b/test/test-hook-functions.c index ab027de..7978658 100644 --- a/test/test-hook-functions.c +++ b/test/test-hook-functions.c @@ -31,7 +31,17 @@ void break_after() { __asm__ volatile(""); } +__attribute__((section("__TEST,__foo"), noinline)) +static int my_own_function(int x) { + return x + 4; +} + +static int hook_my_own_function(int x) { + return x + 5; +} + static const struct substitute_function_hook hooks[] = { + {my_own_function, hook_my_own_function, NULL}, {getpid, hook_getpid, &old_getpid}, {hcreate, hook_hcreate, NULL}, {fwrite, hook_fwrite, &old_fwrite}, @@ -55,6 +65,7 @@ int main() { printf("errno = %d\n", e); printf("getpid() => %d\n", getpid()); printf("hcreate() => %d\n", hcreate(42)); + printf("my_own_function() => %d\n", my_own_function(0)); #else (void) hooks; printf("can't test this here\n"); |