mirror of https://github.com/opa334/TrollStore.git
212 lines
5.5 KiB
Mathematica
212 lines
5.5 KiB
Mathematica
|
//
|
||
|
// ViewController.m
|
||
|
// TrollInstaller
|
||
|
//
|
||
|
// Created by Lars Fröder on 17.08.22.
|
||
|
//
|
||
|
|
||
|
#import "ViewController.h"
|
||
|
#import "kutil.h"
|
||
|
#import "exploit/exploit.h"
|
||
|
#import "exploit/kernel_rw.h"
|
||
|
#import "KernelManager.h"
|
||
|
#import "unarchive.h"
|
||
|
#import <spawn.h>
|
||
|
#import <sys/stat.h>
|
||
|
|
||
|
extern uint64_t g_self_proc;
|
||
|
|
||
|
int runBinary(NSString* path, NSArray* args)
|
||
|
{
|
||
|
NSMutableArray* argsM = args.mutableCopy;
|
||
|
[argsM insertObject:path.lastPathComponent atIndex:0];
|
||
|
|
||
|
NSUInteger argCount = [argsM count];
|
||
|
char **argsC = (char **)malloc((argCount + 1) * sizeof(char*));
|
||
|
|
||
|
for (NSUInteger i = 0; i < argCount; i++)
|
||
|
{
|
||
|
argsC[i] = strdup([[argsM objectAtIndex:i] UTF8String]);
|
||
|
}
|
||
|
argsC[argCount] = NULL;
|
||
|
|
||
|
pid_t task_pid;
|
||
|
int status = 0;
|
||
|
int spawnError = posix_spawn(&task_pid, [path UTF8String], NULL, NULL, (char* const*)argsC, NULL);
|
||
|
for (NSUInteger i = 0; i < argCount; i++)
|
||
|
{
|
||
|
free(argsC[i]);
|
||
|
}
|
||
|
free(argsC);
|
||
|
|
||
|
if(spawnError != 0)
|
||
|
{
|
||
|
NSLog(@"posix_spawn error %d\n", spawnError);
|
||
|
return spawnError;
|
||
|
}
|
||
|
|
||
|
waitpid(task_pid, &status, WEXITED);
|
||
|
|
||
|
waitpid(task_pid, NULL, 0);
|
||
|
|
||
|
NSLog(@"status = %d", status);
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Get root, credit: @xina520
|
||
|
|
||
|
struct k_posix_cred backup_cred;
|
||
|
int backup_groupSize;
|
||
|
gid_t backup_groupList[200];
|
||
|
|
||
|
int getRoot(void)
|
||
|
{
|
||
|
printf("attempting to get root...\n");
|
||
|
usleep(1000);
|
||
|
|
||
|
backup_groupSize = getgroups(200, &backup_groupList[0]);
|
||
|
|
||
|
backup_cred = proc_get_posix_cred(g_self_proc);
|
||
|
|
||
|
struct k_posix_cred zero_cred = {0};
|
||
|
printf("setting posix cred to zero cred...\n");
|
||
|
usleep(1000);
|
||
|
proc_set_posix_cred(g_self_proc, zero_cred);
|
||
|
|
||
|
int err = setgroups(0,0);
|
||
|
if(err)
|
||
|
{
|
||
|
printf("setgroups error %d\n", err);
|
||
|
usleep(1000);
|
||
|
}
|
||
|
|
||
|
int uid = getuid();
|
||
|
printf("getuid => %d\n", uid);
|
||
|
usleep(1000);
|
||
|
|
||
|
return uid;
|
||
|
}
|
||
|
|
||
|
int dropRoot(void)
|
||
|
{
|
||
|
if(getuid() != 0) return getuid();
|
||
|
|
||
|
printf("attempting to drop root...\n");
|
||
|
usleep(1000);
|
||
|
|
||
|
int err = setgroups(backup_groupSize,backup_groupList);
|
||
|
if(err)
|
||
|
{
|
||
|
printf("setgroups error %d\n", err);
|
||
|
usleep(1000);
|
||
|
}
|
||
|
|
||
|
proc_set_posix_cred(g_self_proc, backup_cred);
|
||
|
|
||
|
int uid = getuid();
|
||
|
printf("dropped root??? uid: %d\n", uid);
|
||
|
return uid;
|
||
|
}
|
||
|
|
||
|
@interface ViewController ()
|
||
|
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
|
||
|
@end
|
||
|
|
||
|
@implementation ViewController
|
||
|
|
||
|
- (void)viewDidLoad {
|
||
|
[super viewDidLoad];
|
||
|
// Do any additional setup after loading the view.
|
||
|
}
|
||
|
|
||
|
- (void)updateStatus:(NSString*)status
|
||
|
{
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
self.statusLabel.text = status;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
int writeRemountPrivatePreboot(void)
|
||
|
{
|
||
|
return runBinary(@"/sbin/mount", @[@"-u", @"-w", @"/private/preboot"]);
|
||
|
}
|
||
|
|
||
|
- (void)doInstallation
|
||
|
{
|
||
|
[self updateStatus:@"Exploiting..."];
|
||
|
|
||
|
// Run Kernel exploit
|
||
|
uint64_t kernel_base;
|
||
|
exploit_get_krw_and_kernel_base(&kernel_base);
|
||
|
|
||
|
// Initialize KernelManager
|
||
|
KernelManager* km = [KernelManager sharedInstance];
|
||
|
[km loadOffsets];
|
||
|
[km loadSlidOffsetsWithKernelBase:kernel_base];
|
||
|
km.kread_32_d = kread32;
|
||
|
km.kread_64_d = kread64;
|
||
|
km.kwrite_32 = kwrite32;
|
||
|
km.kwrite_64 = kwrite64;
|
||
|
km.kcleanup = exploitation_cleanup;
|
||
|
|
||
|
[self updateStatus:@"Getting root..."];
|
||
|
|
||
|
// Get root
|
||
|
getRoot();
|
||
|
|
||
|
[self updateStatus:@"Installing..."];
|
||
|
|
||
|
writeRemountPrivatePreboot();
|
||
|
|
||
|
NSString* tmpDir = @"/private/preboot/tmp";
|
||
|
|
||
|
[[NSFileManager defaultManager] createDirectoryAtPath:tmpDir withIntermediateDirectories:NO attributes:nil error:nil];
|
||
|
|
||
|
NSString* tsTarPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"TrollStore.tar"];
|
||
|
|
||
|
extract(tsTarPath, tmpDir);
|
||
|
|
||
|
NSString* helperPath = [tmpDir stringByAppendingPathComponent:@"TrollStore.app/trollstorehelper"];
|
||
|
|
||
|
chmod(helperPath.UTF8String, 0755);
|
||
|
chown(helperPath.UTF8String, 0, 0);
|
||
|
|
||
|
int ret = runBinary(helperPath, @[@"install-trollstore", tsTarPath]);
|
||
|
|
||
|
[self updateStatus:@"Cleaning up..."];
|
||
|
|
||
|
[[NSFileManager defaultManager] removeItemAtPath:tmpDir error:nil];
|
||
|
|
||
|
// Clean everything up so the kernel doesn't panic when the app exits
|
||
|
dropRoot();
|
||
|
[km finishAndCleanupIfNeeded];
|
||
|
|
||
|
[self updateStatus:@"Done!"];
|
||
|
|
||
|
// Print installed message
|
||
|
if(ret == 0)
|
||
|
{
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
UIAlertController* installedAlertController = [UIAlertController alertControllerWithTitle:@"Installed TrollStore" message:@"TrollStore was installed and can now be accessed from your home screen, you can uninstall the installer application now. Some devices suffer from a bug where newly installed applications don't immediately show up, in that case reboot and TrollStore should show up." preferredStyle:UIAlertControllerStyleAlert];
|
||
|
|
||
|
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||
|
exit(0);
|
||
|
}];
|
||
|
|
||
|
[installedAlertController addAction:closeAction];
|
||
|
|
||
|
[self presentViewController:installedAlertController animated:YES completion:nil];
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (IBAction)installButtonPressed:(id)sender {
|
||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||
|
[self doInstallation];
|
||
|
});
|
||
|
}
|
||
|
|
||
|
@end
|