From d88b91519b96d8accdbfc4216010d0a42343ca33 Mon Sep 17 00:00:00 2001 From: comex Date: Fri, 10 Jul 2015 22:38:44 -0400 Subject: stuff! --- configure | 2 +- darwin-bootstrap/com.ex.substituted.plist | 5 ++++ darwin-bootstrap/substituted.m | 38 ++++++++++++++++++++++++++----- lib/hook-functions.c | 4 ++-- lib/jump-dis.c | 3 ++- lib/substitute.h | 4 ++-- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/configure b/configure index f6e51d9..ed64d23 100755 --- a/configure +++ b/configure @@ -212,7 +212,7 @@ if settings.enable_ios_bootstrap: ('dylib', '(out)/bundle-loader.dylib', ['(src)/darwin-bootstrap/bundle-loader.c'], [], [], []), ('exec', '(out)/unrestrict', ['(src)/darwin-bootstrap/unrestrict.c'], ls, [], []), ('exec', '(out)/inject-into-launchd', ['(src)/darwin-bootstrap/inject-into-launchd.c'], ls, ['-framework', 'IOKit', '-framework', 'CoreFoundation'], []), - ('exec', '(out)/substituted', ['(src)/darwin-bootstrap/substituted.m'], [], ['-lbsm', '-framework', 'Foundation', '-framework', 'CoreFoundation'], ['-fobjc-arc']), + ('exec', '(out)/substituted', ['(src)/darwin-bootstrap/substituted.m'], ls, ['-lbsm', '-framework', 'Foundation', '-framework', 'CoreFoundation'], ['-fobjc-arc']), ]: mconfig.build_and_link_c_objs(emitter, settings.host_machine(), settings.specialize(override_ldflags=ldf+settings.host.ldflags, override_cflags=cf+settings.host.cflags), ty, out, ins, objs=objs) diff --git a/darwin-bootstrap/com.ex.substituted.plist b/darwin-bootstrap/com.ex.substituted.plist index 4f30051..caed4c9 100644 --- a/darwin-bootstrap/com.ex.substituted.plist +++ b/darwin-bootstrap/com.ex.substituted.plist @@ -13,6 +13,11 @@ com.ex.substituted Program /Library/Substitute/Helpers/substituted + EnvironmentVariables + + _MSSafeMode + 1 + diff --git a/darwin-bootstrap/substituted.m b/darwin-bootstrap/substituted.m index cfa1541..ec30a49 100644 --- a/darwin-bootstrap/substituted.m +++ b/darwin-bootstrap/substituted.m @@ -1,6 +1,37 @@ #import #import #include "xxpc.h" +#include "substitute.h" +# + +/* This is a daemon contacted by all processes which can load extensions. It + * currently does the work of reading the plists in + * /Library/Substitute/DynamicLibraries in order to avoid loading objc/CF + * libraries into the target binary (unless actually required by loaded + * libraries). In the future it will help with hot loading. */ + +extern kern_return_t bootstrap_look_up3(mach_port_t bp, + const char *service_name, mach_port_t *sp, pid_t target_pid, + const uuid_t instance_id, uint64_t flags); + +static kern_return_t my_bootstrap_look_up3(mach_port_t bp, + const char *service_name, mach_port_t *sp, pid_t target_pid, + const uuid_t instance_id, uint64_t flags) { + NSLog(@"Something in substituted tried to look up '%s', which could cause a deadlock. This is a bug.", + service_name); + return KERN_FAILURE; +} +static const struct substitute_function_hook deadlock_warning_hook = { + bootstrap_look_up3, my_bootstrap_look_up3, NULL +}; + +static void install_deadlock_warning() { + int ret = substitute_hook_functions(&deadlock_warning_hook, 1, NULL, 0); + if (ret) { + NSLog(@"substitute_hook_functions(&deadlock_warning_hook, ..) failed: %d", + ret); + } +} enum convert_filters_ret { PROVISIONAL_PASS, @@ -211,13 +242,8 @@ static void init_peer(xxpc_object_t peer) { xxpc_connection_resume(peer); } -/* This is a daemon contacted by all processes which can load extensions. It - * currently does the work of reading the plists in - * /Library/Substitute/DynamicLibraries in order to avoid loading objc/CF - * libraries into the target binary (unless actually required by loaded - * libraries). In the future it will help with hot loading. */ - int main() { + install_deadlock_warning(); xxpc_connection_t listener = xxpc_connection_create_mach_service( "com.ex.substituted", NULL, XXPC_CONNECTION_MACH_SERVICE_LISTENER); if (!listener) { diff --git a/lib/hook-functions.c b/lib/hook-functions.c index 673d6d9..ee3d049 100644 --- a/lib/hook-functions.c +++ b/lib/hook-functions.c @@ -213,8 +213,8 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, /* Generate the rewritten start of the function for the outro * trampoline (complaining if any bad instructions are found) - * (on arm64, this modifies regs_possibly_written, which is used by the - * ending make_jump_patch call) */ + * (on arm64, this modifies arch.regs_possibly_written, which is used + * by the later make_jump_patch call) */ if ((ret = transform_dis_main(code, &trampoline_ptr, pc_patch_start, &pc_patch_end, (uintptr_t) trampoline_ptr, &arch, hi->offset_by_pcdiff, diff --git a/lib/jump-dis.c b/lib/jump-dis.c index f909cc7..04a919e 100644 --- a/lib/jump-dis.c +++ b/lib/jump-dis.c @@ -121,7 +121,8 @@ void jump_dis_thumb_it(UNUSED struct jump_dis_ctx *ctx) { static void jump_dis_dis(struct jump_dis_ctx *ctx); -bool jump_dis_main(void *code_ptr, uint_tptr pc_patch_start, uint_tptr pc_patch_end, +bool jump_dis_main(void *code_ptr, uint_tptr pc_patch_start, + uint_tptr pc_patch_end, struct arch_dis_ctx initial_dis_ctx) { bool ret; struct jump_dis_ctx ctx; diff --git a/lib/substitute.h b/lib/substitute.h index f75aa82..6b7b9f4 100644 --- a/lib/substitute.h +++ b/lib/substitute.h @@ -124,7 +124,7 @@ enum { * other similar library which cares about atomicity, noticing the same * concern, would independently come up with the same restriction - at least, * if they do not find an easier method to avoid deadlocks. Note that all - * existing hooking libraries I know of do not attempt to do any + * existing hooking libraries I know of make no attempt to do any * synchronization at all; this is fine if hooking is only done during * initialization while the process is single threaded, but I want to properly * support dynamic injection. (Note - if there is such an easier method on OS @@ -280,7 +280,7 @@ int substitute_interpose_imports(const struct substitute_image *handle, * @old_ptr optional - out pointer to the 'old implementation'. * If there is no old implementation, a custom IMP is * returned that delegates to the superclass. This IMP can - * be freed if desired with imp_removeBlock. + * be freed if desired with substitute_free_created_imp. * @created_imp_ptr optional - out pointer to whether a fake superclass-call * IMP has been placed in * -- cgit v1.2.3