diff options
author | comex | 2015-07-13 17:08:55 -0400 |
---|---|---|
committer | comex | 2015-07-13 17:08:55 -0400 |
commit | d52241cfc8b1e1a5ed602fedfe9d11b4653c96cf (patch) | |
tree | fedd5df8cc9dfdd35b22114e737a24939c3c2027 /darwin-bootstrap | |
parent | be beta (diff) | |
download | substitute-d52241cfc8b1e1a5ed602fedfe9d11b4653c96cf.tar.gz |
hook up the list of dylibs
Diffstat (limited to 'darwin-bootstrap')
-rw-r--r-- | darwin-bootstrap/bundle-loader.c | 50 | ||||
-rw-r--r-- | darwin-bootstrap/posixspawn-hook.c | 5 | ||||
-rw-r--r-- | darwin-bootstrap/safemode-ui-hook.m | 4 | ||||
-rw-r--r-- | darwin-bootstrap/safety-dance/main.m | 76 | ||||
-rw-r--r-- | darwin-bootstrap/substituted.m | 51 |
5 files changed, 174 insertions, 12 deletions
diff --git a/darwin-bootstrap/bundle-loader.c b/darwin-bootstrap/bundle-loader.c index 7a90414..3b29b55 100644 --- a/darwin-bootstrap/bundle-loader.c +++ b/darwin-bootstrap/bundle-loader.c @@ -3,10 +3,12 @@ #include "ib-log.h" #include "darwin/mach-decls.h" #include "darwin/xxpc.h" +#include "substitute-internal.h" #include <dlfcn.h> #include <mach/mach.h> #include <mach/mach_time.h> #include <mach/mig.h> +#include <mach-o/loader.h> #include <objc/runtime.h> #include <CoreFoundation/CoreFoundation.h> #include <syslog.h> @@ -146,12 +148,60 @@ do_load:; return true; } +static void notify_added_removed(const struct mach_header *mh32, bool is_add) { + char id_dylib_buf[32]; + const char *id_dylib; + + const mach_header_x *mh = (void *) mh32; + uint32_t ncmds = mh->ncmds; + const struct load_command *lc = (void *) (mh + 1); + for (uint32_t i = 0; i < ncmds; i++) { + if (lc->cmd == LC_ID_DYLIB) { + const struct dylib_command *dc = (void *) lc; + id_dylib = (const char *) dc + dc->dylib.name.offset; + goto ok; + } + lc = (void *) lc + lc->cmdsize; + } + /* no name? */ + sprintf(id_dylib_buf, "unknown.%p", mh32); + id_dylib = id_dylib_buf; + +ok:; + xxpc_object_t message = xxpc_dictionary_create(NULL, NULL, 0); + xxpc_dictionary_set_string(message, "type", "add-remove"); + xxpc_dictionary_set_bool(message, "is-add", is_add); + xxpc_dictionary_set_string(message, "id-dylib", id_dylib); + xxpc_connection_send_message(substituted_conn, message); + xxpc_release(message); +} + +static void add_image_cb(const struct mach_header *mh, intptr_t vmaddr_slide) { + notify_added_removed(mh, true); + +} + +static void remove_image_cb(const struct mach_header *mh, intptr_t vmaddr_slide) { + notify_added_removed(mh, false); +} + static bool handle_hello_reply(xxpc_object_t dict) { if (IB_VERBOSE) { char *desc = xxpc_copy_description(dict); ib_log("hello_reply: %s", desc); free(desc); } + bool notify = xxpc_dictionary_get_bool(dict, "notify-me-of-add-remove"); + if (notify) { + _dyld_register_func_for_add_image(add_image_cb); + _dyld_register_func_for_remove_image(remove_image_cb); + + for (uint32_t i = 0, count = _dyld_image_count(); i < count; i++) { + const struct mach_header *mh32 = _dyld_get_image_header(i); + if (mh32) + notify_added_removed(mh32, true); + } + } xxpc_object_t bundles = xxpc_dictionary_get_value(dict, "bundles"); if (!bundles || xxpc_get_type(bundles) != XXPC_TYPE_ARRAY) return false; diff --git a/darwin-bootstrap/posixspawn-hook.c b/darwin-bootstrap/posixspawn-hook.c index 50c4ca9..893cfee 100644 --- a/darwin-bootstrap/posixspawn-hook.c +++ b/darwin-bootstrap/posixspawn-hook.c @@ -170,11 +170,6 @@ end: return ret; } -static const char *xbasename(const char *path) { - const char *slash = strrchr(path, '/'); - return slash ? slash + 1 : path; -} - static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old, pid_t *restrict pidp, const char *restrict path, const posix_spawn_file_actions_t *file_actions, diff --git a/darwin-bootstrap/safemode-ui-hook.m b/darwin-bootstrap/safemode-ui-hook.m index dbae60c..dc505dc 100644 --- a/darwin-bootstrap/safemode-ui-hook.m +++ b/darwin-bootstrap/safemode-ui-hook.m @@ -43,8 +43,10 @@ static bool detect_substrate_safe_mode() { void (*old_applicationDidFinishLaunching)(id, SEL, id); static void my_applicationDidFinishLaunching(id self, SEL sel, id app) { old_applicationDidFinishLaunching(self, sel, app); - if (detect_substrate_safe_mode()) + if (detect_substrate_safe_mode()) { + NSLog(@"Deferring to Substrate's safe mode."); return; + } id controller = [SBApplicationController sharedInstanceIfExists]; if (!controller) { NSLog(@"substitute safe mode: sharedInstanceIfExists => nil!"); diff --git a/darwin-bootstrap/safety-dance/main.m b/darwin-bootstrap/safety-dance/main.m index 64e0e64..8366430 100644 --- a/darwin-bootstrap/safety-dance/main.m +++ b/darwin-bootstrap/safety-dance/main.m @@ -1,6 +1,10 @@ +#include "darwin/xxpc.h" +#include "substitute-internal.h" #import <UIKit/UIKit.h> -#include <notify.h> #import "AutoGrid.h" +#include <notify.h> + +static NSArray *g_dylibs_to_show; @interface UIApplication (Private) - (void)terminateWithSuccess; @@ -23,11 +27,14 @@ - (void)viewDidLoad { [super viewDidLoad]; [self loadStuff]; + /* NSMutableArray *names = [NSMutableArray array]; for (int i = 0; i < 200; i++) [names addObject:[NSString stringWithFormat:@"Some Dylib %d", i]]; + g_dylibs_to_show = names; + */ NSMutableArray *views = [NSMutableArray array]; - for (NSString *name in names) { + for (NSString *name in g_dylibs_to_show) { UILabel *label = [[UILabel alloc] init]; label.text = name; [views addObject:label]; @@ -191,9 +198,72 @@ static void compression(UIView *view, UILayoutPriority pri) { @end +static const char *test_and_transform_id_dylib(const char *id_dylib) { + const char *base = xbasename(id_dylib); + static const char dir1[] = "/Library/MobileSubstrate/DynamicLibraries/"; + static const char dir2[] = "/Library/Substitute/DynamicLibraries/"; + if (!strncmp(id_dylib, dir1, sizeof(dir1) - 1) || + !strncmp(id_dylib, dir2, sizeof(dir2) - 1)) + return base; + char *fn = NULL, *fn2 = NULL; + asprintf(&fn, "%s%s", dir1, base); + asprintf(&fn2, "%s%s", dir2, base); + bool found = !access(fn, F_OK) || !access(fn2, F_OK); + free(fn); + free(fn2); + if (found) + return base; + return NULL; +} + +static void do_bad() { + NSLog(@"problem asking substituted for springboard-fatal-loaded-dylibs..."); + g_dylibs_to_show = @[@"<error>"]; +} + +static void startup() { + xxpc_connection_t conn = xxpc_connection_create_mach_service( + "com.ex.substituted", NULL, 0); + if (!conn) + return do_bad(); + xxpc_connection_set_event_handler(conn, ^(xxpc_object_t event) { + NSLog(@"< %@", event); + }); + xxpc_connection_resume(conn); + xxpc_object_t request = xxpc_dictionary_create(NULL, NULL, 0); + xxpc_dictionary_set_string(request, "type", + "springboard-fatal-loaded-dylibs"); + NSLog(@"asking substituted..."); + xxpc_object_t reply = xxpc_connection_send_message_with_reply_sync( + conn, request); + NSLog(@"done."); + if (!reply || xxpc_get_type(reply) != XXPC_TYPE_DICTIONARY) + return do_bad(); + NS_VALID_UNTIL_END_OF_SCOPE + xxpc_object_t dylibs = xxpc_dictionary_get_value(reply, "dylibs"); + if (!dylibs) { + g_dylibs_to_show = @[@"<unknown>"]; + return; + } + if (xxpc_get_type(dylibs) != XXPC_TYPE_ARRAY) + return do_bad(); + NSMutableArray *ary = [NSMutableArray array]; + for (size_t i = 0, count = xxpc_array_get_count(dylibs); + i < count; i++) { + const char *dylib = xxpc_array_get_string(dylibs, i); + if (!dylib) + return do_bad(); + const char *dylib_to_show = test_and_transform_id_dylib(dylib); + if (dylib_to_show) + [ary addObject:[NSString stringWithCString:dylib_to_show + encoding:NSUTF8StringEncoding]]; + } + g_dylibs_to_show = ary; +} + int main(int argc, char *argv[]) { - NSLog(@"main"); @autoreleasepool { + startup(); return UIApplicationMain(argc, argv, nil, @"AppDelegate"); } } diff --git a/darwin-bootstrap/substituted.m b/darwin-bootstrap/substituted.m index 3dd17a4..f30ab9f 100644 --- a/darwin-bootstrap/substituted.m +++ b/darwin-bootstrap/substituted.m @@ -18,6 +18,9 @@ static enum { REALLY_SAFE, } g_springboard_needs_safe; +static NSSet *g_springboard_loaded_dylibs; +static NSSet *g_springboard_last_loaded_dylibs; + 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); @@ -63,6 +66,7 @@ static xxpc_object_t nsstring_to_xpc(NSString *in) { xxpc_object_t _connection; NSString *_argv0; bool _is_springboard; + NSMutableSet *_loaded_dylibs; } @end @@ -272,12 +276,16 @@ enum convert_filters_ret { _is_springboard = [_argv0 isEqualToString:sb_exe]; - if (_is_springboard) + if (_is_springboard) { + g_springboard_last_loaded_dylibs = g_springboard_loaded_dylibs; + g_springboard_loaded_dylibs = _loaded_dylibs = [NSMutableSet set]; + [self updateSpringBoardNeedsSafeThen:^{ [self handleMessageHelloRest:request]; }]; - else + } else { [self handleMessageHelloRest:request]; + } return; bad: @@ -322,12 +330,45 @@ bad: NSString *dylib_path = [base stringByAppendingPathComponent:dylib]; xxpc_dictionary_set_value(info, "dylib", nsstring_to_xpc(dylib_path)); - xxpc_array_append_value(bundles, info); } xxpc_object_t reply = xxpc_dictionary_create_reply(request); xxpc_dictionary_set_value(reply, "bundles", bundles); + if (_is_springboard) + xxpc_dictionary_set_bool(reply, "notify-me-of-add-remove", true); + xxpc_connection_send_message(_connection, reply); +} + +- (void)handleMessageAddRemove:(NS_VALID_UNTIL_END_OF_SCOPE + xxpc_object_t)request { + bool is_add = xxpc_dictionary_get_bool(request, "is-add"); + const char *id_dylib = xxpc_dictionary_get_string(request, "id-dylib"); + if (!id_dylib || !_loaded_dylibs) + return [self handleBadMessage:request]; + NSString *id_dylib_s = [NSString stringWithCString:id_dylib + encoding:NSUTF8StringEncoding]; + if (is_add) + [_loaded_dylibs addObject:id_dylib_s]; + else + [_loaded_dylibs removeObject:id_dylib_s]; +} + +- (void)handleMessageSBFatalLoadedDylibs:(xxpc_object_t)request { + /* This should probably be secured somehow... */ + NSLog(@"handleMessageSBFatalLoadedDylibs"); + NSSet *set = g_springboard_last_loaded_dylibs; + xxpc_object_t reply = xxpc_dictionary_create_reply(request); + if (set) { + xxpc_object_t dylibs = xxpc_array_create(NULL, 0); + xxpc_dictionary_set_value(reply, "dylibs", dylibs); + for (NSString *dylib in set) { + xxpc_array_set_string(dylibs, XXPC_ARRAY_APPEND, + [dylib cStringUsingEncoding: + NSUTF8StringEncoding]); + + } + } xxpc_connection_send_message(_connection, reply); } @@ -342,6 +383,10 @@ bad: goto bad; if (!strcmp(type, "hello")) return [self handleMessageHello:request]; + else if (!strcmp(type, "add-remove")) + return [self handleMessageAddRemove:request]; + else if (!strcmp(type, "springboard-fatal-loaded-dylibs")) + return [self handleMessageSBFatalLoadedDylibs:request]; else goto bad; bad: |