mirror of https://github.com/opa334/TrollStore.git
Support injection of TrollInstaller2 into ANY AppStore encrypted IPA
This commit is contained in:
parent
e9aaaa1bbc
commit
7dd6c86c3d
|
@ -5,4 +5,4 @@ packages/
|
||||||
xcuserdata
|
xcuserdata
|
||||||
.vscode
|
.vscode
|
||||||
pwnify_compiled
|
pwnify_compiled
|
||||||
Developer.ipa
|
InstallerVictim.ipa
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
@interface TSI2AppDelegate : UIResponder <UIApplicationDelegate>
|
|
||||||
|
|
||||||
@end
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface TSI2AppDelegateNoScene : UIResponder <UIApplicationDelegate>
|
||||||
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
@property (nonatomic, strong) UINavigationController *rootViewController;
|
||||||
|
@end
|
|
@ -0,0 +1,14 @@
|
||||||
|
#import "TSI2AppDelegateNoScene.h"
|
||||||
|
#import "TSI2RootViewController.h"
|
||||||
|
|
||||||
|
@implementation TSI2AppDelegateNoScene
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
|
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
_rootViewController = [[UINavigationController alloc] initWithRootViewController:[[TSI2RootViewController alloc] init]];
|
||||||
|
_window.rootViewController = _rootViewController;
|
||||||
|
[_window makeKeyAndVisible];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface TSI2AppDelegateWithScene : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
|
@end
|
|
@ -1,6 +1,6 @@
|
||||||
#import "TSI2AppDelegate.h"
|
#import "TSI2AppDelegateWithScene.h"
|
||||||
|
|
||||||
@implementation TSI2AppDelegate
|
@implementation TSI2AppDelegateWithScene
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
return YES;
|
return YES;
|
|
@ -1,14 +1,69 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "TSI2AppDelegate.h"
|
#import "TSI2AppDelegateNoScene.h"
|
||||||
|
#import "TSI2AppDelegateWithScene.h"
|
||||||
#import "TSI2SceneDelegate.h"
|
#import "TSI2SceneDelegate.h"
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
extern int rootHelperMain(int argc, char *argv[], char *envp[]);
|
extern int rootHelperMain(int argc, char *argv[], char *envp[]);
|
||||||
|
|
||||||
void classFixup(void)
|
BOOL sceneDelegateFix(void)
|
||||||
{
|
{
|
||||||
Class newClass = objc_allocateClassPair([TSI2SceneDelegate class], "WWDC.SceneDelegate", 0);
|
NSString* sceneDelegateClassName = nil;
|
||||||
|
|
||||||
|
NSDictionary* UIApplicationSceneManifest = [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIApplicationSceneManifest"];
|
||||||
|
if(UIApplicationSceneManifest && [UIApplicationSceneManifest isKindOfClass:NSDictionary.class])
|
||||||
|
{
|
||||||
|
NSDictionary* UISceneConfiguration = UIApplicationSceneManifest[@"UISceneConfigurations"];
|
||||||
|
if(UISceneConfiguration && [UISceneConfiguration isKindOfClass:NSDictionary.class])
|
||||||
|
{
|
||||||
|
NSArray* UIWindowSceneSessionRoleApplication = UISceneConfiguration[@"UIWindowSceneSessionRoleApplication"];
|
||||||
|
if(UIWindowSceneSessionRoleApplication && [UIWindowSceneSessionRoleApplication isKindOfClass:NSArray.class])
|
||||||
|
{
|
||||||
|
NSDictionary* sceneToUse = nil;
|
||||||
|
if(UIWindowSceneSessionRoleApplication.count > 1)
|
||||||
|
{
|
||||||
|
for(NSDictionary* scene in UIWindowSceneSessionRoleApplication)
|
||||||
|
{
|
||||||
|
if([scene isKindOfClass:NSDictionary.class])
|
||||||
|
{
|
||||||
|
NSString* UISceneConfigurationName = scene[@"UISceneConfigurationName"];
|
||||||
|
if([UISceneConfigurationName isKindOfClass:NSString.class])
|
||||||
|
{
|
||||||
|
if([UISceneConfigurationName isEqualToString:@"Default Configuration"])
|
||||||
|
{
|
||||||
|
sceneToUse = scene;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sceneToUse)
|
||||||
|
{
|
||||||
|
sceneToUse = UIWindowSceneSessionRoleApplication.firstObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sceneToUse = UIWindowSceneSessionRoleApplication.firstObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sceneToUse && [sceneToUse isKindOfClass:NSDictionary.class])
|
||||||
|
{
|
||||||
|
sceneDelegateClassName = sceneToUse[@"UISceneDelegateClassName"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sceneDelegateClassName && [sceneDelegateClassName isKindOfClass:NSString.class])
|
||||||
|
{
|
||||||
|
Class newClass = objc_allocateClassPair([TSI2SceneDelegate class], sceneDelegateClassName.UTF8String, 0);
|
||||||
objc_registerClassPair(newClass);
|
objc_registerClassPair(newClass);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[], char *envp[]) {
|
int main(int argc, char *argv[], char *envp[]) {
|
||||||
|
@ -21,8 +76,15 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
classFixup();
|
BOOL usesSceneDelegate = sceneDelegateFix();
|
||||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass(TSI2AppDelegate.class));
|
if(usesSceneDelegate)
|
||||||
|
{
|
||||||
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass(TSI2AppDelegateWithScene.class));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass(TSI2AppDelegateNoScene.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,38 @@ then
|
||||||
mkdir -p ./out
|
mkdir -p ./out
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -d "./out/tmppwn" ]
|
||||||
|
then
|
||||||
|
rm -rf ./out/tmppwn
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "./out/TrollInstaller2_arm64e.ipa" ]
|
||||||
|
then
|
||||||
|
rm ./out/TrollInstaller2_arm64e.ipa
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir ./out/tmppwn || true 2> /dev/null
|
||||||
|
|
||||||
cd ../Installer/TrollInstaller2
|
cd ../Installer/TrollInstaller2
|
||||||
make clean
|
make clean
|
||||||
make package
|
make package
|
||||||
|
cd - 2> /dev/null
|
||||||
|
|
||||||
|
lipo -thin arm64e ../Installer/TrollInstaller2/.theos/obj/debug/TrollInstaller2.app/TrollInstaller2 -output ./out/tmppwn/pwn_arm64e
|
||||||
|
ldid -S -M -Kcert.p12 ./out/tmppwn/pwn_arm64e
|
||||||
|
|
||||||
|
unzip ./target/InstallerVictim.ipa -d ./out/tmppwn
|
||||||
|
|
||||||
|
cd ./out/tmppwn/Payload
|
||||||
|
APP_NAME=$(find *.app -maxdepth 0)
|
||||||
|
BINARY_NAME=$(echo "$APP_NAME" | cut -f 1 -d '.')
|
||||||
|
cd - 2> /dev/null
|
||||||
|
|
||||||
|
./pwnify_compiled ./out/tmppwn/Payload/$APP_NAME/$BINARY_NAME ./out/tmppwn/pwn_arm64e
|
||||||
|
rm ./out/tmppwn/pwn_arm64e
|
||||||
|
|
||||||
|
cd ./out/tmppwn
|
||||||
|
zip -vr ../TrollInstaller2_arm64e.ipa *
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
lipo -thin arm64e ../Installer/TrollInstaller2/.theos/obj/debug/TrollInstaller2.app/TrollInstaller2 -output ./out/pwn_arm64e
|
rm -rf ./out/tmppwn
|
||||||
ldid -S -M -Kcert.p12 ./out/pwn_arm64e
|
|
||||||
|
|
||||||
mkdir ./out/devpwn
|
|
||||||
unzip target/Developer.ipa -d ./out/devpwn
|
|
||||||
|
|
||||||
./pwnify_compiled ./out/devpwn/Payload/Developer.app/Developer ./out/pwn_arm64e
|
|
||||||
rm ./out/pwn_arm64e
|
|
||||||
|
|
||||||
cd ./out/devpwn
|
|
||||||
zip -vr devpwn.ipa *
|
|
||||||
cd -
|
|
||||||
|
|
||||||
cp ./out/devpwn/devpwn.ipa ./out/DeveloperInstaller.ipa
|
|
||||||
rm -rf ./out/devpwn
|
|
|
@ -8,15 +8,15 @@
|
||||||
|
|
||||||
1. Do `git clone https://github.com/opa334/TrollStore`
|
1. Do `git clone https://github.com/opa334/TrollStore`
|
||||||
|
|
||||||
2. Get a stock "Apple Developer" IPA using [ipatool](https://github.com/majd/ipatool/releases/tag/v1.1.4) (iOS 15 only)
|
2. Get ANY encrypted AppStore IPA using [ipatool](https://github.com/majd/ipatool/releases/tag/v1.1.4)
|
||||||
- Unzip, then do `chmod +x ~/Downloads/ipatool`
|
- Unzip, then do `chmod +x ~/Downloads/ipatool`
|
||||||
- `sudo mv ~/Downloads/ipatool /usr/local/bin`
|
- `sudo mv ~/Downloads/ipatool /usr/local/bin`
|
||||||
- `ipatool auth login`
|
- `ipatool auth login`
|
||||||
- `ipatool download -b developer.apple.wwdc-Release`
|
- `ipatool download -b developer.apple.wwdc-Release`
|
||||||
|
|
||||||
> For iOS 14 please follow [this](https://github.com/flowerible/How-to-Downgrade-apps-on-AppStore-with-iTunes-and-Charles-Proxy) you will need Windows, once you get ipa switch back to Mac preceed.
|
> For iOS 14 please make sure to use an app that still supports iOS 14
|
||||||
|
|
||||||
3. Rename the output ipa to `Developer.ipa`, and put it into ~/TrollStore/_compile/target/Developer.ipa
|
3. Rename the output ipa to `InstallerVictim.ipa`, and put it into ~/TrollStore/_compile/InstallerVictim.ipa
|
||||||
|
|
||||||
4. Grab pwnify_compiled from Fugu14 repo (https://github.com/LinusHenze/Fugu14/blob/master/tools/pwnify_compiled), sign it using codesign (`codesign -f -s - <path/to/pwnify_compiled>`) and put it at ~/TrollStore/_compile/pwnify_compiled
|
4. Grab pwnify_compiled from Fugu14 repo (https://github.com/LinusHenze/Fugu14/blob/master/tools/pwnify_compiled), sign it using codesign (`codesign -f -s - <path/to/pwnify_compiled>`) and put it at ~/TrollStore/_compile/pwnify_compiled
|
||||||
|
|
||||||
|
@ -25,18 +25,16 @@
|
||||||
- Rename the Procursus ldid for your arch to `ldid`, then do `chmod +x ~/Downloads/ldid`
|
- Rename the Procursus ldid for your arch to `ldid`, then do `chmod +x ~/Downloads/ldid`
|
||||||
- `sudo mv ~/Downloads/ldid /usr/local/bin`
|
- `sudo mv ~/Downloads/ldid /usr/local/bin`
|
||||||
|
|
||||||
> As of right now you need to add an "`out`" folder in _compile
|
|
||||||
|
|
||||||
6. cd into _compile and run `./build_trollinstaller2.sh` (`chmod +x ./build_trollinstaller2.sh` if you get a permission error)
|
6. cd into _compile and run `./build_trollinstaller2.sh` (`chmod +x ./build_trollinstaller2.sh` if you get a permission error)
|
||||||
|
|
||||||
7. Wait a bit, when done, there will be a `DeveloperInstaller.ipa` in ~/TrollStore/_compile/out
|
7. Wait a bit, when done, there will be a `TrollInstaller2.ipa` in ~/TrollStore/_compile/out
|
||||||
|
|
||||||
> If this fails and gives you a `devpwn.ipa`, unzip that ipa and put all the contents in it back into their original places.
|
|
||||||
|
|
||||||
## Using compiled IPA (does not neccessarily require a Mac if you obtained the IPA from non orthodox ways)
|
## Using compiled IPA (does not neccessarily require a Mac if you obtained the IPA from non orthodox ways)
|
||||||
|
|
||||||
8. You can install that to a device using e.g. ideviceinstaller(do `brew install ideviceinstaller` then do `ideviceinstaller -i DeveloperInstaller.ipa`)
|
8. You can install that to a device using e.g. ideviceinstaller(do `brew install ideviceinstaller` then do `ideviceinstaller -i TrollInstaller2.ipa`)
|
||||||
|
|
||||||
|
Alternatively, you can use Sideloadly if you select "Normal Installation".
|
||||||
|
|
||||||
(Other methods may also work, but make sure you don't use a signing cert, you can also use an enterprise plist or something to install it via Safari as shown in Fugu15 demo, something like iFunBox may also work)
|
(Other methods may also work, but make sure you don't use a signing cert, you can also use an enterprise plist or something to install it via Safari as shown in Fugu15 demo, something like iFunBox may also work)
|
||||||
|
|
||||||
9. After installation, you can use the "Developer" app on your device to install TrollStore
|
9. After installation, you can use the newly installed app on your device to install TrollStore
|
||||||
|
|
Loading…
Reference in New Issue