123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- //
- // nitoInstaller.m
- // nitotvinstaller
- //
- // Created by Kevin Bradley on 1/31/18.
- // Copyright © 2018 Kevin Bradley. All rights reserved.
- //
- #include <objc/runtime.h>
- #include <libgen.h>
- #include <dlfcn.h>
- #include <CoreFoundation/CoreFoundation.h>
- #ifdef ARM
- #include <Foundation/Foundation.h> // NSObject
- #endif
- #import "nitoInstaller.h"
- #include<stdio.h>
- //#include<conio.h>
- #include<string.h>
- #define CORE_SERVICE_FRAMEWORK "/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices"
- NSObject * workspace; // Intentionally void * so as to NOT involve @interface files
- @interface LSApplicationWorkspace: NSObject
- - (id)allApplications;
- - (void)openApplicationWithBundleID:(NSString *)string;
- - (id)defaultWorkspace;
- @end
- void get_string(char *string);
- @implementation nitoInstaller
- - (NSString *)airPlayVersionNumber
- {
- NSDictionary *infoDictionary = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/PrivateFrameworks/AirPlaySupport.framework/Info.plist"];
- return infoDictionary[@"CFBundleVersion"];
-
- }
- + (NSString *)getTextWithPrompt:(NSString *)thePrompt
- {
- NSString *prompt = [NSString stringWithFormat:@"\n%@ ", thePrompt];
- fprintf(stdout, "%s", [prompt UTF8String]);
-
- NSString *thestring = [NSString.alloc initWithData:
- [NSFileHandle.fileHandleWithStandardInput availableData]
- encoding:NSUTF8StringEncoding];
-
- return [thestring stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- }
- - (NSString *)tarPathForCurrentMode
- {
- NSString *path = nil;
- switch (self.versionState) {
- case InstallVersionStateNine:
-
- path= @"/usr/bin/tar";
- break;
-
- case InstallVersionStateTenOne:
-
- path= @"/tmp/usr/bin/tar"; //need to verify
- break;
-
- case InstallVersionStateTenTwo:
-
- path= @"/usr/bin/tar";
- break;
-
- case InstallVersionStateEleven:
-
- path= @"/jb/usr/bin/tar";
- break;
- default:
- break;
- }
- return path;
- }
- - (NSString *)bootstrapPathForVersion:(NSString *)swVers
- {
- NSString *bootstrapPath = @"https://nitosoft.com/ATV4/bootstraps/";
- {
- OurLog(@"srcvers: %@", swVers);//352.18.1 == 11.0, 353.50 = 11.1
- if ([swVers compare:@"352.18.1" options:NSNumericSearch] != NSOrderedAscending)
- {
- OurLog(@"11.x or greater!");
- self.versionState = InstallVersionStateEleven;
- bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
- } else if([swVers compare:@"320.20.1" options:NSNumericSearch] != NSOrderedAscending)
- {
- OurLog(@"10.2.2 or greater!");
- self.versionState = InstallVersionStateTenTwo;
- bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
- } else if([swVers compare:@"301.44.3" options:NSNumericSearch] != NSOrderedAscending)
- {
- OurLog(@"10.0 or greater");
- self.versionState = InstallVersionStateTenOne;
- bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
- } else {
- OurLog(@"9.0 or greater?");
- self.versionState = InstallVersionStateNine;
- bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap9.tar"];
-
- }
-
- }
- return bootstrapPath;
- }
- + (int)returnForProcess:(NSString *)call
- {
- if (call==nil)
- return 0;
- char line[200];
-
- 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]];
- OurLog(@"%@",s);
- // [lines addObject:s];
- }
- }
- int returnStatus = pclose(fp);
- return returnStatus;
- }
- int main(int argc, const char * argv[]) {
- NSString *runPath = [[NSFileManager defaultManager] currentDirectoryPath];
- nitoInstaller *installer = [nitoInstaller new];
- //checking for dpkg status file might not be the most elegant check, but if its there we should have bootstrap installed
- NSString *fileCheck = @"/var/lib/dpkg/status";
- OurLog(@"\n\nWelcome to the nitoTV 2.0 & bootstrap installer script! Version 1.1");
- OurLog(@"\nWe will detect your tvOS version and install the compatible bootstrap nitoTV, upon completion nitoTV should appear on your AppleTV\n\n");
- if ([[NSFileManager defaultManager] fileExistsAtPath:fileCheck])
- {
- char c;
- printf("\nIt appears you have already installed nitoTV and the bootstrap, it is NOT recommended to do this again, are you sure you want to continue? [y/n]?");
- c=getchar();
- while(c!='y' && c!='n')
- {
- if (c!='\n'){
- printf("[y/n]");
- }
- c=getchar();
- }
-
- if (c == 'n')
- {
- OurLog(@"\nsmart move... exiting\n");
- return 0;
- } else if (c == 'y') {
- OurLog(@"\nits your funeral....\n");
- }
- }
- [installer installPackageInPath:runPath];
-
- CFRunLoopRun();
- return 0;
-
- }
- - (void)openApp:(NSString *)bundleID;
- {
- Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace"); if (!LSApplicationWorkspace_class) {fprintf(stderr,"Unable to get Workspace class\n"); } workspace = [LSApplicationWorkspace_class performSelector:@selector (defaultWorkspace)]; if (!workspace) {fprintf(stderr,"Unable to get Workspace\n"); }
- void *CS_handle = dlopen (CORE_SERVICE_FRAMEWORK, RTLD_NOW); if (!CS_handle) {
- fprintf(stderr,"Can't find %s!\n", CORE_SERVICE_FRAMEWORK);
- return;
- }
-
- if (workspace){
- [workspace performSelector:@selector(openApplicationWithBundleID:) withObject:(id) bundleID ];
- }
-
-
- }
- - (void)installPackageInPath:(NSString *)thePath
- {
- NSString *bootstrapPath = [self bootstrapPathForVersion:[self airPlayVersionNumber]];
-
- NSURL *url = [NSURL URLWithString:bootstrapPath];
- OurLog(@"Downloading file: %@", bootstrapPath);
- NSString *downloadLocation = [thePath stringByAppendingPathComponent:bootstrapPath.lastPathComponent];
-
-
- self.downloader = [URLDownloader new];
- [self.downloader downloadFileWithURL:url toLocation:downloadLocation withCredential:nil completed:^(NSString *downloadedFile) {
- OurLog(@"Download complete: %@", downloadedFile);
-
- OurLog(@"Installing...");
- NSString *tarPath = [self tarPathForCurrentMode];
-
- OurLog(@"Extracting tar...");
-
- NSString *installString = [NSString stringWithFormat:@"%@ fxpv %@ -C / ; echo \"Starting Substrate\" ; /usr/libexec/substrate ; echo \"running uicache...\" ; /usr/bin/uicache ; /usr/bin/bash /usr/libexec/nito/firmware.sh ; rm /var/mobile/Library/Preferences/Featured.plist", tarPath, downloadedFile];
-
- OurLog(@"install string: %@", installString);
-
-
- [nitoInstaller returnForProcess:installString];
- if (self.versionState == InstallVersionStateNine)
- {
- [nitoInstaller returnForProcess:@"/usr/bin/killall -9 PineBoard HeadBoard lsd nitoTV"];
- sleep(35);
- } else {
-
- sleep(10);
- }
-
- [self openApp:@"com.nito.nitoTV4"];
-
- CFRunLoopStop(CFRunLoopGetCurrent());
- }];
- }
- @end
|