aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--darwin-bootstrap/com.ex.substituted.plist5
-rw-r--r--darwin-bootstrap/substituted.m38
-rw-r--r--lib/hook-functions.c4
-rw-r--r--lib/jump-dis.c3
-rw-r--r--lib/substitute.h4
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 @@
<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>
*