#import #import #import #define YT_BUNDLE_ID @"com.google.ios.youtube" #define YT_NAME @"YouTube" @interface SSOConfiguration : NSObject @end %group gSideloading // Keychain patching static NSString *accessGroupID() { NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass, @"bundleSeedID", kSecAttrAccount, @"", kSecAttrService, (id)kCFBooleanTrue, kSecReturnAttributes, nil]; CFDictionaryRef result = nil; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); if (status == errSecItemNotFound) status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); if (status != errSecSuccess) return nil; NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; return accessGroup; } // IAmYouTube (https://github.com/PoomSmart/IAmYouTube/) %hook YTVersionUtils + (NSString *)appName { return YT_NAME; } + (NSString *)appID { return YT_BUNDLE_ID; } %end %hook GCKBUtils + (NSString *)appIdentifier { return YT_BUNDLE_ID; } %end %hook GPCDeviceInfo + (NSString *)bundleId { return YT_BUNDLE_ID; } %end %hook OGLBundle + (NSString *)shortAppName { return YT_NAME; } %end %hook GVROverlayView + (NSString *)appName { return YT_NAME; } %end %hook OGLPhenotypeFlagServiceImpl - (NSString *)bundleId { return YT_BUNDLE_ID; } %end %hook APMAEU + (BOOL)isFAS { return YES; } %end %hook GULAppEnvironmentUtil + (BOOL)isFromAppStore { return YES; } %end %hook SSOConfiguration - (id)initWithClientID:(id)clientID supportedAccountServices:(id)supportedAccountServices { self = %orig; [self setValue:YT_NAME forKey:@"_shortAppName"]; [self setValue:YT_BUNDLE_ID forKey:@"_applicationIdentifier"]; return self; } %end %hook NSBundle - (NSString *)bundleIdentifier { NSArray *address = [NSThread callStackReturnAddresses]; Dl_info info = {0}; if (dladdr((void *)[address[2] longLongValue], &info) == 0) return %orig; NSString *path = [NSString stringWithUTF8String:info.dli_fname]; if ([path hasPrefix:NSBundle.mainBundle.bundlePath]) return YT_BUNDLE_ID; return %orig; } - (id)objectForInfoDictionaryKey:(NSString *)key { if ([key isEqualToString:@"CFBundleIdentifier"]) return YT_BUNDLE_ID; if ([key isEqualToString:@"CFBundleDisplayName"] || [key isEqualToString:@"CFBundleName"]) return YT_NAME; return %orig; } // Fix Google Sign in by @PoomSmart and @level3tjg (qnblackcat/uYouPlus#684) - (NSDictionary *)infoDictionary { NSMutableDictionary *info = %orig.mutableCopy; NSString *altBundleIdentifier = info[@"ALTBundleIdentifier"]; if (altBundleIdentifier) info[@"CFBundleIdentifier"] = altBundleIdentifier; return info; } %end // Fix login for YouTube 18.13.2 and higher %hook SSOKeychainHelper + (NSString *)accessGroup { return accessGroupID(); } + (NSString *)sharedAccessGroup { return accessGroupID(); } %end // Fix login for YouTube 17.33.2 and higher %hook SSOKeychainCore + (NSString *)accessGroup { return accessGroupID(); } + (NSString *)sharedAccessGroup { return accessGroupID(); } %end // Fix App Group Directory by moving it to documents directory %hook NSFileManager - (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier { if (groupIdentifier != nil) { NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; NSURL *documentsURL = [paths lastObject]; return [documentsURL URLByAppendingPathComponent:@"AppGroup"]; } return %orig(groupIdentifier); } %end %end %ctor { NSString *embeddedMobileProvisionPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]; if ([[NSFileManager defaultManager] fileExistsAtPath:embeddedMobileProvisionPath]) %init(gSideloading); }