Browse Source

universalize

Kevin Bradley 4 years ago
parent
commit
5a864e91af

+ 6 - 0
bootstrapTool.xcodeproj/project.pbxproj

@@ -15,6 +15,7 @@
 		325A24BF20E83F95001D1BAD /* NSObject+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A24B220E83EF8001D1BAD /* NSObject+Additions.m */; };
 		325A24C020E83F97001D1BAD /* NSString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A24B420E83EF8001D1BAD /* NSString+Additions.m */; };
 		325A24C120E83FCA001D1BAD /* InputPackageFIle.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A24B820E83EF8001D1BAD /* InputPackageFIle.m */; };
+		32B2C838236BC8270085F065 /* Universalize.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B2C837236BC8270085F065 /* Universalize.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -47,6 +48,8 @@
 		325A24BA20E83F46001D1BAD /* ErrorReturn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ErrorReturn.h; sourceTree = "<group>"; };
 		325A24BB20E83F46001D1BAD /* ErrorReturn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ErrorReturn.m; sourceTree = "<group>"; };
 		325A24C220E84033001D1BAD /* Defines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Defines.h; path = Classes/Defines.h; sourceTree = "<group>"; };
+		32B2C837236BC8270085F065 /* Universalize.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Universalize.m; sourceTree = "<group>"; };
+		32B2C839236D1BD40085F065 /* Universalize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Universalize.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -89,6 +92,8 @@
 		325A24AC20E83EF8001D1BAD /* Classes */ = {
 			isa = PBXGroup;
 			children = (
+				32B2C839236D1BD40085F065 /* Universalize.h */,
+				32B2C837236BC8270085F065 /* Universalize.m */,
 				325A24BA20E83F46001D1BAD /* ErrorReturn.h */,
 				325A24BB20E83F46001D1BAD /* ErrorReturn.m */,
 				325A24AD20E83EF8001D1BAD /* StatusPackageModel.h */,
@@ -164,6 +169,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				32B2C838236BC8270085F065 /* Universalize.m in Sources */,
 				325A24C020E83F97001D1BAD /* NSString+Additions.m in Sources */,
 				325A24BD20E83F7E001D1BAD /* InputPackage.m in Sources */,
 				325A24BC20E83F46001D1BAD /* ErrorReturn.m in Sources */,

BIN
bootstrapTool.xcodeproj/project.xcworkspace/xcuserdata/kevinbradley.xcuserdatad/UserInterfaceState.xcuserstate


+ 5 - 8
bootstrapTool/Classes/HelperClass.m

@@ -125,22 +125,19 @@
     inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
     inputLine = [inputLine stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\t"]];
     NSMutableString *newString = [[NSMutableString alloc] initWithString:inputLine];
-   
     [newString replaceOccurrencesOfString:@"      " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"     " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"    " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    [newString replaceOccurrencesOfString:@"   " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
     [newString replaceOccurrencesOfString:@"  " withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [newString length])];
+    
     NSArray *lineObjects = [newString componentsSeparatedByString:@" "];
+    
     //NSLog(@"lineObjects: %@", lineObjects);
     
     
     /*
      
-     "drwxr-xr-x",
-     "root/wheel0",
-     "2019-08-31",
-     "06:03",
-     "."
-     
-     
      "drwxr-xr-x",
      "root/wheel",
      0,

+ 69 - 9
bootstrapTool/Classes/InputPackage.m

@@ -1,6 +1,7 @@
 #import "InputPackage.h"
 #import "ErrorReturn.h"
 #import "HelperClass.h"
+#import "Universalize.h"
 
 @implementation InputPackage
 
@@ -234,6 +235,58 @@
     
 }
 
+- (BOOL)fileIsSymbolicLink:(NSString *)file {
+    
+    NSString *fileType = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:nil][NSFileType];
+    return ([fileType isEqualToString:NSFileTypeSymbolicLink] || [fileType isEqualToString:NSFileTypeDirectory]);
+}
+
+- (void)flattenIfNecessary:(NSString *)file {
+    if ([self fileIsSymbolicLink:file]){
+        DLog(@"skipping symbolic link: %@", file);
+        return;
+    }
+    NSFileManager *man = [NSFileManager defaultManager];
+    NSString *fat = [HelperClass singleLineReturnForProcess:[NSString stringWithFormat:@"/usr/bin/lipo -info %@",file]];
+    if ([fat containsString:@"Architectures"]){
+        NSString *newFile = [file stringByAppendingPathExtension:@"thin"];
+        [HelperClass singleLineReturnForProcess:[NSString stringWithFormat:@"/usr/bin/lipo -thin arm64 %@ -output %@",file, newFile]];
+        if ([man fileExistsAtPath:newFile]){
+            
+            [man removeItemAtPath:file error:nil];
+            [man moveItemAtPath:newFile toPath:file error:nil];
+        }
+        int uni = [Universalize universalize:file];
+        if (uni == 1){
+            DLog(@"Universalized %@ successfully!", file);
+            [self codesignRetainingSignature:file];
+        } else {
+            DLog(@"Universalize %@ failed or non zero!: %d", file, uni);
+        }
+        // @"sudo lipo -thin arm64 $input.og -output $input";
+    }
+}
+
+- (void)codesignRetainingSignature:(NSString *)file {
+    
+    NSString *jtp = [HelperClass singleLineReturnForProcess:@"/usr/bin/which jtool"];
+    if (jtp){
+        
+        [[NSFileManager defaultManager] removeItemAtPath:@"/tmp/ent.plist" error:nil];
+        [HelperClass singleLineReturnForProcess:[NSString stringWithFormat:@"%@ %@ --ent > /tmp/ent.plist", jtp, file]];
+        NSString *ents = [HelperClass singleLineReturnForProcess:@"/bin/cat /tmp/ent.plist"];
+        DLog(@"ents: %@", ents);
+        NSString *runCommand = [NSString stringWithFormat:@"%@ --sign platform %@ --ent /tmp/ent.plist --inplace", jtp, file];
+        
+        DLog(@"running codesign command: %@", runCommand);
+        
+        NSString *returnValue = [HelperClass singleLineReturnForProcess:runCommand];
+        
+        DLog(@"returnValue: %@", returnValue);
+        
+    }
+}
+
 - (void)codesignIfNecessary:(NSString *)file {
     
     if (![[[file pathExtension] lowercaseString] isEqualToString:@"dylib"]){
@@ -248,28 +301,34 @@
         NSLog(@"proc: %@", proc);
         
         if ([proc containsString:@"No Code Signing blob detected in this file"]){
-        
+            
             NSString *runCommand = [NSString stringWithFormat:@"%@ --sign platform %@ --inplace", jtp, file];
             
             NSLog(@"running codesign command: %@", runCommand);
             
-           NSString *returnValue = [HelperClass singleLineReturnForProcess:runCommand];
+            NSString *returnValue = [HelperClass singleLineReturnForProcess:runCommand];
             
             NSLog(@"returnValue: %@", returnValue);
         }
     }
 }
 
+- (void)flattenInPath:(NSString *)thePath {
+    
+    [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        NSString *file = [thePath stringByAppendingPathComponent:obj.path];
+        NSLog(@"check sig file: %@", obj.path);
+        [self flattenIfNecessary:file];
+    }];
+    
+}
+
 - (void)validateSignaturesInPath:(NSString *)thePath {
     
     [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-       
         NSString *file = [thePath stringByAppendingPathComponent:obj.path];
-        
         NSLog(@"check sig file: %@", file);
         [self codesignIfNecessary:file];
-        
-        
     }];
     
 }
@@ -417,8 +476,8 @@
                 
                 __block NSInteger markedForDeath = NSNotFound;
                 [lines enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
-                   
-                  //  DLog(@"obj: %@", obj);
+                    
+                    //  DLog(@"obj: %@", obj);
                     
                     if ([obj rangeOfString:@"uicache"].location != NSNotFound){
                         
@@ -434,7 +493,7 @@
                 }];
                 
                 if (markedForDeath != NSNotFound){
-                
+                    
                     [lines removeObjectAtIndex:markedForDeath];
                     NSString *newString = [lines componentsJoinedByString:@"\n"];
                     [newString writeToFile:postinst atomically:TRUE];
@@ -467,6 +526,7 @@
     
     NSArray *ignoreFiles = @[@".fauxsu", @".DS_Store"];
     NSArray *forbiddenRoots = @[@"etc", @"var", @"tmp"];
+    [self flattenInPath:tmpPath];
     //__block NSMutableArray *_overwriteArray = [NSMutableArray new];
     [self.files enumerateObjectsUsingBlock:^(InputPackageFile * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
         

+ 12 - 0
bootstrapTool/Classes/Universalize.h

@@ -0,0 +1,12 @@
+//
+//  Universalize.h
+//  bootstrapTool
+//
+//  Created by Kevin Bradley on 11/1/19.
+//  Copyright © 2019 nito. All rights reserved.
+//
+
+@interface Universalize: NSObject
++ (int)universalize:(NSString *)path;
+@end
+

+ 60 - 0
bootstrapTool/Classes/Universalize.m

@@ -0,0 +1,60 @@
+//
+//  Universalize.m
+//  bootstrapTool
+//
+//  Created by Kevin Bradley on 10/31/19.
+//  Copyright © 2019 nito. All rights reserved.
+//
+
+#include <Foundation/Foundation.h>
+#include <mach-o/loader.h>
+#import "Universalize.h"
+
+@implementation Universalize
+
++ (int)universalize:(NSString *)path {
+    
+    int fd = open([path UTF8String], O_RDWR);
+    if (fd < 0) {
+        perror("open");
+        return -2;
+    }
+    char header[4096];
+    struct mach_header_64* mh = (struct mach_header_64*)header;
+    if (4096 != pread(fd, header, 4096, 0))
+    {
+        perror("read");
+        return -3;
+    }
+    BOOL patched = false;
+    struct load_command* lc = (struct load_command*)(mh + 1);
+    for (int i = 0; i < mh->ncmds; i++) {
+        if (lc->cmd == LC_VERSION_MIN_IPHONEOS) {
+            puts("patching");
+            patched = true;
+            lc->cmd = LC_VERSION_MIN_TVOS;
+        } else if (lc->cmd == LC_BUILD_VERSION) {
+            struct build_version_command *bvc = (struct build_version_command*)lc;
+            if (bvc->platform == PLATFORM_IOS){
+                puts("patching");
+                bvc->platform = PLATFORM_TVOS;
+                patched = true;
+            }
+        }
+        lc = (struct load_command*)(((char*)lc) + lc->cmdsize);
+    }
+    if (4096 != pwrite(fd, header, 4096, 0))
+    {
+        perror("write");
+        return -4;
+    }
+    if (patched){
+        return 1;
+    }
+    return 0;
+}
+
+@end
+
+
+