Browse Source

changed to newer version of download that doesnt mess up the checksums, updated checksums. sign with ldid to make sure itll work on 9 and 10.

Kevin Bradley 6 years ago
parent
commit
878dd1df2f

+ 40 - 1
README.md

@@ -1,3 +1,42 @@
 # nitoTVInstaller
 
-installer for nitoTV4 on tvOS
+## Targets
+
+This project comproises of two different installation methods for our jailbreak bootstrap + nitoTV 4 for tvOS.
+
+**nitoTV4Installer** is a native Mac OS X application that will download and install a bootstrap to your AppleTV depending on which one you choose from the Airplay dropdown menu.
+
+**MAC OS 10.11 SDK is required to build this target**
+
+**tool** is a command line utility that runs natively on the AppleTV itself, it will determine which bootstrap is appropriate and install it as necessary.
+
+## Usage
+
+### Mac OS X Installer
+
+1. Make sure your AppleTV on 9.0, 9.1, or 10.1 is jailbroken and awake and that Airplay is ON
+2. Open the nitoTV4Installer application
+3. Choose your AppleTV from the dropdown menu
+4. Click install payload
+5. Wait & Enjoy
+
+### Native CLI Tool 
+
+1. SCP nitoTVInstaller over to your AppleTV with Terminal app on mac or putty on windows (after building it will be in the standalone folder)
+ 
+ 	`scp nitoTVInstaller root@apple-tv.local`
+ 
+2. SSH in to your AppleTV with Terminal.app or putty
+	
+	`ssh root@apple-tv.local`
+	
+3. Run this command directly on the AppleTV
+
+	`./nitoTVInstaller`
+	
+4. Wait & Enjoy
+	
+
+
+
+

+ 29 - 9
nitoTV4Installer/AppDelegate.m

@@ -88,6 +88,9 @@ static NSString *appleTVAddress = nil;
     
 }
 
+
+
+
 - (void)downloadFile:(NSString *)thePayload toLocation:(NSString *)downloadLocation
 {
     //statusLabel.stringValue = [NSString stringWithFormat:@"Downloading: %@...", thePayload.lastPathComponent];
@@ -96,7 +99,23 @@ static NSString *appleTVAddress = nil;
     //get the stream we want to download
     
     
-    
+	[downloadFile downloadURL:[NSURL URLWithString:thePayload] toLocation:downloadLocation progress:^(double percentComplete) {
+		
+		[self setDownloadProgress:percentComplete];
+		
+	} completed:^(NSString *downloadedFile) {
+		self.downloading = false;
+		
+		[self setDownloadProgress:0];
+		statusLabel.stringValue = [NSString stringWithFormat:@"Uploading file %@....", downloadedFile.lastPathComponent];
+		
+		
+		[self handleDownloadFile:downloadedFile];
+		
+	}];
+	
+	return;
+	
     [downloadFile downloadFileWithURL:[NSURL URLWithString:thePayload] toLocation:downloadLocation progress:^(double percentComplete) {
         
         [self setDownloadProgress:percentComplete];
@@ -141,18 +160,19 @@ static NSString *appleTVAddress = nil;
     
     if ([FM fileExistsAtPath:downloadLocation])
     {
-        NSString *hash = @"59293ffbdee698488aba799a96fcfe95e1165fa10f760362a2ce910576134e39";
+        NSString *hash = @"9e021bd57a31155bfdd05f1cec42a2ba9d0f2c00d4d0e66962b0240d66435577";
         switch (self.versionState) {
             case KBInstallVersionStateEleven:
             case KBInstallVersionStateTenTwo:
-                
-                hash = @"59293ffbdee698488aba799a96fcfe95e1165fa10f760362a2ce910576134e39";
+			case KBInstallVersionStateTenOne:
+				
+		        hash = @"9e021bd57a31155bfdd05f1cec42a2ba9d0f2c00d4d0e66962b0240d66435577";
                 break;
                 
             case KBInstallVersionStateNine:
-            case KBInstallVersionStateTenOne:
+				
                 
-                hash = @"327c7cea49282109e23c9415d318121f91b79ca7bb813c8724a1c0752e8311af";
+                hash = @"e9f68bc562b6f675839437e87d37d5d996f3aafb2d62e7c6cb2c60eb6181ea10";
                 break;
                 
             default:
@@ -165,7 +185,7 @@ static NSString *appleTVAddress = nil;
         if (!verify)
         {
             NSLog(@"invalid selection");
-            NSAlert *alert = [NSAlert alertWithMessageText:@"This payload does not match our checksum, if you did not modify the payload you should not proceed any further! Otherwise press continue."
+            NSAlert *alert = [NSAlert alertWithMessageText:@"This payload does not match our checksum, if you did not modify the payload you should click Download Again! Otherwise press continue."
                                              defaultButton:@"Cancel"
                                            alternateButton:@"Continue"
                                                otherButton:@"Download Again"
@@ -241,7 +261,7 @@ static NSString *appleTVAddress = nil;
                     NSString *tarString = [self tarPathForCurrentMode];
                     NSString *bootstrap = [NSString stringWithFormat:@"/var/mobile/Documents/%@", downloadedFile.lastPathComponent];
                     
-                    NSString *installCommand = [NSString stringWithFormat:@"%@ fxpv %@ -C / ; /usr/libexec/substrate ; /usr/bin/uicache  ; /bin/bash /usr/libexec/nito/firmware.sh ; rm /var/mobile/Library/Preferences/Featured.plist", tarString, bootstrap];
+                    NSString *installCommand = [NSString stringWithFormat:@"%@ fxpv %@ -C / ; /usr/libexec/substrate ; /usr/bin/uicache  ; /usr/bin/bash /usr/libexec/nito/firmware.sh ; rm /var/mobile/Library/Preferences/Featured.plist", tarString, bootstrap];
                     
                     
                     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
@@ -752,7 +772,7 @@ static NSString *appleTVAddress = nil;
             {
                 NSLog(@"10.0 or greater");
                 self.versionState = KBInstallVersionStateTenOne;
-                bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap9.tar"];
+                bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
             } else {
                 NSLog(@"9.0 or greater?");
                 self.versionState = KBInstallVersionStateNine;

+ 2 - 2
nitoTV4Installer/Info.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
+	<string>1.1</string>
 	<key>CFBundleVersion</key>
-	<string>1</string>
+	<string>2</string>
 	<key>LSMinimumSystemVersion</key>
 	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
 	<key>NSAppTransportSecurity</key>

+ 6 - 1
nitoTV4Installer/KBDownloadFile.h

@@ -25,6 +25,7 @@
 @end
 
 
+
 @interface KBDownloadFile : NSObject <NSURLDownloadDelegate>  {
 	
 	NSURLDownload				*urlDownload;
@@ -37,6 +38,8 @@
 
 }
 
+typedef void (^CompletionHandler)();
+@property NSMutableDictionary <NSString *, CompletionHandler>*completionHandlers;
 @property (strong, atomic) void (^ProgressBlock)(double percentComplete);
 @property (strong, atomic) void (^FancyProgressBlock)(double percentComplete, NSString *status);
 @property (strong, atomic) void (^CompletedBlock)(NSString *downloadedFile);
@@ -48,7 +51,9 @@ typedef void(^DownloadCompletedBlock)(NSString *downloadedFile);
 @property (nonatomic, retain) NSString *downloadLocation;
 @property (readwrite, assign) NSInteger downloadMode; //0 = muxed file, 1 = demuxed tracks
 
-
+- (void)downloadURL:(NSURL *)url toLocation:(NSString *)dlLocation
+		   progress:(DownloadProgressBlock)progressBlock
+		  completed:(DownloadCompletedBlock)completedBlock;
 
 - (void)downloadFileWithURL:(NSURL *)url
                  toLocation:(NSString *)dlLocation

+ 107 - 0
nitoTV4Installer/KBDownloadFile.m

@@ -57,6 +57,113 @@
 }
 
 
+- (void)downloadURL:(NSURL *)url toLocation:(NSString *)dlLocation
+		   progress:(DownloadProgressBlock)progressBlock
+		  completed:(DownloadCompletedBlock)completedBlock
+{
+	self.CompletedBlock = completedBlock;
+	self.ProgressBlock = progressBlock;
+	self.downloadLocation = dlLocation;
+
+	NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"com.nito.installer"];
+	
+	// Creating sessions
+	NSOperationQueue *operationQueue = [NSOperationQueue mainQueue];
+	
+	NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:operationQueue];
+	NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithURL:url];
+	[downloadTask resume];
+	
+	
+}
+
+- (void)URLSession:(NSURLSession *)session
+	  downloadTask:(NSURLSessionDownloadTask *)downloadTask
+	  didWriteData:(int64_t)bytesWritten
+ totalBytesWritten:(int64_t)totalBytesWritten
+totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
+{
+	//NSLog(@"Session %@ download task %@ wrote an additional %lld bytes (total %lld bytes) out of an expected %lld bytes.\n", session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
+	if (totalBytesExpectedToWrite != NSURLResponseUnknownLength) {
+		
+		double percentComplete=(totalBytesWritten/(float)totalBytesExpectedToWrite)*100.0;
+		// NSLog(@"Percent complete - %f",percentComplete);
+		
+		if((freq%updateFrequency) == 0){
+			
+			if (self.ProgressBlock != nil)
+			{
+				self.ProgressBlock(percentComplete);
+			}
+			
+			if (self.FancyProgressBlock != nil)
+			{
+				NSString *mediaType = @"media";
+				NSString *pathExt = downloadLocation.pathExtension;
+				if ([pathExt isEqualToString:@"m4v"])
+				{
+					mediaType = @"video";
+				} else if ([pathExt isEqualToString:@"aac"])
+				{
+					mediaType = @"audio";
+				}
+				self.FancyProgressBlock(percentComplete, [NSString stringWithFormat:@"Downloading %@ file...", mediaType]);
+			}
+		}
+		freq++;
+		
+	} else {
+		
+		NSLog(@"Bytes received - %lld",totalBytesWritten);
+		
+	}
+	
+	
+}
+
+- (void)URLSession:(NSURLSession *)session
+	  downloadTask:(NSURLSessionDownloadTask *)downloadTask
+ didResumeAtOffset:(int64_t)fileOffset
+expectedTotalBytes:(int64_t)expectedTotalBytes
+{
+	NSLog(@"Session %@ download task %@ resumed at offset %lld bytes out of an expected %lld bytes.\n", session, downloadTask, fileOffset, expectedTotalBytes);
+}
+
+- (void)URLSession:(NSURLSession *)session
+	  downloadTask:(NSURLSessionDownloadTask *)downloadTask
+didFinishDownloadingToURL:(NSURL *)location
+{
+	NSLog(@"Session %@ download task %@ finished downloading to URL %@\n", session, downloadTask, location);
+	
+	// Perform the completion handler for the current session
+	//self.completionHandlers[session.configuration.identifier]();
+	
+	// Open the downloaded file for reading
+	//NSError *readError = nil;
+	//NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:location error:&readError];
+	// ...
+	
+	// Move the file to a new URL
+	NSFileManager *fileManager = [NSFileManager defaultManager];
+	//NSURL *cacheDirectory = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] firstObject];
+	NSError *moveError = nil;
+	if ([fileManager fileExistsAtPath:self.downloadLocation])
+	{
+		[fileManager removeItemAtPath:self.downloadLocation error:nil];
+	}
+	if ([fileManager moveItemAtPath:location.path toPath:self.downloadLocation error:&moveError])
+	{
+		self.CompletedBlock(self.downloadLocation);
+	} else {
+		NSLog(@"error: %@", moveError);
+	}
+	/*
+	if ([fileManager moveItemAtURL:location toURL:cacheDirectory error:&moveError]) {
+		// ...
+	}
+	 */
+}
+
 //deprecated / obsolete, SHOULD still work but should never be used.
 - (void)downloadFileWithURL:(NSURL *)url
                  toLocation:(NSString *)dlLocation

+ 4 - 2
nitoTV4Installer/standalone/Makefile

@@ -2,11 +2,13 @@ CC=`xcrun -v -sdk appletvos clang`
 
 nitoInstaller: nitoInstaller.m Download/URLDownloader.m
 	xcrun -v -sdk appletvos clang -fobjc-arc -arch arm64 -IDownload -framework Foundation -framework MobileCoreServices -o nitoInstaller nitoInstaller.m Download/URLDownloader.m Download/URLCredential.m
-	jtool --sign platform nitoInstaller --inplace
+#jtool --sign platform nitoInstaller --inplace
+		ldid -S nitoInstaller
 
 lsdtrip: ls.m
 	xcrun -v -sdk appletvos clang -arch arm64 ls.m -framework Foundation -framework MobileCoreServices -o lsdtrip
-	jtool --sign platform lsdtrip --inplace
+	ldid -S lsdtrip
+#jtool --sign platform lsdtrip --inplace
 
 all: nitoInstaller lsdtrip
 clean:

BIN
nitoTV4Installer/standalone/lsdtrip


BIN
nitoTV4Installer/standalone/nitoInstaller


+ 6 - 3
nitoTV4Installer/standalone/nitoInstaller.m

@@ -102,7 +102,7 @@ void get_string(char *string);
         {
             OurLog(@"10.0 or greater");
             self.versionState = InstallVersionStateTenOne;
-            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap9.tar"];
+            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
         } else {
             OurLog(@"9.0 or greater?");
             self.versionState = InstallVersionStateNine;
@@ -144,7 +144,7 @@ int main(int argc, const char * argv[]) {
     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!");
+    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])
     {
@@ -205,7 +205,10 @@ int main(int argc, const char * argv[]) {
         
         OurLog(@"Installing...");
         NSString *tarPath = [self tarPathForCurrentMode];
-        NSString *installString = [NSString stringWithFormat:@"%@ fxpv %@ -C / ; /usr/libexec/substrate ; /usr/bin/uicache  ; /bin/bash /usr/libexec/nito/firmware.sh ; rm /var/mobile/Library/Preferences/Featured.plist", tarPath, downloadedFile];
+		
+		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);