1.1
Fix icons not showing up for some users app crashing on launch, app crashing when going to share files
37
LSApplicationProxy+AltList.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#import <MobileCoreServices/LSApplicationProxy.h>
|
||||||
|
#import <MobileCoreServices/LSApplicationWorkspace.h>
|
||||||
|
|
||||||
|
@interface LSApplicationRecord : NSObject
|
||||||
|
@property (nonatomic,readonly) NSArray* appTags; // 'hidden'
|
||||||
|
@property (getter=isLaunchProhibited,readonly) BOOL launchProhibited;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationProxy (Additions)
|
||||||
|
@property (readonly, nonatomic) NSString *shortVersionString;
|
||||||
|
@property (nonatomic,readonly) NSString* localizedName;
|
||||||
|
@property (nonatomic,readonly) NSString* applicationType; // (User/System)
|
||||||
|
@property (nonatomic,readonly) NSArray* appTags; // 'hidden'
|
||||||
|
@property (getter=isLaunchProhibited,nonatomic,readonly) BOOL launchProhibited;
|
||||||
|
+ (instancetype)applicationProxyForIdentifier:(NSString*)identifier;
|
||||||
|
- (LSApplicationRecord*)correspondingApplicationRecord;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationWorkspace (Additions)
|
||||||
|
- (void)addObserver:(id)arg1;
|
||||||
|
- (void)removeObserver:(id)arg1;
|
||||||
|
- (void)enumerateApplicationsOfType:(NSUInteger)type block:(void (^)(LSApplicationProxy*))block;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationProxy (AltList)
|
||||||
|
- (BOOL)atl_isSystemApplication;
|
||||||
|
- (BOOL)atl_isUserApplication;
|
||||||
|
- (BOOL)atl_isHidden;
|
||||||
|
- (NSString*)atl_fastDisplayName;
|
||||||
|
- (NSString*)atl_nameToDisplay;
|
||||||
|
- (NSString*)atl_shortVersionString;
|
||||||
|
@property (nonatomic,readonly) NSString* atl_bundleIdentifier;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface LSApplicationWorkspace (AltList)
|
||||||
|
- (NSArray*)atl_allInstalledApplications;
|
||||||
|
@end
|
||||||
183
LSApplicationProxy+AltList.m
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "LSApplicationProxy+AltList.h"
|
||||||
|
|
||||||
|
@implementation LSApplicationProxy (AltList)
|
||||||
|
|
||||||
|
- (BOOL)atl_isSystemApplication
|
||||||
|
{
|
||||||
|
return [self.applicationType isEqualToString:@"System"] && ![self atl_isHidden];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)atl_isUserApplication
|
||||||
|
{
|
||||||
|
return [self.applicationType isEqualToString:@"User"] && ![self atl_isHidden];
|
||||||
|
}
|
||||||
|
|
||||||
|
// the tag " hidden " is also valid, so we need to check if any strings contain "hidden" instead
|
||||||
|
BOOL tagArrayContainsTag(NSArray* tagArr, NSString* tag)
|
||||||
|
{
|
||||||
|
if(!tagArr || !tag) return NO;
|
||||||
|
|
||||||
|
__block BOOL found = NO;
|
||||||
|
|
||||||
|
[tagArr enumerateObjectsUsingBlock:^(NSString* tagToCheck, NSUInteger idx, BOOL* stop)
|
||||||
|
{
|
||||||
|
if(![tagToCheck isKindOfClass:[NSString class]])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if([tagToCheck rangeOfString:tag options:0].location != NSNotFound)
|
||||||
|
{
|
||||||
|
found = YES;
|
||||||
|
*stop = YES;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
// always returns NO on iOS 7
|
||||||
|
- (BOOL)atl_isHidden
|
||||||
|
{
|
||||||
|
NSArray* appTags;
|
||||||
|
NSArray* recordAppTags;
|
||||||
|
NSArray* sbAppTags;
|
||||||
|
|
||||||
|
BOOL launchProhibited = NO;
|
||||||
|
|
||||||
|
if([self respondsToSelector:@selector(correspondingApplicationRecord)])
|
||||||
|
{
|
||||||
|
// On iOS 14, self.appTags is always empty but the application record still has the correct ones
|
||||||
|
LSApplicationRecord* record = [self correspondingApplicationRecord];
|
||||||
|
recordAppTags = record.appTags;
|
||||||
|
launchProhibited = record.launchProhibited;
|
||||||
|
}
|
||||||
|
if([self respondsToSelector:@selector(appTags)])
|
||||||
|
{
|
||||||
|
appTags = self.appTags;
|
||||||
|
}
|
||||||
|
if(!launchProhibited && [self respondsToSelector:@selector(isLaunchProhibited)])
|
||||||
|
{
|
||||||
|
launchProhibited = self.launchProhibited;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSURL* bundleURL = self.bundleURL;
|
||||||
|
if(bundleURL && [bundleURL checkResourceIsReachableAndReturnError:nil])
|
||||||
|
{
|
||||||
|
NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
|
||||||
|
sbAppTags = [bundle objectForInfoDictionaryKey:@"SBAppTags"];
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL isWebApplication = ([self.atl_bundleIdentifier rangeOfString:@"com.apple.webapp" options:NSCaseInsensitiveSearch].location != NSNotFound);
|
||||||
|
return tagArrayContainsTag(appTags, @"hidden") || tagArrayContainsTag(recordAppTags, @"hidden") || tagArrayContainsTag(sbAppTags, @"hidden") || isWebApplication || launchProhibited;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getting the display name is slow (up to 2ms) because it uses an IPC call
|
||||||
|
// this stacks up if you do it for every single application
|
||||||
|
// This method provides a faster way (around 0.5ms) to get the display name
|
||||||
|
// This reduces the overall time needed to sort the applications from ~230 to ~120ms on my test device
|
||||||
|
- (NSString*)atl_fastDisplayName
|
||||||
|
{
|
||||||
|
NSString* cachedDisplayName = [self valueForKey:@"_localizedName"];
|
||||||
|
if(cachedDisplayName && ![cachedDisplayName isEqualToString:@""])
|
||||||
|
{
|
||||||
|
return cachedDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* localizedName;
|
||||||
|
|
||||||
|
NSURL* bundleURL = self.bundleURL;
|
||||||
|
if(!bundleURL || ![bundleURL checkResourceIsReachableAndReturnError:nil])
|
||||||
|
{
|
||||||
|
localizedName = self.localizedName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
|
||||||
|
|
||||||
|
localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
|
||||||
|
if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
|
||||||
|
if(!localizedName || [localizedName isEqualToString:@""])
|
||||||
|
{
|
||||||
|
localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
|
||||||
|
if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
|
||||||
|
if(!localizedName || [localizedName isEqualToString:@""])
|
||||||
|
{
|
||||||
|
localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleExecutable"];
|
||||||
|
if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
|
||||||
|
if(!localizedName || [localizedName isEqualToString:@""])
|
||||||
|
{
|
||||||
|
//last possible fallback: use slow IPC call
|
||||||
|
localizedName = self.localizedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self setValue:localizedName forKey:@"_localizedName"];
|
||||||
|
return localizedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*)atl_nameToDisplay
|
||||||
|
{
|
||||||
|
NSString* localizedName = [self atl_fastDisplayName];
|
||||||
|
|
||||||
|
if([self.atl_bundleIdentifier rangeOfString:@"carplay" options:NSCaseInsensitiveSearch].location != NSNotFound)
|
||||||
|
{
|
||||||
|
if([localizedName rangeOfString:@"carplay" options:NSCaseInsensitiveSearch range:NSMakeRange(0, localizedName.length) locale:[NSLocale currentLocale]].location == NSNotFound)
|
||||||
|
{
|
||||||
|
return [localizedName stringByAppendingString:@" (CarPlay)"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return localizedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)atl_bundleIdentifier
|
||||||
|
{
|
||||||
|
// iOS 8-14
|
||||||
|
if([self respondsToSelector:@selector(bundleIdentifier)])
|
||||||
|
{
|
||||||
|
return [self bundleIdentifier];
|
||||||
|
}
|
||||||
|
// iOS 7
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return [self applicationIdentifier];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)atl_shortVersionString {
|
||||||
|
NSString *version = self.shortVersionString;
|
||||||
|
if (version == nil || [version isEqualToString:@""]) {
|
||||||
|
version = @"1.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation LSApplicationWorkspace (AltList)
|
||||||
|
|
||||||
|
- (NSArray*)atl_allInstalledApplications
|
||||||
|
{
|
||||||
|
if(![self respondsToSelector:@selector(enumerateApplicationsOfType:block:)])
|
||||||
|
{
|
||||||
|
return [self allInstalledApplications];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableArray* installedApplications = [NSMutableArray new];
|
||||||
|
[self enumerateApplicationsOfType:0 block:^(LSApplicationProxy* appProxy)
|
||||||
|
{
|
||||||
|
[installedApplications addObject:appProxy];
|
||||||
|
}];
|
||||||
|
[self enumerateApplicationsOfType:1 block:^(LSApplicationProxy* appProxy)
|
||||||
|
{
|
||||||
|
[installedApplications addObject:appProxy];
|
||||||
|
}];
|
||||||
|
return installedApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
4
Makefile
@@ -9,7 +9,7 @@ include $(THEOS)/makefiles/common.mk
|
|||||||
APPLICATION_NAME = TrollDecrypt
|
APPLICATION_NAME = TrollDecrypt
|
||||||
|
|
||||||
TrollDecrypt_FILES = SSZipArchive/minizip/unzip.c SSZipArchive/minizip/crypt.c SSZipArchive/minizip/ioapi_buf.c SSZipArchive/minizip/ioapi_mem.c SSZipArchive/minizip/ioapi.c SSZipArchive/minizip/minishared.c SSZipArchive/minizip/zip.c SSZipArchive/minizip/aes/aes_ni.c SSZipArchive/minizip/aes/aescrypt.c SSZipArchive/minizip/aes/aeskey.c SSZipArchive/minizip/aes/aestab.c SSZipArchive/minizip/aes/fileenc.c SSZipArchive/minizip/aes/hmac.c SSZipArchive/minizip/aes/prng.c SSZipArchive/minizip/aes/pwd2key.c SSZipArchive/minizip/aes/sha1.c SSZipArchive/SSZipArchive.m
|
TrollDecrypt_FILES = SSZipArchive/minizip/unzip.c SSZipArchive/minizip/crypt.c SSZipArchive/minizip/ioapi_buf.c SSZipArchive/minizip/ioapi_mem.c SSZipArchive/minizip/ioapi.c SSZipArchive/minizip/minishared.c SSZipArchive/minizip/zip.c SSZipArchive/minizip/aes/aes_ni.c SSZipArchive/minizip/aes/aescrypt.c SSZipArchive/minizip/aes/aeskey.c SSZipArchive/minizip/aes/aestab.c SSZipArchive/minizip/aes/fileenc.c SSZipArchive/minizip/aes/hmac.c SSZipArchive/minizip/aes/prng.c SSZipArchive/minizip/aes/pwd2key.c SSZipArchive/minizip/aes/sha1.c SSZipArchive/SSZipArchive.m
|
||||||
TrollDecrypt_FILES += main.m TDAppDelegate.m TDRootViewController.m TDDumpDecrypted.m TDUtils.m TDFileManagerViewController.m
|
TrollDecrypt_FILES += main.m TDAppDelegate.m TDRootViewController.m TDDumpDecrypted.m TDUtils.m TDFileManagerViewController.m LSApplicationProxy+AltList.m
|
||||||
TrollDecrypt_FRAMEWORKS = UIKit CoreGraphics MobileCoreServices
|
TrollDecrypt_FRAMEWORKS = UIKit CoreGraphics MobileCoreServices
|
||||||
TrollDecrypt_CFLAGS = -fobjc-arc
|
TrollDecrypt_CFLAGS = -fobjc-arc
|
||||||
TrollDecrypt_CODESIGN_FLAGS = -Sentitlements.plist
|
TrollDecrypt_CODESIGN_FLAGS = -Sentitlements.plist
|
||||||
@@ -22,4 +22,4 @@ after-stage::
|
|||||||
ldid -Sentitlements.plist $(THEOS_STAGING_DIR)/Applications/TrollDecrypt.app/TrollDecrypt
|
ldid -Sentitlements.plist $(THEOS_STAGING_DIR)/Applications/TrollDecrypt.app/TrollDecrypt
|
||||||
cp -a $(THEOS_STAGING_DIR)/Applications/* $(THEOS_STAGING_DIR)/Payload
|
cp -a $(THEOS_STAGING_DIR)/Applications/* $(THEOS_STAGING_DIR)/Payload
|
||||||
mv $(THEOS_STAGING_DIR)/Payload .
|
mv $(THEOS_STAGING_DIR)/Payload .
|
||||||
zip -q -r TrollDecrypt.ipa Payload
|
zip -q -r TrollDecrypt.tipa Payload
|
||||||
|
|||||||
@@ -19,4 +19,5 @@ make package
|
|||||||
- [TrollDecryptor](https://github.com/wh1te4ever/TrollDecryptor) by wh1te4ever
|
- [TrollDecryptor](https://github.com/wh1te4ever/TrollDecryptor) by wh1te4ever
|
||||||
- [dumpdecrypted](https://github.com/stefanesser/dumpdecrypted) by Stefan Esser
|
- [dumpdecrypted](https://github.com/stefanesser/dumpdecrypted) by Stefan Esser
|
||||||
- [bfdecrypt](https://github.com/BishopFox/bfdecrypt) by BishopFox
|
- [bfdecrypt](https://github.com/BishopFox/bfdecrypt) by BishopFox
|
||||||
- App Icon by super.user
|
- [opa334](https://github.com/opa334) for some pieces of code
|
||||||
|
- App Icon by super.user
|
||||||
BIN
Resources/AppIcon-1024.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
Resources/AppIcon-20.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Resources/AppIcon-20@2x.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Resources/AppIcon-20@3x.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
Resources/AppIcon-29.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
Resources/AppIcon-29@2x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
Resources/AppIcon-29@3x.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
Resources/AppIcon-40.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Resources/AppIcon-40@2x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
Resources/AppIcon-40@3x.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
Resources/AppIcon-60@2x.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
Resources/AppIcon-60@3x.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Resources/AppIcon-76.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
Resources/AppIcon-76@2x.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
Resources/AppIcon-83.5@2x.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
@@ -10,7 +10,10 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleIconFiles</key>
|
<key>CFBundleIconFiles</key>
|
||||||
<array>
|
<array>
|
||||||
<string>AppIcon60x60</string>
|
<string>AppIcon-29</string>
|
||||||
|
<string>AppIcon-40</string>
|
||||||
|
<string>AppIcon-57</string>
|
||||||
|
<string>AppIcon-60</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIPrerenderedIcon</key>
|
<key>UIPrerenderedIcon</key>
|
||||||
<true/>
|
<true/>
|
||||||
@@ -22,8 +25,13 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleIconFiles</key>
|
<key>CFBundleIconFiles</key>
|
||||||
<array>
|
<array>
|
||||||
<string>AppIcon60x60</string>
|
<string>AppIcon-29</string>
|
||||||
<string>AppIcon76x76~ipad</string>
|
<string>AppIcon-40</string>
|
||||||
|
<string>AppIcon-57</string>
|
||||||
|
<string>AppIcon-60</string>
|
||||||
|
<string>AppIcon-50</string>
|
||||||
|
<string>AppIcon-72</string>
|
||||||
|
<string>AppIcon-76</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIPrerenderedIcon</key>
|
<key>UIPrerenderedIcon</key>
|
||||||
<true/>
|
<true/>
|
||||||
@@ -42,7 +50,7 @@
|
|||||||
<string>iPhoneOS</string>
|
<string>iPhoneOS</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.1</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
|
|||||||
@@ -238,7 +238,8 @@ int find_off_cryptid(const char *filePath) {
|
|||||||
self.appVersion = appVersion;
|
self.appVersion = appVersion;
|
||||||
|
|
||||||
[self setAppPath:[pathToBinary stringByDeletingLastPathComponent]];
|
[self setAppPath:[pathToBinary stringByDeletingLastPathComponent]];
|
||||||
[self setDocPath:[NSString stringWithFormat:@"%@/Documents", NSHomeDirectory()]];
|
// [self setDocPath:[NSString stringWithFormat:@"%@/Documents", NSHomeDirectory()]];
|
||||||
|
[self setDocPath:docPath()];
|
||||||
|
|
||||||
char *lastPartOfAppPath = strdup([[self appPath] UTF8String]);
|
char *lastPartOfAppPath = strdup([[self appPath] UTF8String]);
|
||||||
lastPartOfAppPath = strrchr(lastPartOfAppPath, '/') + 1;
|
lastPartOfAppPath = strrchr(lastPartOfAppPath, '/') + 1;
|
||||||
|
|||||||
@@ -18,6 +18,29 @@
|
|||||||
self.refreshControl = refreshControl;
|
self.refreshControl = refreshControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewDidAppear:(bool)animated {
|
||||||
|
[super viewDidAppear:animated];
|
||||||
|
|
||||||
|
fetchLatestTrollDecryptVersion(^(NSString *latestVersion) {
|
||||||
|
NSString *currentVersion = trollDecryptVersion();
|
||||||
|
NSComparisonResult result = [currentVersion compare:latestVersion options:NSNumericSearch];
|
||||||
|
NSLog(@"[trolldecrypter] Current version: %@, Latest version: %@", currentVersion, latestVersion);
|
||||||
|
if (result == NSOrderedAscending) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Update Available" message:@"An update for TrollDecrypt is available." preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||||
|
UIAlertAction *update = [UIAlertAction actionWithTitle:@"Download" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
|
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://github.com/donato-fiore/TrollDecrypt/releases/latest"]] options:@{} completionHandler:nil];
|
||||||
|
}];
|
||||||
|
|
||||||
|
[alert addAction:update];
|
||||||
|
[alert addAction:cancel];
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
- (void)openDocs:(id)sender {
|
- (void)openDocs:(id)sender {
|
||||||
TDFileManagerViewController *fmVC = [[TDFileManagerViewController alloc] init];
|
TDFileManagerViewController *fmVC = [[TDFileManagerViewController alloc] init];
|
||||||
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:fmVC];
|
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:fmVC];
|
||||||
|
|||||||
23
TDUtils.h
@@ -17,23 +17,6 @@
|
|||||||
- (BOOL)launchApplicationWithIdentifier:(id)arg1 suspended:(BOOL)arg2;
|
- (BOOL)launchApplicationWithIdentifier:(id)arg1 suspended:(BOOL)arg2;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface LSApplicationProxy : NSObject
|
|
||||||
@property (readonly, nonatomic) NSString *bundleIdentifier; // ivar: _bundleIdentifier
|
|
||||||
@property (readonly) NSString *shortVersionString;
|
|
||||||
@property (readonly, nonatomic) NSString *canonicalExecutablePath;
|
|
||||||
@property (getter=isLaunchProhibited) BOOL launchProhibited;
|
|
||||||
@property (readonly, nonatomic) NSArray *appTags;
|
|
||||||
@property(readonly) NSString * applicationType;
|
|
||||||
- (NSString *)localizedName;
|
|
||||||
+ (instancetype)applicationProxyForIdentifier:(NSString*)identifier;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface LSApplicationWorkspace : NSObject
|
|
||||||
+ (instancetype)defaultWorkspace;
|
|
||||||
- (NSMutableArray<LSApplicationProxy *> *)allApplications;
|
|
||||||
- (NSArray<LSApplicationProxy *> *)allInstalledApplications;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface UIImage (Private)
|
@interface UIImage (Private)
|
||||||
+ (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(NSUInteger)format scale:(CGFloat)scale;
|
+ (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(NSUInteger)format scale:(CGFloat)scale;
|
||||||
@end
|
@end
|
||||||
@@ -42,6 +25,7 @@
|
|||||||
#define PROC_PIDPATHINFO_SIZE (MAXPATHLEN)
|
#define PROC_PIDPATHINFO_SIZE (MAXPATHLEN)
|
||||||
#define PROC_PIDPATHINFO_MAXSIZE (4 * MAXPATHLEN)
|
#define PROC_PIDPATHINFO_MAXSIZE (4 * MAXPATHLEN)
|
||||||
#define PROC_ALL_PIDS 1
|
#define PROC_ALL_PIDS 1
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
# define NSLog(...) (void)0
|
# define NSLog(...) (void)0
|
||||||
#endif
|
#endif
|
||||||
@@ -55,4 +39,7 @@ void decryptApp(NSDictionary *app);
|
|||||||
void decryptAppWithPID(pid_t pid);
|
void decryptAppWithPID(pid_t pid);
|
||||||
void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version);
|
void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version);
|
||||||
NSArray *decryptedFileList(void);
|
NSArray *decryptedFileList(void);
|
||||||
NSString *docPath(void);
|
NSString *docPath(void);
|
||||||
|
void fetchLatestTrollDecryptVersion(void (^completionHandler)(NSString *version));
|
||||||
|
void github_fetchLatedVersion(NSString *repo, void (^completionHandler)(NSString *latestVersion));
|
||||||
|
NSString *trollDecryptVersion(void);
|
||||||
119
TDUtils.m
@@ -1,5 +1,6 @@
|
|||||||
#import "TDUtils.h"
|
#import "TDUtils.h"
|
||||||
#import "TDDumpDecrypted.h"
|
#import "TDDumpDecrypted.h"
|
||||||
|
#import "LSApplicationProxy+AltList.h"
|
||||||
|
|
||||||
UIWindow *alertWindow = NULL;
|
UIWindow *alertWindow = NULL;
|
||||||
UIWindow *kw = NULL;
|
UIWindow *kw = NULL;
|
||||||
@@ -10,14 +11,17 @@ UIAlertController *errorController = NULL;
|
|||||||
|
|
||||||
NSArray *appList(void) {
|
NSArray *appList(void) {
|
||||||
NSMutableArray *apps = [NSMutableArray array];
|
NSMutableArray *apps = [NSMutableArray array];
|
||||||
|
|
||||||
for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
|
|
||||||
if (![[app applicationType] isEqualToString:@"User"]) continue;
|
|
||||||
|
|
||||||
NSString *bundleID = app.bundleIdentifier;
|
NSArray <LSApplicationProxy *> *installedApplications = [[LSApplicationWorkspace defaultWorkspace] atl_allInstalledApplications];
|
||||||
NSString *name = [app localizedName];
|
[installedApplications enumerateObjectsUsingBlock:^(LSApplicationProxy *proxy, NSUInteger idx, BOOL *stop) {
|
||||||
NSString *version = app.shortVersionString;
|
if (![proxy atl_isUserApplication]) return;
|
||||||
NSString *executable = [app canonicalExecutablePath];
|
|
||||||
|
NSString *bundleID = [proxy atl_bundleIdentifier];
|
||||||
|
NSString *name = [proxy atl_nameToDisplay];
|
||||||
|
NSString *version = [proxy atl_shortVersionString];
|
||||||
|
NSString *executable = proxy.canonicalExecutablePath;
|
||||||
|
|
||||||
|
if (!bundleID || !name || !version || !executable) return;
|
||||||
|
|
||||||
NSDictionary *item = @{
|
NSDictionary *item = @{
|
||||||
@"bundleID":bundleID,
|
@"bundleID":bundleID,
|
||||||
@@ -27,11 +31,11 @@ NSArray *appList(void) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
[apps addObject:item];
|
[apps addObject:item];
|
||||||
}
|
}];
|
||||||
|
|
||||||
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
|
||||||
[apps sortUsingDescriptors:@[descriptor]];
|
[apps sortUsingDescriptors:@[descriptor]];
|
||||||
|
|
||||||
[apps addObject:@{@"bundleID":@"", @"name":@"", @"version":@"", @"executable":@""}];
|
[apps addObject:@{@"bundleID":@"", @"name":@"", @"version":@"", @"executable":@""}];
|
||||||
|
|
||||||
return [apps copy];
|
return [apps copy];
|
||||||
@@ -42,42 +46,6 @@ NSUInteger iconFormat(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSArray *sysctl_ps(void) {
|
NSArray *sysctl_ps(void) {
|
||||||
// int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
|
||||||
// size_t miblen = 4;
|
|
||||||
// size_t size;
|
|
||||||
// int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
|
|
||||||
// struct kinfo_proc * process = NULL;
|
|
||||||
// struct kinfo_proc * newprocess = NULL;
|
|
||||||
|
|
||||||
// do {
|
|
||||||
// size += size / 10;
|
|
||||||
// newprocess = realloc(process, size);
|
|
||||||
// if (!newprocess){
|
|
||||||
// if (process){
|
|
||||||
// free(process);
|
|
||||||
// }
|
|
||||||
// return nil;
|
|
||||||
// }
|
|
||||||
// process = newprocess;
|
|
||||||
// st = sysctl(mib, miblen, process, &size, NULL, 0);
|
|
||||||
// } while (st == -1 && errno == ENOMEM);
|
|
||||||
|
|
||||||
// if (st == 0) {
|
|
||||||
// if (size % sizeof(struct kinfo_proc) == 0){
|
|
||||||
// int nprocess = size / sizeof(struct kinfo_proc);
|
|
||||||
// if (nprocess){
|
|
||||||
// NSMutableArray * array = [[NSMutableArray alloc] init];
|
|
||||||
// for (int i = nprocess - 1; i >= 0; i--){
|
|
||||||
// NSString *processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
|
|
||||||
// NSString *processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];
|
|
||||||
// NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil] forKeys:[NSArray arrayWithObjects:@"pid", @"proc_name", nil]];
|
|
||||||
// [array addObject:dict];
|
|
||||||
// }
|
|
||||||
// free(process);
|
|
||||||
// return array;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
||||||
@@ -246,6 +214,7 @@ void bfinject_rocknroll(pid_t pid, NSString *appName, NSString *version) {
|
|||||||
|
|
||||||
NSArray *decryptedFileList(void) {
|
NSArray *decryptedFileList(void) {
|
||||||
NSMutableArray *files = [NSMutableArray array];
|
NSMutableArray *files = [NSMutableArray array];
|
||||||
|
NSMutableArray *fileNames = [NSMutableArray array];
|
||||||
|
|
||||||
// iterate through all files in the Documents directory
|
// iterate through all files in the Documents directory
|
||||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
@@ -257,7 +226,7 @@ NSArray *decryptedFileList(void) {
|
|||||||
NSString *filePath = [[docPath() stringByAppendingPathComponent:file] stringByStandardizingPath];
|
NSString *filePath = [[docPath() stringByAppendingPathComponent:file] stringByStandardizingPath];
|
||||||
|
|
||||||
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:nil];
|
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:nil];
|
||||||
NSDate *modificationDate = [fileAttributes fileModificationDate];
|
NSDate *modificationDate = fileAttributes[NSFileModificationDate];
|
||||||
|
|
||||||
NSDictionary *fileInfo = @{@"fileName": file, @"modificationDate": modificationDate};
|
NSDictionary *fileInfo = @{@"fileName": file, @"modificationDate": modificationDate};
|
||||||
[files addObject:fileInfo];
|
[files addObject:fileInfo];
|
||||||
@@ -271,11 +240,22 @@ NSArray *decryptedFileList(void) {
|
|||||||
return [date2 compare:date1];
|
return [date2 compare:date1];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return [sortedFiles valueForKey:@"fileName"];
|
// Get the file names from the sorted array
|
||||||
|
for (NSDictionary *fileInfo in sortedFiles) {
|
||||||
|
[fileNames addObject:[fileInfo objectForKey:@"fileName"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [fileNames copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *docPath(void) {
|
NSString *docPath(void) {
|
||||||
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
NSError * error = nil;
|
||||||
|
[[NSFileManager defaultManager] createDirectoryAtPath:@"/var/mobile/Library/TrollDecrypt/decrypted" withIntermediateDirectories:YES attributes:nil error:&error];
|
||||||
|
if (error != nil) {
|
||||||
|
NSLog(@"[trolldecrypt] error creating directory: %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return @"/var/mobile/Library/TrollDecrypt/decrypted";
|
||||||
}
|
}
|
||||||
|
|
||||||
void decryptAppWithPID(pid_t pid) {
|
void decryptAppWithPID(pid_t pid) {
|
||||||
@@ -341,17 +321,11 @@ void decryptAppWithPID(pid_t pid) {
|
|||||||
|
|
||||||
NSLog(@"[trolldecrypt] app: %@", app);
|
NSLog(@"[trolldecrypt] app: %@", app);
|
||||||
|
|
||||||
NSString *name = [app localizedName];
|
|
||||||
NSString *version = app.shortVersionString;
|
|
||||||
if (!version) version = @"1.0";
|
|
||||||
|
|
||||||
NSString *exec = [app canonicalExecutablePath];
|
|
||||||
|
|
||||||
NSDictionary *appInfo = @{
|
NSDictionary *appInfo = @{
|
||||||
@"bundleID":bundleID,
|
@"bundleID":bundleID,
|
||||||
@"name":name,
|
@"name":[app atl_nameToDisplay],
|
||||||
@"version":version,
|
@"version":[app atl_shortVersionString],
|
||||||
@"executable":exec
|
@"executable":executable
|
||||||
};
|
};
|
||||||
|
|
||||||
NSLog(@"[trolldecrypt] appInfo: %@", appInfo);
|
NSLog(@"[trolldecrypt] appInfo: %@", appInfo);
|
||||||
@@ -369,4 +343,33 @@ void decryptAppWithPID(pid_t pid) {
|
|||||||
|
|
||||||
[root presentViewController:alert animated:YES completion:nil];
|
[root presentViewController:alert animated:YES completion:nil];
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void github_fetchLatedVersion(NSString *repo, void (^completionHandler)(NSString *latestVersion)) {
|
||||||
|
NSString *urlString = [NSString stringWithFormat:@"https://api.github.com/repos/%@/releases/latest", repo];
|
||||||
|
NSURL *url = [NSURL URLWithString:urlString];
|
||||||
|
|
||||||
|
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||||
|
if (!error) {
|
||||||
|
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||||
|
NSError *jsonError;
|
||||||
|
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
|
||||||
|
|
||||||
|
if (!jsonError) {
|
||||||
|
NSString *version = [json[@"tag_name"] stringByReplacingOccurrencesOfString:@"v" withString:@""];
|
||||||
|
completionHandler(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
[task resume];
|
||||||
|
}
|
||||||
|
|
||||||
|
void fetchLatestTrollDecryptVersion(void (^completionHandler)(NSString *version)) {
|
||||||
|
github_fetchLatedVersion(@"donato-fiore/TrollDecrypt", completionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *trollDecryptVersion(void) {
|
||||||
|
return [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||||
}
|
}
|
||||||
2
control
@@ -1,6 +1,6 @@
|
|||||||
Package: com.fiore.trolldecrypt
|
Package: com.fiore.trolldecrypt
|
||||||
Name: TrollDecrypt
|
Name: TrollDecrypt
|
||||||
Version: 0.0.1
|
Version: 1.1
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: An awesome application!
|
Description: An awesome application!
|
||||||
Maintainer: fiore
|
Maintainer: fiore
|
||||||
|
|||||||
@@ -34,5 +34,17 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.springboard.launchapplications</key>
|
<key>com.apple.springboard.launchapplications</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.exception.iokit-user-client-class</key>
|
||||||
|
<array>
|
||||||
|
<string>IOUserClient</string>
|
||||||
|
<string>IOUserServer</string>
|
||||||
|
<string>RootDomainUserClient</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.security.iokit-user-client-class</key>
|
||||||
|
<array>
|
||||||
|
<string>IOUserClient</string>
|
||||||
|
<string>IOUserServer</string>
|
||||||
|
<string>RootDomainUserClient</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||