Search code examples
objective-cios7hookjailbreaktheos

(iOS, TheOS) %hook into global app function


I am looking for a global function for apps in iOS 7.

More specifically, I want to injected code into the app(s) upon launch, which will only effect the app, and not the SpringBoard.

I have tried a couple of things but they only affect the SpringBoard:

%hook SBApplicationIcon
    - (id)application {
        return %orig;
    }
    - (id)initWithApplication:(id)arg1 {
        return %orig;
    }
%end

%hook SBApplicationController
    - (id)init {
         return %orig;
    }
%end

%hook SBUIController
    - (void)launchIcon:(id)arg1 fromLocation:(int)arg2 {
        %orig;
    }
    - (id)contentView {
        return %orig;
    }
%end

%hook SBApplication
    - (void)didLaunch:(id)arg1 {
        %orig;
    }
%end

These are just a couple of examples of functions I've tried.

I suspect the filter needs to be changed as well, but that depends on where the function is located ofc (com.apple.springboard is set atm).

I was received a tip to set the filter to *, but that doesn't do me much good if I don't know what function to %hook.

Please explain your answer if possible.


Solution

  • There is a workaround using NSDistributedNotificationCenter which will do what you want.

    First of all, you need to set your filter to com.apple.UIKit so your dynamic library get's hooked into all processes.

    Then create a Class (.h and .m file) and lets name it GlobalFunction:

    GlobalFunction.h file

    @interface GlobalFunction: NSObject
    @end
    

    GlobalFunction.m file

    #import "GlobalFunction.h"
    
    @implementation GlobalFunction
    - (id)init {
        self = [super init];
    
        if (self) {
            [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(globalNotificationReceived:) name:@"info.ilendemli.globalNotification" object:nil];
        }
    
        return self;
    }
    
    - (void)globalNotificationReceived:(NSNotification *)notification {
        NSLog(@"Notification Received");
    }
    @end
    

    and in your Tweak.xm do the following:

    #import "GlobalFunction.h"
    
    %hook SpringBoard
    - (void)applicationDidFinishLaunching:(id)application {
        %orig;
        [GlobalFunction new];
    }
    %end
    

    so the Class gets initialized when SpringBoard loads up. Then use:

    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"info.ilendemli.globalNotification" object:nil];
    

    to post a notification so the method gets called.

    I haven't tested this but it should work, and it's similar to something i made before, which works great.

    Edit #1:

    To execute the method on app-launch add the following in your Tweak.xm file:

    static NSArray *blackList = @[ @"MailAppController", @"SpringBoard", @"FBWildeApplication" ];
    
    %hook UIApplication
    
    - (void)_run {
        NSString *classString = NSStringFromClass([self class]);
    
        if (![blackList containsObject:classString]) {
            [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"info.ilendemli.globalNotification" object:nil];
        }
    
        %orig;
    }
    
    %end
    

    Edit #2:

    Edited the post to remove %ctor, because that probably wouldn't work. Added alternative approach by hooking SpringBoard and initializing the Class there.