// // ViewController.m // g0blinTV // // Created by Kevin Bradley on 1/15/18. // Copyright © 2018 Sticktron. All rights reserved. // #import "ViewController.h" #include #include "v0rtex2.h" #include "common2.h" #include "offsets2.h" #include "kernel.h" #include "kpp.h" #include "remount.h" #include "bootstrap.h" #include #import #import #import "SVProgressHUD.h" #import "UIColor+Additions.h" //#define GRAPE [UIColor colorWithRed:0.5 green:0 blue:1 alpha:1] #define GRAPE [UIColor colorFromHex:@"25b24a"] @implementation FocusedButton - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { self.layer.cornerRadius = 5; self.backgroundColor = [UIColor lightGrayColor]; self.focusColor = [UIColor redColor]; self.unfocusedColor = [UIColor lightGrayColor]; } return self; } - (void)buttonColors:(UIColor *)focusedColor andUnfocused:(UIColor *)unfocusedColor { self.focusColor = focusedColor; self.unfocusedColor = unfocusedColor; self.backgroundColor = unfocusedColor; } - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator { [coordinator addCoordinatedAnimations:^{ if (self.focused) { self.backgroundColor = self.focusColor; self.transform = CGAffineTransformMakeScale(1.1, 1.1); self.layer.shadowColor = [UIColor blackColor].CGColor; self.layer.shadowOffset = CGSizeMake(0, 27); self.layer.shadowOpacity = 0.25; self.layer.shadowRadius = 10; self.clipsToBounds = NO; } else { self.transform = CGAffineTransformIdentity; self.backgroundColor = self.unfocusedColor; self.clipsToBounds = YES; } } completion:nil]; } @end @interface ViewController () { BOOL _force; BOOL _disabled; } @property (weak, nonatomic) IBOutlet UIImageView *logoView; @property (weak, nonatomic) IBOutlet FocusedButton *goButton; @property (weak, nonatomic) IBOutlet FocusedButton *reinstallBootstrap; @property (weak, nonatomic) IBOutlet UITextView *consoleView; @property (weak, nonatomic) IBOutlet UIButton *settingsButton; @property (weak, nonatomic) IBOutlet UILabel *reinstallBootstrapLabel; @end static task_t tfp0; static uint64_t kslide; static uint64_t kbase; static uint64_t kcred; BOOL respringNeeded; BOOL fun; AVPlayer *player; AVPlayerViewController *cont; @implementation ViewController - (IBAction)toggleForce:(id)sender { _force = !_force; if (_force) { [self.reinstallBootstrap setTitle:@"Force Reinstall Bootstrap" forState:UIControlStateNormal]; [self.reinstallBootstrap setTitle:@"Force Reinstall Bootstrap" forState:UIControlStateFocused]; } else { [self.reinstallBootstrap setTitle:@"Dont Reinstall Bootstrap" forState:UIControlStateNormal]; [self.reinstallBootstrap setTitle:@"Dont Reinstall Bootstrap" forState:UIControlStateFocused]; } } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.goButton buttonColors:GRAPE andUnfocused:[UIColor darkTextColor]]; [self.reinstallBootstrap buttonColors:GRAPE andUnfocused:[UIColor darkTextColor]]; //self.consoleView.layer.cornerRadius = 6; self.consoleView.text = nil; self.consoleView.editable = false; self.consoleView.userInteractionEnabled = true; self.consoleView.layoutManager.allowsNonContiguousLayout = NO; self.goButton.layer.cornerRadius = 16; _force = NO; //self.reinstallBootstrapLabel.hidden = YES; // print kernel version struct utsname u; uname(&u); [self log:[NSString stringWithFormat:@"%s \n", u.version]]; _disabled = NO; // abort if already jailbroken //if (strstr(u.version, "MarijuanARM")) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithUTF8String:u.version] message:nil preferredStyle:UIAlertControllerStyleAlert]; [self presentViewController:alert animated:YES completion:nil]; if ([[NSString stringWithUTF8String:u.version] containsString:@"MarijuanARM"]){ self.goButton.enabled = NO; _disabled = YES; //self.goButton.backgroundColor = UIColor.darkGrayColor; [self.goButton setTitle:@"jailbroke yo!" forState:UIControlStateDisabled]; [self.goButton buttonColors:UIColor.darkGrayColor andUnfocused:[UIColor darkGrayColor]]; } // try to load offsets for device /* if (init_offsets() == KERN_SUCCESS) { [self log:@"Ready. \n"]; } else { self.goButton.enabled = NO; self.goButton.backgroundColor = UIColor.darkGrayColor; [self.goButton setTitle:@"device not supported" forState:UIControlStateDisabled]; } */ // fun UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fun:)]; doubleTap.delaysTouchesBegan = YES; doubleTap.numberOfTapsRequired = 3; [self.logoView addGestureRecognizer:doubleTap]; self.logoView.userInteractionEnabled = YES; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)log:(NSString *)text { dispatch_async(dispatch_get_main_queue(), ^{ [UIView setAnimationsEnabled:NO]; self.consoleView.text = [NSString stringWithFormat:@"%@%@ \n", self.consoleView.text, text]; [self.consoleView scrollRangeToVisible:NSMakeRange([self.consoleView.text length], 0)]; [UIView setAnimationsEnabled:YES]; }); } - (IBAction)prepareForUnwind:(UIStoryboardSegue *)segue { //segue exit marker //SettingsController *settingsController = segue.sourceViewController; //self.reinstallBootstrapLabel.hidden = !settingsController.reinstallBootstrapSwitch.on; } - (IBAction)go:(UIButton *)sender { if (_disabled) { LOG("Already jailbroken bro!"); return; } dispatch_async(dispatch_get_main_queue(), ^{ [self.consoleView.layoutManager ensureLayoutForTextContainer:self.consoleView.textContainer]; }); if (respringNeeded == YES) { [self restart]; return; } self.goButton.enabled = NO; self.goButton.backgroundColor = UIColor.darkGrayColor; [self.goButton setTitle:@"jailbreaking" forState:UIControlStateDisabled]; [self log:@"exploiting kernel"]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ offsets_t *off = get_offsets(); if (off) { kern_return_t ret = v0rtex(off, &tfp0, &kslide, &kcred); if (ret != KERN_SUCCESS) { self.goButton.enabled = YES; self.goButton.backgroundColor = GRAPE; [self.goButton setTitle:@"try again" forState:UIControlStateNormal]; [self log:@"ERROR: exploit failed \n"]; [self kludgeBoot]; return; } LOG("v0rtex was successful"); LOG("tfp0 -> %x", tfp0); LOG("slide -> 0x%llx", kslide); kbase = kslide + 0xFFFFFFF007004000; LOG("kern base -> 0x%llx", kbase); LOG("kern cred -> 0x%llx", kcred); [self bypassKPP]; } }); } - (void)bypassKPP { [self log:@"pwning kernel"]; if (do_kpp(1, 0, kbase, kslide, tfp0) == KERN_SUCCESS) { LOG("you down with kpp? yeah you know me"); [self remount]; } else { [self log:@"ERROR: kpp bypass failed \n"]; } } - (void)remount { [self log:@"remounting"]; if (do_remount(kslide) == KERN_SUCCESS) { [self bootstrap]; } else { [self log:@"ERROR: failed to remount system partition \n"]; } } - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator { if (context.nextFocusedView == self.goButton) { // set background color self.goButton.backgroundColor = [UIColor redColor]; } } //we know retrying with reboot, and if we detect faiure wait a few seconds and try again to force a reboot - (void)kludgeBoot { LOG("== Auto retrying in 3 seconds to trigger reboot =="); [self log:@"== Auto retrying in 3 seconds to trigger reboot =="]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self go:nil]; }); } - (void)bootstrap { [self log:@"bootstrapping"]; // _force = NO; if (_force == YES) { //_force = YES; [self log:@"(forcing reinstall)"]; } if (do_bootstrap(_force) == KERN_SUCCESS) { [self finish]; } else { [self log:@"ERROR: failed to bootstrap \n"]; } } + (NSString *)returnForProcess:(NSString *)call { if (call==nil) return 0; char line[200]; NSLog(@"running process: %@", call); FILE* fp = popen([call UTF8String], "r"); NSMutableArray *lines = [[NSMutableArray alloc]init]; if (fp) { while (fgets(line, sizeof line, fp)) { NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding]; s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; [lines addObject:s]; } } pclose(fp); return [lines componentsJoinedByString:@"\n"]; } - (void)finish { NSString *hostname = [ViewController returnForProcess:@"/bin/hostname"]; [self log:@"device is now jailbroken!"]; [self log:@""]; [self log:[NSString stringWithFormat:@"SSH server is ready at %@.local", hostname]]; [self log:@"change your root/mobile passwords"]; [self log:@""]; [self log:@"reloading daemons..."]; sleep(2); RunCmd("/usr/libexec/substrate"); LOG("reloading daemons..."); pid_t pid; posix_spawn(&pid, "/bin/launchctl", 0, 0, (char**)&(const char*[]){"/bin/launchctl", "load", "/Library/LaunchDaemons/0.reload.plist", NULL}, NULL); waitpid(pid, 0, 0); sleep(2); dispatch_async(dispatch_get_main_queue(), ^{ respringNeeded = YES; [self log:@""]; [self log:@"respring to reload Applications and Tweaks"]; [self.goButton setTitle:@"respring" forState:UIControlStateNormal]; self.goButton.enabled = YES; }); } - (void)showHUD { dispatch_async(dispatch_get_main_queue(), ^{ [SVProgressHUD setBackgroundColor:[UIColor clearColor]]; [SVProgressHUD show]; }); } - (void)restart { [self showHUD]; LOG("Running uicache..."); //pid_t pd; //const char* args[] = { "PineBoard", "HeadBoard", "lsd", NULL }; //posix_spawn(&pid, "/jb/usr/bin/killall", NULL, NULL, (char* const*)args, NULL); //posix_spawn(&pd, "/usr/bin/uicache", 0, 0, (char**)&(const char*[]){"/usr/bin/uicache", NULL}, NULL); //waitpid(pd, 0, 0); RunCmd("/usr/libexec/substrate"); RunCmd("/usr/bin/uicache"); } @end