#import #import #include @interface NSObject (topViewController) - (id)topViewController; @end @interface FLEXManager: NSObject +(id)sharedManager; -(void)showExplorer; -(void)showHintsIfNecessary; -(void)_addTVOSGestureRecognizer:(UIViewController *)explorer; @end @interface NSDistributedNotificationCenter : NSNotificationCenter + (id)defaultCenter; - (void)addObserver:(id)arg1 selector:(SEL)arg2 name:(id)arg3 object:(id)arg4; - (void)postNotificationName:(id)arg1 object:(id)arg2 userInfo:(id)arg3; @end @interface UIWindow (Additions) - (UIViewController *)visibleViewController; @end @interface NSObject (Additions) - (UIViewController *)topViewController; @end @implementation UIWindow (Additions) - (UIViewController *)visibleViewController { UIViewController *rootViewController = self.rootViewController; return [UIWindow getVisibleViewControllerFrom:rootViewController]; } + (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [UIWindow getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [UIWindow getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]]; } else { if (vc.presentedViewController) { return [UIWindow getVisibleViewControllerFrom:vc.presentedViewController]; } else { return vc; } } } @end @interface LSApplicationProxy: NSObject +(id)applicationProxyForIdentifier:(id)sender; +(id)tv_applicationFlatIcon; -(BOOL)isContainerized; @end @implementation NSObject (Additions) - (UIViewController *)topViewController { return [[[UIApplication sharedApplication] keyWindow] visibleViewController]; } @end static void sendNotification(NSString *title, NSString *message, UIImage *image) { NSMutableDictionary *dict = [NSMutableDictionary new]; dict[@"message"] = message; dict[@"title"] = title; dict[@"timeout"] = [NSNumber numberWithInteger:4]; if (image){ NSData *imageData = UIImagePNGRepresentation(image); if (imageData){ dict[@"imageData"] = imageData; } } [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.nito.bulletinh4x/displayBulletin" object:nil userInfo:dict]; } __attribute__ ((constructor)) static void FLEXInjected_main() { NSBundle *bundle = [NSBundle mainBundle]; NSString *bundleID = [bundle bundleIdentifier]; NSDictionary *ourDict = [[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.nito.flexinjected.plist"]; NSArray *iconBlacklist = @[@"com.apple.PineBoard", @"com.apple.HeadBoard"]; NSNumber *value = [ourDict objectForKey:bundleID]; if ([value boolValue] == YES) { BOOL sendAlert = true; id prox = [%c(LSApplicationProxy) applicationProxyForIdentifier:bundleID]; UIImage *icon = nil; if (prox){ NSLog(@"[FLEXInjected] found prox: %@", prox); if ([prox isContainerized]){ icon = nil; } else { if ([prox respondsToSelector:@selector(tv_applicationFlatIcon)] && ![iconBlacklist containsObject:bundleID]){ icon = [prox tv_applicationFlatIcon]; } } } else { //no prox found NSString *mcsPath = @"/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices"; [[NSBundle bundleWithPath:mcsPath] load]; prox = [%c(LSApplicationProxy) applicationProxyForIdentifier:bundleID]; if ([prox isContainerized]){ icon = nil; } else { if ([prox respondsToSelector:@selector(tv_applicationFlatIcon)] && ![iconBlacklist containsObject:bundleID]){ icon = [prox tv_applicationFlatIcon]; } } } NSLog(@"[FLEXInjected] found icon: %@", icon); if (sendAlert){ NSString *message = [NSString stringWithFormat:@"Injected into bundle: %@", bundleID]; sendNotification(@"FLEXInjected", message, icon); NSLog(@"[FLEXInjected) bundle ID %@", bundleID); } NSLog(@"[FLEXInjected] post send alert"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"[FLEXInjected] weouchea..."); NSString *p = @"/Library/Frameworks/FLEX.framework"; NSBundle *bundle = [NSBundle bundleWithPath:p]; [bundle load]; id flexManager = [%c(FLEXManager) sharedManager]; UIViewController *tvc = [[UIApplication sharedApplication] topViewController]; if([tvc respondsToSelector: @selector(tabBarController)]){ UITabBarController *tabBar = [tvc tabBarController]; if (tabBar) tvc = tabBar; } NSLog(@"[FLEXInjected] top view controller: %@ violated...", tvc); [flexManager _addTVOSGestureRecognizer:tvc]; [flexManager showExplorer]; if ([flexManager respondsToSelector:@selector(showHintsIfNecessary)]){ [flexManager showHintsIfNecessary]; } }); } }