diff options
Diffstat (limited to '')
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | darwin-bootstrap/com.ex.substituted.plist | 5 | ||||
-rw-r--r-- | darwin-bootstrap/substituted.m | 38 | ||||
-rw-r--r-- | lib/hook-functions.c | 4 | ||||
-rw-r--r-- | lib/jump-dis.c | 3 | ||||
-rw-r--r-- | lib/substitute.h | 4 |
6 files changed, 44 insertions, 12 deletions
@@ -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 @@ <string>com.ex.substituted</string> <key>Program</key> <string>/Library/Substitute/Helpers/substituted</string> + <key>EnvironmentVariables</key> + <dict> + <key>_MSSafeMode</key> + <string>1</string> + </dict> </dict> </plist> 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 <Foundation/Foundation.h> #import <CoreFoundation/CoreFoundation.h> #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 <old_ptr> * |