diff --git a/TrollStore/TSAppInfo.m b/TrollStore/TSAppInfo.m index bc77c88..714dcbd 100644 --- a/TrollStore/TSAppInfo.m +++ b/TrollStore/TSAppInfo.m @@ -1,4 +1,5 @@ #import "TSAppInfo.h" +#import "TSCommonTCCServiceNames.h" #import extern CGImageRef LICreateIconForImage(CGImageRef image, int variant, int precomposed); @@ -858,7 +859,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); } }]; - __block NSMutableArray* accessibleContainers = [NSMutableArray new]; + __block NSMutableSet* accessibleContainers = [NSMutableSet new]; if(!unrestrictedContainerAccess) { [self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) { @@ -898,7 +899,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); // keychain-access-groups // Unrestricted if single * (maybe?) __block BOOL unrestrictedKeychainAccess = NO; - __block NSMutableArray* accessibleKeychainGroups = [NSMutableArray new]; + __block NSMutableSet* accessibleKeychainGroups = [NSMutableSet new]; [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) { if([key isEqualToString:@"keychain-access-groups"]) { @@ -923,7 +924,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); } }]; - __block NSMutableArray* URLSchemes = [NSMutableArray new]; + __block NSMutableSet* URLSchemes = [NSMutableSet new]; [self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) { if([key isEqualToString:@"CFBundleURLTypes"]) { @@ -950,6 +951,61 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); } } }]; + + __block NSMutableSet* allowedTccServices = [NSMutableSet new]; + [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) { + if([key isEqualToString:@"com.apple.private.tcc.allow"]) + { + NSArray* valueArr = (NSArray*)value; + if([valueArr isKindOfClass:NSArray.class]) + { + for(NSString* serviceID in valueArr) + { + if([serviceID isKindOfClass:NSString.class]) + { + NSString* displayName = commonTCCServices[serviceID]; + if(displayName == nil) + { + [allowedTccServices addObject:[serviceID stringByReplacingOccurrencesOfString:@"kTCCService" withString:@""]]; + } + else + { + [allowedTccServices addObject:displayName]; + } + } + } + } + } + else if ([key isEqualToString:@"com.apple.locationd.preauthorized"]) + { + NSNumber* valueNum = (NSNumber*)value; + if([valueNum isKindOfClass:NSNumber.class]) + { + if([valueNum boolValue]) + { + [allowedTccServices addObject:@"Location"]; + } + } + } + }]; + + __block NSMutableSet* allowedMGKeys = [NSMutableSet new]; + [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) { + if([key isEqualToString:@"com.apple.private.MobileGestalt.AllowedProtectedKeys"]) + { + NSArray* valueArr = (NSArray*)value; + if([valueArr isKindOfClass:NSArray.class]) + { + for(NSString* protectedKey in valueArr) + { + if([protectedKey isKindOfClass:NSString.class]) + { + [allowedMGKeys addObject:protectedKey]; + } + } + } + } + }]; NSMutableParagraphStyle* leftAlignment = [[NSMutableParagraphStyle alloc] init]; leftAlignment.alignment = NSTextAlignmentLeft; @@ -1036,6 +1092,20 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can not spawn other binaries." attributes:bodyAttributes]]; } + if(allowedTccServices.count) + { + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nPrivacy" attributes:headerAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access the following services without asking for permission.\n" attributes:bodyDangerAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedTccServices allObjects]] attributes:bodyAttributes]]; + } + + if (allowedMGKeys.count) + { + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nDevice Info" attributes:headerAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access protected information about this device.\n" attributes:bodyWarningAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedMGKeys allObjects]] attributes:bodyAttributes]]; + } + if(unrestrictedContainerAccess || accessibleContainers.count) { [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nAccessible Containers" attributes:headerAttributes]]; diff --git a/TrollStore/TSAppTableViewController.m b/TrollStore/TSAppTableViewController.m index d82498e..89e25fb 100644 --- a/TrollStore/TSAppTableViewController.m +++ b/TrollStore/TSAppTableViewController.m @@ -102,6 +102,7 @@ UIImage* imageWithSize(UIImage* image, CGSize size) [super viewDidLoad]; self.tableView.allowsMultipleSelectionDuringEditing = NO; + self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; [self _setUpNavigationBar]; [self _setUpSearchBar]; diff --git a/TrollStore/TSCommonTCCServiceNames.h b/TrollStore/TSCommonTCCServiceNames.h new file mode 100644 index 0000000..9e3b0b2 --- /dev/null +++ b/TrollStore/TSCommonTCCServiceNames.h @@ -0,0 +1,31 @@ +// +// TSCommonTCCServiceNames.h +// IPAInfo +// +// Created by Luke Noble on 30.10.22. +// + +#import + +static NSDictionary* const commonTCCServices = @{ + @"kTCCServicePhotos": @"Photo Library", + @"kTCCServicePhotosAdd": @"Photo Library (Add)", + @"kTCCServiceCamera": @"Camera", + @"kTCCServiceMicrophone": @"Microphone", + @"kTCCServiceAddressBook": @"Contacts", + @"kTCCServiceCalendar": @"Calendars", + @"kTCCServiceReminders": @"Reminders", + @"kTCCServiceWillow": @"HomeKit", + @"kTCCServiceGameCenterFriends": @"Game Center Friends", + @"kTCCServiceExposureNotification": @"Exposure Notifications", + @"kTCCServiceFocusStatus": @"Focus Status", + @"kTCCServiceUserTracking": @"User Tracking", + @"kTCCServiceFaceID": @"Face ID", + @"kTCCServiceMediaLibrary": @"Apple Media Library", + @"kTCCServiceMotion": @"Motion Sensors", + @"kTCCServiceNearbyInteraction": @"Nearby Device Interaction", + @"kTCCServiceBluetoothAlways": @"Bluetooth (Always)", + @"kTCCServiceBluetoothWhileInUse": @"Bluetooth (While In Use)", + @"kTCCServiceBluetoothPeripheral": @"Bluetooth (Peripherals)", + @"kTCCServiceLocation": @"Location" +};