diff --git a/.gitmodules b/.gitmodules index 0f2879c3..00ed9c25 100644 --- a/.gitmodules +++ b/.gitmodules @@ -54,10 +54,6 @@ path = Dependencies/em_proxy url = https://github.com/SideStore/em_proxy branch = master -[submodule "Dependencies/libfragmentzip"] - path = Dependencies/libfragmentzip - url = https://github.com/SideStore/libfragmentzip - branch = master [submodule "Dependencies/apps-v2.json"] path = Dependencies/apps-v2.json url = https://github.com/SideStore/apps-v2.json diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index dfca3ab2..66fb20e3 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -93,11 +93,9 @@ A8B646012D70C23E00125819 /* MarkdownKit in Frameworks */ = {isa = PBXBuildFile; productRef = A8B646002D70C23E00125819 /* MarkdownKit */; }; A8C2260E2EC9039A00047C0D /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = A8C2260D2EC9039A00047C0D /* Nuke */; }; A8EB89C22F5448B20094BC01 /* em_proxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BD2F652F543FD40045335F /* em_proxy.swift */; }; - A8EB89CA2F54519C0094BC01 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8EB89C92F54519C0094BC01 /* libfragmentzip.a */; }; A8EB89CC2F5451AF0094BC01 /* Minimuxer in Frameworks */ = {isa = PBXBuildFile; productRef = A8EB89CB2F5451AF0094BC01 /* Minimuxer */; }; A8EB89CE2F5451B50094BC01 /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = A8EB89CD2F5451B50094BC01 /* SemanticVersion */; }; A8EB89D02F5451C20094BC01 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = A8EB89CF2F5451C20094BC01 /* KeychainAccess */; }; - A8EB89D12F5451E90094BC01 /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8BD2F6D2F543FFF0045335F /* libcurl.a */; }; A8EB955C2F5455B30094BC01 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = A8BD30312F5440300045335F /* debug.c */; }; A8EB95C92F5455FE0094BC01 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = A8BD30302F5440300045335F /* debug.h */; }; A8EB96042F54561E0094BC01 /* afc.c in Sources */ = {isa = PBXBuildFile; fileRef = A8BD30932F5440300045335F /* afc.c */; }; @@ -231,41 +229,6 @@ remoteGlobalIDString = CA60C44C93D7916DE57E6EBD; remoteInfo = "em_proxy-staticlib"; }; - A8EB8CC32F5453CD0094BC01 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 87B8C3401E0E9C37002F817D; - remoteInfo = "fragmentzip-cli-macOS"; - }; - A8EB8CC52F5453CD0094BC01 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B315FDB02866CCF8002E243C; - remoteInfo = "fragmentzip-cli-iOS"; - }; - A8EB8CC72F5453CD0094BC01 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B315FDB52866CD91002E243C; - remoteInfo = "fragmentzip-macOS"; - }; - A8EB8CC92F5453CD0094BC01 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = B315FDCE2866CDD3002E243C; - remoteInfo = "fragmentzip-iOS"; - }; - A8EB8CCE2F5453CD0094BC01 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = A8BD2FD72F5440300045335F /* libgeneral.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 87977F6F227C4B71004F31DA; - remoteInfo = libgeneral; - }; BF66EE832501AE50007EE018 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFD247622284B9A500981D42 /* Project object */; @@ -361,6 +324,10 @@ A8036E7F2F54606400097AF1 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; A8036EA72F54642D00097AF1 /* libimobiledevice.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libimobiledevice.a; sourceTree = BUILT_PRODUCTS_DIR; }; A8037A0D2F54664300097AF1 /* libem_proxy_swift.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libem_proxy_swift.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A84596F12F7DC4C90000B8CD /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; + A84596F22F7DC4C90000B8CD /* .gitmodules */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitmodules; sourceTree = ""; }; + A84596F32F7DC4C90000B8CD /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + A84596F42F7DC4C90000B8CD /* trustedapps.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = trustedapps.json; sourceTree = ""; }; A8635D052F4CF16D00E66784 /* OpenSSL.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:67RAULRX93:Marcin Krzyzanowski"; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = Dependencies/AltSign/Dependencies/OpenSSL.xcframework; sourceTree = ""; }; A8945AA52D059B6100D86CBE /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A8BD20292F543FD40045335F /* client_privatekey */ = {isa = PBXFileReference; lastKnownFileType = text; path = client_privatekey; sourceTree = ""; }; @@ -381,26 +348,12 @@ A8BD2F692F543FD40045335F /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; A8BD2F6A2F543FD40045335F /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; A8BD2F6B2F543FD40045335F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - A8BD2F6D2F543FFF0045335F /* libcurl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libcurl.a; sourceTree = ""; }; A8BD2FA62F54401E0045335F /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; A8BD2FA72F54401E0045335F /* NSAttributedString+Markdown.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+Markdown.h"; sourceTree = ""; }; A8BD2FA82F54401E0045335F /* NSAttributedString+Markdown.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+Markdown.m"; sourceTree = ""; }; A8BD2FA92F54401E0045335F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; A8BD2FBD2F5440300045335F /* em_proxy.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = em_proxy.xcodeproj; sourceTree = ""; }; A8BD2FBE2F5440300045335F /* fetch-prebuilt.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "fetch-prebuilt.sh"; sourceTree = ""; }; - A8BD2FD72F5440300045335F /* libgeneral.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = libgeneral.xcodeproj; sourceTree = ""; }; - A8BD2FDB2F5440300045335F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - A8BD2FE02F5440300045335F /* curl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = curl.h; sourceTree = ""; }; - A8BD2FE12F5440300045335F /* curlbuild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = curlbuild.h; sourceTree = ""; }; - A8BD2FE42F5440300045335F /* curlrules.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = curlrules.h; sourceTree = ""; }; - A8BD2FE52F5440300045335F /* curlver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = curlver.h; sourceTree = ""; }; - A8BD2FE62F5440300045335F /* easy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = easy.h; sourceTree = ""; }; - A8BD2FE82F5440300045335F /* mprintf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mprintf.h; sourceTree = ""; }; - A8BD2FE92F5440300045335F /* multi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = multi.h; sourceTree = ""; }; - A8BD2FEA2F5440300045335F /* stdcheaders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stdcheaders.h; sourceTree = ""; }; - A8BD2FEB2F5440300045335F /* typecheck-gcc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "typecheck-gcc.h"; sourceTree = ""; }; - A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = libfragmentzip.xcodeproj; sourceTree = ""; }; - A8BD30012F5440300045335F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; A8BD30062F5440300045335F /* add_scalar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = add_scalar.c; sourceTree = ""; }; A8BD30072F5440300045335F /* ed25519.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ed25519.h; sourceTree = ""; }; A8BD30082F5440300045335F /* fe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fe.h; sourceTree = ""; }; @@ -568,8 +521,6 @@ A8BD325F2F5440300045335F /* minimuxer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = minimuxer; sourceTree = ""; }; A8BD32D02F5440300045335F /* Roxas.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = Roxas.xcodeproj; sourceTree = ""; }; A8BD32FA2F54444D0045335F /* AltSign */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = AltSign; sourceTree = ""; }; - A8EB89C72F5451970094BC01 /* libfragmentzip.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libfragmentzip.a; sourceTree = BUILT_PRODUCTS_DIR; }; - A8EB89C92F54519C0094BC01 /* libfragmentzip.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libfragmentzip.a; sourceTree = BUILT_PRODUCTS_DIR; }; B3C39606284F4C8400DA9E2F /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; B3C39607284F4C8400DA9E2F /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; B3C39608284F4C8400DA9E2F /* CodeSigning.xcconfig.sample */ = {isa = PBXFileReference; lastKnownFileType = text; path = CodeSigning.xcconfig.sample; sourceTree = ""; }; @@ -644,7 +595,6 @@ isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( Info.plist, - "Operations/Patch App/ALTAppPatcher.m", Resources/ReleaseEntitlements.plist, ); target = BFD247692284B9A500981D42 /* SideStore */; @@ -686,14 +636,6 @@ ); target = BF989166250AABF3002ACF50 /* AltWidgetExtension */; }; - A8FAC1FE2F4B52F40061A851 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - "Operations/Patch App/ALTAppPatcher.h", - "Operations/Patch App/ALTAppPatcher.m", - ); - target = BF66EE7D2501AE50007EE018 /* AltStoreCore */; - }; /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ @@ -713,7 +655,7 @@ A8EEC3B92F4B0EFC00F2436D /* AltWidget */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8EEC3CA2F4B0EFC00F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = AltWidget; sourceTree = ""; }; A8EEC3D92F4B0FC800F2436D /* AltBackup */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8EEC3E22F4B0FC800F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = AltBackup; sourceTree = ""; }; A8EEC71D2F4B10D900F2436D /* xcconfigs */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = xcconfigs; sourceTree = ""; }; - A8EEC8412F4B146A00F2436D /* AltStore */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8EEC8CB2F4B146B00F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, A8EEC8CC2F4B146B00F2436D /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, A8FAC1FE2F4B52F40061A851 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, A8EEC8CD2F4B146B00F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = AltStore; sourceTree = ""; }; + A8EEC8412F4B146A00F2436D /* AltStore */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8EEC8CB2F4B146B00F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, A8EEC8CC2F4B146B00F2436D /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, A8EEC8CD2F4B146B00F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = AltStore; sourceTree = ""; }; A8EECF2A2F4B195000F2436D /* SideStore */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (A8EECF492F4B195000F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, A8EECF4A2F4B195000F2436D /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SideStore; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ @@ -769,9 +711,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A8EB89D12F5451E90094BC01 /* libcurl.a in Frameworks */, A8EB89CC2F5451AF0094BC01 /* Minimuxer in Frameworks */, - A8EB89CA2F54519C0094BC01 /* libfragmentzip.a in Frameworks */, A8037A012F54661200097AF1 /* libimobiledevice.a in Frameworks */, A8B646012D70C23E00125819 /* MarkdownKit in Frameworks */, A8037A0E2F54664300097AF1 /* libem_proxy_swift.a in Frameworks */, @@ -848,8 +788,6 @@ A8BD32FA2F54444D0045335F /* AltSign */, A8BD325F2F5440300045335F /* minimuxer */, A8BD20242F543FAD0045335F /* apps-v2.json */, - A8BD2F6E2F543FFF0045335F /* libcurl */, - A8BD30022F5440300045335F /* libfragmentzip */, A8BD325E2F5440300045335F /* libusbmuxd */, A8BD30F02F5440300045335F /* libimobiledevice */, A8036E802F54606400097AF1 /* libimobiledevice-glue */, @@ -904,14 +842,6 @@ path = em_proxy; sourceTree = ""; }; - A8BD2F6E2F543FFF0045335F /* libcurl */ = { - isa = PBXGroup; - children = ( - A8BD2F6D2F543FFF0045335F /* libcurl.a */, - ); - path = libcurl; - sourceTree = ""; - }; A8BD2FAA2F54401E0045335F /* MarkdownAttributedString */ = { isa = PBXGroup; children = ( @@ -923,58 +853,6 @@ path = MarkdownAttributedString; sourceTree = ""; }; - A8BD2FDC2F5440300045335F /* libgeneral */ = { - isa = PBXGroup; - children = ( - A8BD2FD72F5440300045335F /* libgeneral.xcodeproj */, - A8BD2FDB2F5440300045335F /* README.md */, - ); - path = libgeneral; - sourceTree = ""; - }; - A8BD2FDD2F5440300045335F /* dependencies */ = { - isa = PBXGroup; - children = ( - A8BD2FDC2F5440300045335F /* libgeneral */, - ); - path = dependencies; - sourceTree = ""; - }; - A8BD2FEC2F5440300045335F /* curl */ = { - isa = PBXGroup; - children = ( - A8BD2FE02F5440300045335F /* curl.h */, - A8BD2FE12F5440300045335F /* curlbuild.h */, - A8BD2FE42F5440300045335F /* curlrules.h */, - A8BD2FE52F5440300045335F /* curlver.h */, - A8BD2FE62F5440300045335F /* easy.h */, - A8BD2FE82F5440300045335F /* mprintf.h */, - A8BD2FE92F5440300045335F /* multi.h */, - A8BD2FEA2F5440300045335F /* stdcheaders.h */, - A8BD2FEB2F5440300045335F /* typecheck-gcc.h */, - ); - path = curl; - sourceTree = ""; - }; - A8BD2FF02F5440300045335F /* include */ = { - isa = PBXGroup; - children = ( - A8BD2FEC2F5440300045335F /* curl */, - ); - path = include; - sourceTree = ""; - }; - A8BD30022F5440300045335F /* libfragmentzip */ = { - isa = PBXGroup; - children = ( - A8BD2FDD2F5440300045335F /* dependencies */, - A8BD2FF02F5440300045335F /* include */, - A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */, - A8BD30012F5440300045335F /* README.md */, - ); - path = libfragmentzip; - sourceTree = ""; - }; A8BD301A2F5440300045335F /* ed25519 */ = { isa = PBXGroup; children = ( @@ -1290,25 +1168,6 @@ name = Products; sourceTree = ""; }; - A8EB8CBD2F5453CD0094BC01 /* Products */ = { - isa = PBXGroup; - children = ( - A8EB8CC42F5453CD0094BC01 /* libfragmentzip */, - A8EB8CC62F5453CD0094BC01 /* libfragmentzip */, - A8EB8CC82F5453CD0094BC01 /* libfragmentzip.a */, - A8EB8CCA2F5453CD0094BC01 /* libfragmentzip.a */, - ); - name = Products; - sourceTree = ""; - }; - A8EB8CCB2F5453CD0094BC01 /* Products */ = { - isa = PBXGroup; - children = ( - A8EB8CCF2F5453CD0094BC01 /* libgeneral */, - ); - name = Products; - sourceTree = ""; - }; BFD247612284B9A500981D42 = { isa = PBXGroup; children = ( @@ -1325,6 +1184,10 @@ B3C39607284F4C8400DA9E2F /* Build.xcconfig */, B3C39606284F4C8400DA9E2F /* CodeSigning.xcconfig */, B3C39608284F4C8400DA9E2F /* CodeSigning.xcconfig.sample */, + A84596F12F7DC4C90000B8CD /* .gitignore */, + A84596F22F7DC4C90000B8CD /* .gitmodules */, + A84596F32F7DC4C90000B8CD /* README.md */, + A84596F42F7DC4C90000B8CD /* trustedapps.json */, ); sourceTree = ""; }; @@ -1344,8 +1207,6 @@ BFD247852284BB3300981D42 /* Frameworks */ = { isa = PBXGroup; children = ( - A8EB89C92F54519C0094BC01 /* libfragmentzip.a */, - A8EB89C72F5451970094BC01 /* libfragmentzip.a */, A8635D052F4CF16D00E66784 /* OpenSSL.xcframework */, BF580497246A3D19008AE704 /* UIKit.framework */, BFD247862284BB3B00981D42 /* Roxas.framework */, @@ -1624,14 +1485,6 @@ ProductGroup = A8EB8CB82F5453CD0094BC01 /* Products */; ProjectRef = A8BD2FBD2F5440300045335F /* em_proxy.xcodeproj */; }, - { - ProductGroup = A8EB8CBD2F5453CD0094BC01 /* Products */; - ProjectRef = A8BD2FFB2F5440300045335F /* libfragmentzip.xcodeproj */; - }, - { - ProductGroup = A8EB8CCB2F5453CD0094BC01 /* Products */; - ProjectRef = A8BD2FD72F5440300045335F /* libgeneral.xcodeproj */; - }, { ProductGroup = A8EB8CAD2F5453CD0094BC01 /* Products */; ProjectRef = A8BD32D02F5440300045335F /* Roxas.xcodeproj */; @@ -1678,41 +1531,6 @@ remoteRef = A8EB8CBB2F5453CD0094BC01 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - A8EB8CC42F5453CD0094BC01 /* libfragmentzip */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = libfragmentzip; - remoteRef = A8EB8CC32F5453CD0094BC01 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - A8EB8CC62F5453CD0094BC01 /* libfragmentzip */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = libfragmentzip; - remoteRef = A8EB8CC52F5453CD0094BC01 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - A8EB8CC82F5453CD0094BC01 /* libfragmentzip.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfragmentzip.a; - remoteRef = A8EB8CC72F5453CD0094BC01 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - A8EB8CCA2F5453CD0094BC01 /* libfragmentzip.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfragmentzip.a; - remoteRef = A8EB8CC92F5453CD0094BC01 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - A8EB8CCF2F5453CD0094BC01 /* libgeneral */ = { - isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = libgeneral; - remoteRef = A8EB8CCE2F5453CD0094BC01 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -2453,8 +2271,6 @@ LD_WARN_UNUSED_DYLIBS = YES; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Dependencies/libfragmentzip", - "$(PROJECT_DIR)/Dependencies/libcurl", "$(PROJECT_DIR)/Dependencies/minimuxer/Sources/RustBridge/lib", ); LLVM_LTO = YES_THIN; @@ -2502,8 +2318,6 @@ LD_WARN_UNUSED_DYLIBS = YES; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Dependencies/libfragmentzip", - "$(PROJECT_DIR)/Dependencies/libcurl", "$(PROJECT_DIR)/Dependencies/minimuxer/Sources/RustBridge/lib", ); LLVM_LTO = YES_THIN; diff --git a/AltStore/AltStore-Bridging-Header.h b/AltStore/AltStore-Bridging-Header.h index f75b06b6..c8dd6ac5 100644 --- a/AltStore/AltStore-Bridging-Header.h +++ b/AltStore/AltStore-Bridging-Header.h @@ -3,6 +3,3 @@ // #import "NSAttributedString+Markdown.h" -#import "ALTAppPatcher.h" - -#include "fragmentzip.h" diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index c18261ac..f98fea59 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -942,70 +942,6 @@ extension AppManager self.run([enableJITOperation], context: context, requiresSerialQueue: true) } - func patch(resignedApp: ALTApplication, presentingViewController: UIViewController, context authContext: AuthenticatedOperationContext, completionHandler: @escaping (Result) -> Void) -> PatchAppOperation - { - final class Context: InstallAppOperationContext, PatchAppContext - { - } - - guard let originalBundleID = resignedApp.bundle.infoDictionary?[Bundle.Info.altBundleID] as? String else { - let context = Context(bundleIdentifier: resignedApp.bundleIdentifier, authenticatedContext: authContext) - completionHandler(.failure(OperationError.invalidApp)) - - return PatchAppOperation(context: context) - } - - let context = Context(bundleIdentifier: originalBundleID, authenticatedContext: authContext) - context.resignedApp = resignedApp - - let patchAppOperation = PatchAppOperation(context: context) - let sendAppOperation = SendAppOperation(context: context) - let installOperation = InstallAppOperation(context: context) - - let installationProgress = Progress.discreteProgress(totalUnitCount: 100) - installationProgress.addChild(sendAppOperation.progress, withPendingUnitCount: 40) - installationProgress.addChild(installOperation.progress, withPendingUnitCount: 60) - - /* Patch */ - patchAppOperation.resultHandler = { [weak patchAppOperation] (result) in - switch result - { - case .failure(let error): - context.error = error - case .success: - // Kinda hacky that we're calling patchAppOperation's progressHandler manually, but YOLO. - patchAppOperation?.progressHandler?(installationProgress, NSLocalizedString("Patching placeholder app...", comment: "")) - } - } - - /* Send */ - sendAppOperation.resultHandler = { (result) in - switch result - { - case .failure(let error): - context.error = error - completionHandler(.failure(error)) - case .success(_): print("App sent over AFC") - } - } - sendAppOperation.addDependency(patchAppOperation) - - - /* Install */ - installOperation.resultHandler = { (result) in - switch result - { - case .failure(let error): completionHandler(.failure(error)) - case .success(let installedApp): completionHandler(.success(installedApp)) - } - //UIApplication.shared.open(shortcutURLon, options: [:], completionHandler: nil) - } - installOperation.addDependency(sendAppOperation) - - self.run([patchAppOperation, sendAppOperation, installOperation], context: context.authenticatedContext) - return patchAppOperation - } - func installationProgress(for app: AppProtocol) -> Progress? { os_unfair_lock_lock(self.progressLock) @@ -1392,80 +1328,6 @@ private extension AppManager } } deactivateAppsOperation.addDependency(fetchProvisioningProfilesOperation) - - /* Patch App */ - let patchAppOperation = RSTAsyncBlockOperation { operation in - do - { - // Only attempt to patch app if we're installing a new app, not refreshing existing app. - // Post reboot, we install the correct jailbreak app by refreshing the patched app, - // so this check avoids infinite recursion. - guard case .install = appOperation else { - operation.finish() - return - } - - guard let presentingViewController = context.presentingViewController else { return operation.finish() } - - if let error = context.error - { - throw error - } - - guard let app = context.app else { - throw OperationError.invalidParameters("AppManager._install.patchAppOperation: context.app is nil") - } - - guard let isUntetherRequired = app.bundle.infoDictionary?[Bundle.Info.untetherRequired] as? Bool, - let minimumiOSVersionString = app.bundle.infoDictionary?[Bundle.Info.untetherMinimumiOSVersion] as? String, - let maximumiOSVersionString = app.bundle.infoDictionary?[Bundle.Info.untetherMaximumiOSVersion] as? String, - case let minimumiOSVersion = OperatingSystemVersion(string: minimumiOSVersionString), - case let maximumiOSVersion = OperatingSystemVersion(string: maximumiOSVersionString) - else { return operation.finish() } - - let iOSVersion = ProcessInfo.processInfo.operatingSystemVersion - let iOSVersionSupported = ProcessInfo.processInfo.isOperatingSystemAtLeast(minimumiOSVersion) && - (!ProcessInfo.processInfo.isOperatingSystemAtLeast(maximumiOSVersion) || maximumiOSVersion == iOSVersion) - - guard isUntetherRequired, iOSVersionSupported, UIDevice.current.supportsFugu14 else { return operation.finish() } - - guard let patchAppLink = app.bundle.infoDictionary?[Bundle.Info.untetherURL] as? String, - let patchAppURL = URL(string: patchAppLink) - else { throw OperationError.invalidApp } - - let patchApp = AnyApp(name: app.name, bundleIdentifier: context.bundleIdentifier, url: patchAppURL, storeApp: nil) - - DispatchQueue.main.async { - let storyboard = UIStoryboard(name: "PatchApp", bundle: nil) - let navigationController = storyboard.instantiateInitialViewController() as! UINavigationController - - let patchViewController = navigationController.topViewController as! PatchViewController - patchViewController.patchApp = patchApp - patchViewController.completionHandler = { [weak presentingViewController] (result) in - switch result - { - case .failure(OperationError.cancelled): break // Ignore - case .failure(let error): group.context.error = error - case .success: group.context.error = OperationError.cancelled - } - - operation.finish() - - DispatchQueue.main.async { - presentingViewController?.dismiss(animated: true, completion: nil) - } - } - presentingViewController.present(navigationController, animated: true, completion: nil) - } - } - catch - { - group.context.error = error - operation.finish() - } - } - patchAppOperation.addDependency(deactivateAppsOperation) - let modifyAppExBundleIdOperation = RSTAsyncBlockOperation { operation in if !context.useMainProfile { @@ -1498,7 +1360,7 @@ private extension AppManager self.exportResginedAppsToDocsDir(resignedApp) } } - resignAppOperation.addDependency(patchAppOperation) + resignAppOperation.addDependency(deactivateAppsOperation) resignAppOperation.addDependency(modifyAppExBundleIdOperation) progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20) @@ -1549,7 +1411,6 @@ private extension AppManager verifyOperation, removeAppExtensionsOperation, deactivateAppsOperation, - patchAppOperation, refreshAnisetteDataOperation, fetchProvisioningProfilesOperation, modifyAppExBundleIdOperation, diff --git a/AltStore/Operations/Patch App/ALTAppPatcher.h b/AltStore/Operations/Patch App/ALTAppPatcher.h deleted file mode 100644 index 38bf8843..00000000 --- a/AltStore/Operations/Patch App/ALTAppPatcher.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// ALTAppPatcher.h -// AltStore -// -// Created by Riley Testut on 10/18/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTAppPatcher : NSObject - -- (BOOL)patchAppBinaryAtURL:(NSURL *)appFileURL withBinaryAtURL:(NSURL *)patchFileURL error:(NSError *_Nullable *)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltStore/Operations/Patch App/ALTAppPatcher.m b/AltStore/Operations/Patch App/ALTAppPatcher.m deleted file mode 100644 index 5cfbbdbe..00000000 --- a/AltStore/Operations/Patch App/ALTAppPatcher.m +++ /dev/null @@ -1,143 +0,0 @@ -// -// ALTAppPatcher.m -// AltStore -// -// Created by Riley Testut on 10/18/21. -// Copied with minor modifications from sample code provided by Linus Henze. -// - -#import "ALTAppPatcher.h" - -#include -#include -#include - -@import Roxas; - -#define CPU_SUBTYPE_PAC 0x80000000 -#define FAT_MAGIC 0xcafebabe - -#define ROUND_TO_PAGE(val) (((val % 0x4000) == 0) ? val : (val + (0x4000 - (val & 0x3FFF)))) - -typedef struct { - uint32_t magic; - uint32_t cpuType; - uint32_t cpuSubType; - // Incomplete, we don't need anything else -} MachOHeader; - -typedef struct { - uint32_t cpuType; - uint32_t cpuSubType; - uint32_t fileOffset; - uint32_t size; - uint32_t alignment; -} FatArch; - -typedef struct { - uint32_t magic; - uint32_t archCount; - FatArch archs[0]; -} FatHeader; - -// Given two MachO files, return a FAT file with the following properties: -// 1. installd will still see the original MachO and validate it's code signature -// 2. The kernel will only see the injected MachO instead -// -// Only arm64e for now -void *injectApp(void *originalApp, size_t originalAppSize, void *appToInject, size_t appToInjectSize, size_t *outputSize) { - *outputSize = 0; - - // First validate the App to inject: It must be an arm64e application - if (appToInjectSize < sizeof(MachOHeader)) { - return NULL; - } - - MachOHeader *injectedHeader = (MachOHeader*) appToInject; - if (injectedHeader->cpuType != CPU_TYPE_ARM64) { - return NULL; - } - - if (injectedHeader->cpuSubType != (CPU_SUBTYPE_ARM64E | CPU_SUBTYPE_PAC)) { - return NULL; - } - - // Ok, the App to inject is ok - // Now build a fat header - size_t originalAppSizeRounded = ROUND_TO_PAGE(originalAppSize); - size_t appToInjectSizeRounded = ROUND_TO_PAGE(appToInjectSize); - size_t totalSize = 0x4000 /* Fat Header + Alignment */ + originalAppSizeRounded + appToInjectSizeRounded; - - void *fatBuf = malloc(totalSize); - if (fatBuf == NULL) { - return NULL; - } - - bzero(fatBuf, totalSize); - - FatHeader *fatHeader = (FatHeader*) fatBuf; - fatHeader->magic = htonl(FAT_MAGIC); - fatHeader->archCount = htonl(2); - - // Write first arch (original app) - fatHeader->archs[0].cpuType = htonl(CPU_TYPE_ARM64); - fatHeader->archs[0].cpuSubType = htonl(CPU_SUBTYPE_ARM64E); /* Note that this is not a valid cpu subtype */ - fatHeader->archs[0].fileOffset = htonl(0x4000); - fatHeader->archs[0].size = htonl(originalAppSize); - fatHeader->archs[0].alignment = htonl(0xE); - - // Write second arch (injected app) - fatHeader->archs[1].cpuType = htonl(CPU_TYPE_ARM64); - fatHeader->archs[1].cpuSubType = htonl(CPU_SUBTYPE_ARM64E | CPU_SUBTYPE_PAC); - fatHeader->archs[1].fileOffset = htonl(0x4000 + originalAppSizeRounded); - fatHeader->archs[1].size = htonl(appToInjectSize); - fatHeader->archs[1].alignment = htonl(0xE); - - // Ok, now write the MachOs - memcpy(fatBuf + 0x4000, originalApp, originalAppSize); - memcpy(fatBuf + 0x4000 + originalAppSizeRounded, appToInject, appToInjectSize); - - // We're done! - *outputSize = totalSize; - return fatBuf; -} - -@implementation ALTAppPatcher - -- (BOOL)patchAppBinaryAtURL:(NSURL *)appFileURL withBinaryAtURL:(NSURL *)patchFileURL error:(NSError *__autoreleasing *)error -{ - NSMutableData *originalApp = [NSMutableData dataWithContentsOfURL:appFileURL options:0 error:error]; - if (originalApp == nil) - { - return NO; - } - - NSMutableData *injectedApp = [NSMutableData dataWithContentsOfURL:patchFileURL options:0 error:error]; - if (injectedApp == nil) - { - return NO; - } - - size_t outputSize = 0; - void *output = injectApp(originalApp.mutableBytes, originalApp.length, injectedApp.mutableBytes, injectedApp.length, &outputSize); - if (output == NULL) - { - if (error) - { - // If injectApp fails, it means the patch app is in the wrong format. - *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: patchFileURL}]; - } - - return NO; - } - - NSData *outputData = [NSData dataWithBytesNoCopy:output length:outputSize freeWhenDone:YES]; - if (![outputData writeToURL:appFileURL options:NSDataWritingAtomic error:error]) - { - return NO; - } - - return YES; -} - -@end diff --git a/AltStore/Operations/Patch App/PatchApp.storyboard b/AltStore/Operations/Patch App/PatchApp.storyboard deleted file mode 100644 index 6b6bc322..00000000 --- a/AltStore/Operations/Patch App/PatchApp.storyboard +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AltStore/Operations/Patch App/PatchAppOperation.swift b/AltStore/Operations/Patch App/PatchAppOperation.swift deleted file mode 100644 index 21d636ba..00000000 --- a/AltStore/Operations/Patch App/PatchAppOperation.swift +++ /dev/null @@ -1,256 +0,0 @@ -// -// PatchAppOperation.swift -// AltStore -// -// Created by Riley Testut on 10/13/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import UIKit -import Combine -import AppleArchive -import System -import AltStoreCore -import AltSign -import Roxas - -protocol PatchAppContext -{ - var bundleIdentifier: String { get } - var temporaryDirectory: URL { get } - - var resignedApp: ALTApplication? { get } - var error: Error? { get } -} - -extension PatchAppError -{ - enum Code: Int, ALTErrorCode, CaseIterable { - typealias Error = PatchAppError - - case unsupportedOperatingSystemVersion - } - - static func unsupportedOperatingSystemVersion(_ osVersion: OperatingSystemVersion) -> PatchAppError { - PatchAppError(code: .unsupportedOperatingSystemVersion, osVersion: osVersion) - } -} - -struct PatchAppError: ALTLocalizedError { - let code: Code - - var errorTitle: String? - var errorFailure: String? - - var osVersion: OperatingSystemVersion? - - var errorFailureReason: String { - switch self.code { - case .unsupportedOperatingSystemVersion: - let osVersionString: String - - if let osVersion = self.osVersion?.stringValue { - osVersionString = NSLocalizedString("iOS", comment: "") + " " + osVersion - } else { - osVersionString = NSLocalizedString("your device's iOS version", comment: "") - } - return String(format: NSLocalizedString("The OTA download URL for %@ could not be determined.", comment: ""), osVersionString) - } - } -} - -private struct OTAUpdate -{ - var url: URL - var archivePath: String -} - -@available(iOS 14, *) -final class PatchAppOperation: ResultOperation -{ - let context: PatchAppContext - - var progressHandler: ((Progress, String) -> Void)? - - private let appPatcher = ALTAppPatcher() - private lazy var patchDirectory: URL = self.context.temporaryDirectory.appendingPathComponent("Patch", isDirectory: true) - - private var cancellable: AnyCancellable? - - init(context: PatchAppContext) - { - self.context = context - - super.init() - - self.progress.totalUnitCount = 100 - } - - override func main() - { - super.main() - - if let error = self.context.error - { - self.finish(.failure(error)) - return - } - - guard let resignedApp = self.context.resignedApp else { - return self.finish(.failure(OperationError.invalidParameters("PatchAppOperation.main: self.context.resignedApp is nil"))) - } - - self.progressHandler?(self.progress, NSLocalizedString("Downloading iOS firmware...", comment: "")) - - self.cancellable = self.fetchOTAUpdate() - .flatMap { self.downloadArchive(from: $0) } - .flatMap { self.extractSpotlightFromArchive(at: $0) } - .flatMap { self.patch(resignedApp, withBinaryAt: $0) } - .tryMap { try FileManager.default.zipAppBundle(at: $0) } - .tryMap { (fileURL) in - let app = AnyApp(name: resignedApp.name, bundleIdentifier: self.context.bundleIdentifier, url: resignedApp.fileURL, storeApp: nil) - - let destinationURL = InstalledApp.refreshedIPAURL(for: app) - try FileManager.default.copyItem(at: fileURL, to: destinationURL, shouldReplace: true) - } - .receive(on: RunLoop.main) - .sink { completion in - switch completion - { - case .failure(let error): self.finish(.failure(error)) - case .finished: self.finish(.success(())) - } - } receiveValue: { _ in } - } - - override func cancel() - { - super.cancel() - - self.cancellable?.cancel() - self.cancellable = nil - } -} - -private let ALTFragmentZipCallback: @convention(c) (UInt32) -> Void = { (percentageComplete) in - guard let progress = Progress.current() else { return } - - if percentageComplete == 100 && progress.completedUnitCount == 0 - { - // Ignore first percentageComplete, which is always 100. - return - } - - progress.completedUnitCount = Int64(percentageComplete) -} - -private extension PatchAppOperation -{ - func fetchOTAUpdate() -> AnyPublisher - { - Just(()).tryMap { - let osVersion = ProcessInfo.processInfo.operatingSystemVersion - switch (osVersion.majorVersion, osVersion.minorVersion) - { - case (14, 3): - return OTAUpdate(url: URL(string: "https://updates.cdn-apple.com/2020WinterFCS/patches/001-87330/99E29969-F6B6-422A-B946-70DE2E2D73BE/com_apple_MobileAsset_SoftwareUpdate/67f9e42f5e57a20e0a87eaf81b69dd2a61311d3f.zip")!, - archivePath: "AssetData/payloadv2/payload.042") - - case (14, 4): - return OTAUpdate(url: URL(string: "https://updates.cdn-apple.com/2021WinterFCS/patches/001-98606/43AF99A1-F286-43B1-A101-F9F856EA395A/com_apple_MobileAsset_SoftwareUpdate/c4985c32c344beb7b49c61919b4e39d1fd336c90.zip")!, - archivePath: "AssetData/payloadv2/payload.042") - - case (14, 5): - return OTAUpdate(url: URL(string: "https://updates.cdn-apple.com/2021SpringFCS/patches/061-84483/AB525139-066E-46F8-8E85-DCE802C03BA8/com_apple_MobileAsset_SoftwareUpdate/788573ae93113881db04269acedeecabbaa643e3.zip")!, - archivePath: "AssetData/payloadv2/payload.043") - - default: throw PatchAppError.unsupportedOperatingSystemVersion(osVersion) - } - } - .eraseToAnyPublisher() - } - - func downloadArchive(from update: OTAUpdate) -> AnyPublisher - { - Just(()).tryMap { - #if targetEnvironment(simulator) - throw PatchAppError.unsupportedOperatingSystemVersion(ProcessInfo.processInfo.operatingSystemVersion) - #else - - try FileManager.default.createDirectory(at: self.patchDirectory, withIntermediateDirectories: true, attributes: nil) - - let archiveURL = self.patchDirectory.appendingPathComponent("ota.archive") - try archiveURL.withUnsafeFileSystemRepresentation { archivePath in - guard let fz = fragmentzip_open((update.url.absoluteString as NSString).utf8String!) else { - throw URLError(.cannotConnectToHost, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("The connection failed because a connection cannot be made to the host.", comment: ""), - NSURLErrorKey: update.url]) - } - defer { fragmentzip_close(fz) } - - self.progress.becomeCurrent(withPendingUnitCount: 100) - defer { self.progress.resignCurrent() } - - guard fragmentzip_download_file(fz, update.archivePath, archivePath!, ALTFragmentZipCallback) == 0 else { - throw URLError(.networkConnectionLost, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("The connection failed because the network connection was lost.", comment: ""), - NSURLErrorKey: update.url]) - } - } - - Logger.fugu14.notice("Downloaded iOS OTA archive.") - return archiveURL - - #endif - } - .mapError { ($0 as NSError).withLocalizedFailure(NSLocalizedString("Could not download OTA archive.", comment: "")) } - .eraseToAnyPublisher() - } - - func extractSpotlightFromArchive(at archiveURL: URL) -> AnyPublisher - { - Just(()).tryMap { - #if targetEnvironment(simulator) - throw PatchAppError.unsupportedOperatingSystemVersion(ProcessInfo.processInfo.operatingSystemVersion) - #else - let spotlightPath = "Applications/Spotlight.app/Spotlight" - let spotlightFileURL = self.patchDirectory.appendingPathComponent(spotlightPath) - - guard let readFileStream = ArchiveByteStream.fileStream(path: FilePath(archiveURL.path), mode: .readOnly, options: [], permissions: FilePermissions(rawValue: 0o644)), - let decompressStream = ArchiveByteStream.decompressionStream(readingFrom: readFileStream), - let decodeStream = ArchiveStream.decodeStream(readingFrom: decompressStream), - let readStream = ArchiveStream.extractStream(extractingTo: FilePath(self.patchDirectory.path)) - else { throw CocoaError(.fileReadCorruptFile, userInfo: [NSURLErrorKey: archiveURL]) } - - _ = try ArchiveStream.process(readingFrom: decodeStream, writingTo: readStream) { message, filePath, data in - guard filePath == FilePath(spotlightPath) else { return .skip } - return .ok - } - - Logger.fugu14.notice("Extracted Spotlight from OTA archive.") - return spotlightFileURL - - #endif - } - .mapError { ($0 as NSError).withLocalizedFailure(NSLocalizedString("Could not extract Spotlight from OTA archive.", comment: "")) } - .eraseToAnyPublisher() - } - - func patch(_ app: ALTApplication, withBinaryAt patchFileURL: URL) -> AnyPublisher - { - Just(()).tryMap { - // executableURL may be nil, so use infoDictionary instead to determine executable name. - // guard let appName = app.bundle.executableURL?.lastPathComponent else { throw OperationError.invalidApp } - guard let appName = app.bundle.infoDictionary?[kCFBundleExecutableKey as String] as? String else { throw OperationError.invalidApp } - - let temporaryAppURL = self.patchDirectory.appendingPathComponent("Patched.app", isDirectory: true) - try FileManager.default.copyItem(at: app.fileURL, to: temporaryAppURL) - - let appBinaryURL = temporaryAppURL.appendingPathComponent(appName, isDirectory: false) - try self.appPatcher.patchAppBinary(at: appBinaryURL, withBinaryAt: patchFileURL) - - Logger.fugu14.notice("Patched \(app.name, privacy: .public)!") - return temporaryAppURL - } - .mapError { ($0 as NSError).withLocalizedFailure(String(format: NSLocalizedString("Could not patch %@ placeholder.", comment: ""), app.name)) } - .eraseToAnyPublisher() - } -} diff --git a/AltStore/Operations/Patch App/PatchViewController.swift b/AltStore/Operations/Patch App/PatchViewController.swift deleted file mode 100644 index 483d2a56..00000000 --- a/AltStore/Operations/Patch App/PatchViewController.swift +++ /dev/null @@ -1,494 +0,0 @@ -// -// PatchViewController.swift -// AltStore -// -// Created by Riley Testut on 10/20/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -import UIKit -import Combine -import AltStoreCore -import AltSign -import Roxas - -extension PatchViewController -{ - enum Step - { - case confirm - case install - case openApp - case patchApp - case reboot - case refresh - case finish - } -} - -@available(iOS 14.0, *) -final class PatchViewController: UIViewController -{ - var patchApp: AnyApp? - var installedApp: InstalledApp? - - var completionHandler: ((Result) -> Void)? - - private let context = AuthenticatedOperationContext() - - private var currentStep: Step = .confirm { - didSet { - DispatchQueue.main.async { - self.update() - } - } - } - - private var buttonHandler: (() -> Void)? - private var resignedApp: ALTApplication? - - private lazy var temporaryDirectory: URL = FileManager.default.uniqueTemporaryURL() - - private var didEnterBackgroundObservation: NSObjectProtocol? - private weak var cancellableProgress: Progress? - - @IBOutlet private var placeholderView: RSTPlaceholderView! - @IBOutlet private var taskDescriptionLabel: UILabel! - @IBOutlet private var pillButton: PillButton! - @IBOutlet private var cancelBarButtonItem: UIBarButtonItem! - @IBOutlet private var cancelButton: UIButton! - - override func viewDidLoad() - { - super.viewDidLoad() - - self.isModalInPresentation = true - - self.placeholderView.stackView.spacing = 20 - self.placeholderView.textLabel.textColor = .white - - self.placeholderView.detailTextLabel.textAlignment = .left - self.placeholderView.detailTextLabel.textColor = UIColor.white.withAlphaComponent(0.6) - - self.buttonHandler = { [weak self] in - self?.startProcess() - } - - do - { - try FileManager.default.createDirectory(at: self.temporaryDirectory, withIntermediateDirectories: true, attributes: nil) - } - catch - { - Logger.fugu14.error("Failed to create temporary directory \(self.temporaryDirectory.lastPathComponent, privacy: .public). \(error.localizedDescription, privacy: .public)") - } - - self.update() - } - - override func viewWillAppear(_ animated: Bool) - { - super.viewWillAppear(animated) - - if self.installedApp != nil - { - self.refreshApp() - } - } -} - -private extension PatchViewController -{ - func update() - { - self.cancelButton.alpha = 0.0 - - switch self.currentStep - { - case .confirm: - guard let app = self.patchApp else { break } - - if UIDevice.current.isUntetheredJailbreakRequired - { - self.placeholderView.textLabel.text = NSLocalizedString("Jailbreak Requires Untethering", comment: "") - self.placeholderView.detailTextLabel.text = String(format: NSLocalizedString("This jailbreak is untethered, which means %@ will never expire — even after 7 days or rebooting the device.\n\nInstalling an untethered jailbreak requires a few extra steps, but SideStore will walk you through the process.\n\nWould you like to continue? ", comment: ""), app.name) - } - else - { - self.placeholderView.textLabel.text = NSLocalizedString("Jailbreak Supports Untethering", comment: "") - self.placeholderView.detailTextLabel.text = String(format: NSLocalizedString("This jailbreak has an untethered version, which means %@ will never expire — even after 7 days or rebooting the device.\n\nInstalling an untethered jailbreak requires a few extra steps, but SideStore will walk you through the process.\n\nWould you like to continue? ", comment: ""), app.name) - } - - self.pillButton.setTitle(NSLocalizedString("Install Untethered Jailbreak", comment: ""), for: .normal) - - self.cancelButton.alpha = 1.0 - - case .install: - guard let app = self.patchApp else { break } - - self.placeholderView.textLabel.text = String(format: NSLocalizedString("Installing %@ placeholder…", comment: ""), app.name) - self.placeholderView.detailTextLabel.text = NSLocalizedString("A placeholder app needs to be installed in order to prepare your device for untethering.\n\nThis may take a few moments.", comment: "") - - case .openApp: - self.placeholderView.textLabel.text = NSLocalizedString("Continue in App", comment: "") - self.placeholderView.detailTextLabel.text = NSLocalizedString("Please open the placeholder app and follow the instructions to continue jailbreaking your device.", comment: "") - - self.pillButton.setTitle(NSLocalizedString("Open Placeholder", comment: ""), for: .normal) - - case .patchApp: - guard let app = self.patchApp else { break } - - self.placeholderView.textLabel.text = String(format: NSLocalizedString("Patching %@ placeholder…", comment: ""), app.name) - self.placeholderView.detailTextLabel.text = NSLocalizedString("This will take a few moments. Please do not turn off the screen or leave the app until patching is complete.", comment: "") - - self.pillButton.setTitle(NSLocalizedString("Patch Placeholder", comment: ""), for: .normal) - - case .reboot: - self.placeholderView.textLabel.text = NSLocalizedString("Continue in App", comment: "") - self.placeholderView.detailTextLabel.text = NSLocalizedString("Please open the placeholder app and follow the instructions to continue jailbreaking your device.", comment: "") - - self.pillButton.setTitle(NSLocalizedString("Open Placeholder", comment: ""), for: .normal) - - case .refresh: - guard let installedApp = self.installedApp else { break } - - self.placeholderView.textLabel.text = String(format: NSLocalizedString("Finish installing %@?", comment: ""), installedApp.name) - self.placeholderView.detailTextLabel.text = String(format: NSLocalizedString("In order to finish jailbreaking this device, you need to install %@ then follow the instructions in the app.", comment: ""), installedApp.name) - - self.pillButton.setTitle(String(format: NSLocalizedString("Install %@", comment: ""), installedApp.name), for: .normal) - - case .finish: - guard let installedApp = self.installedApp else { break } - - self.placeholderView.textLabel.text = String(format: NSLocalizedString("Finish in %@", comment: ""), installedApp.name) - self.placeholderView.detailTextLabel.text = String(format: NSLocalizedString("Follow the instructions in %@ to finish jailbreaking this device.", comment: ""), installedApp.name) - - self.pillButton.setTitle(String(format: NSLocalizedString("Open %@", comment: ""), installedApp.name), for: .normal) - } - } - - func present(_ error: Error, title: String) - { - DispatchQueue.main.async { - let nsError = error as NSError - - let alertController = UIAlertController(title: nsError.localizedFailure ?? title, message: error.localizedDescription, preferredStyle: .alert) - alertController.addAction(.ok) - self.present(alertController, animated: true, completion: nil) - - self.setProgress(nil, description: nil) - } - } - - func setProgress(_ progress: Progress?, description: String?) - { - DispatchQueue.main.async { - self.pillButton.progress = progress - self.taskDescriptionLabel.text = description ?? " " // Use non-empty string to prevent label resizing itself. - } - } - - func finish(with result: Result) - { - do - { - try FileManager.default.removeItem(at: self.temporaryDirectory) - } - catch - { - Logger.fugu14.error("Failed to remove temporary directory \(self.temporaryDirectory.lastPathComponent, privacy: .public). \(error.localizedDescription, privacy: .public)") - } - - if let observation = self.didEnterBackgroundObservation - { - NotificationCenter.default.removeObserver(observation) - } - - self.completionHandler?(result) - self.completionHandler = nil - } -} - -private extension PatchViewController -{ - @IBAction func performButtonAction() - { - self.buttonHandler?() - } - - @IBAction func cancel() - { - self.finish(with: .success(())) - - self.cancellableProgress?.cancel() - } - - @IBAction func installRegularJailbreak() - { - guard let app = self.patchApp else { return } - - let title: String - let message: String - - if UIDevice.current.isUntetheredJailbreakRequired - { - title = NSLocalizedString("Untethering Required", comment: "") - message = String(format: NSLocalizedString("%@ can not jailbreak this device unless you untether it first. Are you sure you want to install without untethering?", comment: ""), app.name) - } - else - { - title = NSLocalizedString("Untethering Recommended", comment: "") - message = String(format: NSLocalizedString("Untethering this jailbreak will prevent %@ from expiring, even after 7 days or rebooting the device. Are you sure you want to install without untethering?", comment: ""), app.name) - } - - let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Install Without Untethering", comment: ""), style: .default) { _ in - self.finish(with: .failure(OperationError.cancelled)) - }) - alertController.addAction(.cancel) - self.present(alertController, animated: true, completion: nil) - } -} - -private extension PatchViewController -{ - func startProcess() - { - guard let patchApp = self.patchApp else { return } - - self.currentStep = .install - - if let progress = AppManager.shared.installationProgress(for: patchApp) - { - // Cancel pending jailbreak app installation so we can start a new one. - progress.cancel() - } - - let appURL = InstalledApp.fileURL(for: patchApp) - let cachedAppURL = self.temporaryDirectory.appendingPathComponent("Cached.app") - - do - { - // Make copy of original app, so we can replace the cached patch app with it later. - try FileManager.default.copyItem(at: appURL, to: cachedAppURL, shouldReplace: true) - } - catch - { - self.present(error, title: NSLocalizedString("Could not back up jailbreak app.", comment: "")) - return - } - - var unzippingError: Error? - let refreshGroup = AppManager.shared.install(patchApp, presentingViewController: self, context: self.context) { result in - do - { - _ = try result.get() - - if let unzippingError = unzippingError - { - throw unzippingError - } - - // Replace cached patch app with original app so we can resume installing it post-reboot. - try FileManager.default.copyItem(at: cachedAppURL, to: appURL, shouldReplace: true) - - self.openApp() - } - catch - { - self.present(error, title: String(format: NSLocalizedString("Could not install %@ placeholder.", comment: ""), patchApp.name)) - } - } - refreshGroup.beginInstallationHandler = { (installedApp) in - do - { - // Replace patch app name with correct name. - installedApp.name = patchApp.name - - let ipaURL = installedApp.refreshedIPAURL - let resignedAppURL = try FileManager.default.unzipAppBundle(at: ipaURL, toDirectory: self.temporaryDirectory) - - self.resignedApp = ALTApplication(fileURL: resignedAppURL) - } - catch - { - Logger.fugu14.error("Error unzipping app bundle: \(error.localizedDescription, privacy: .public)") - unzippingError = error - } - } - self.setProgress(refreshGroup.progress, description: nil) - - self.cancellableProgress = refreshGroup.progress - } - - func openApp() - { - guard let patchApp = self.patchApp else { return } - - self.setProgress(nil, description: nil) - self.currentStep = .openApp - - // This observation is willEnterForeground because patching starts immediately upon return. - self.didEnterBackgroundObservation = NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { (notification) in - self.didEnterBackgroundObservation.map { NotificationCenter.default.removeObserver($0) } - self.patchApplication() - } - - self.buttonHandler = { [weak self] in - guard let self = self else { return } - - #if !targetEnvironment(simulator) - - let openURL = InstalledApp.openAppURL(for: patchApp) - UIApplication.shared.open(openURL) { success in - guard !success else { return } - self.present(OperationError.openAppFailed(name: patchApp.name), title: String(format: NSLocalizedString("Could not open %@ placeholder.", comment: ""), patchApp.name)) - } - - #endif - } - } - - func patchApplication() - { - guard let resignedApp = self.resignedApp else { return } - - self.currentStep = .patchApp - - self.buttonHandler = { [weak self] in - self?.patchApplication() - } - - let patchAppOperation = AppManager.shared.patch(resignedApp: resignedApp, presentingViewController: self, context: self.context) { result in - switch result - { - case .failure(let error): self.present(error, title: String(format: NSLocalizedString("Could not patch %@ placeholder.", comment: ""), resignedApp.name)) - case .success: self.rebootDevice() - } - } - patchAppOperation.progressHandler = { (progress, description) in - self.setProgress(progress, description: description) - } - self.cancellableProgress = patchAppOperation.progress - } - - func rebootDevice() - { - guard let patchApp = self.patchApp else { return } - - self.setProgress(nil, description: nil) - self.currentStep = .reboot - - self.didEnterBackgroundObservation = NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { (notification) in - self.didEnterBackgroundObservation.map { NotificationCenter.default.removeObserver($0) } - - var patchedApps = UserDefaults.standard.patchedApps ?? [] - if !patchedApps.contains(patchApp.bundleIdentifier) - { - patchedApps.append(patchApp.bundleIdentifier) - UserDefaults.standard.patchedApps = patchedApps - } - - self.finish(with: .success(())) - } - - self.buttonHandler = { [weak self] in - guard let self = self else { return } - - #if !targetEnvironment(simulator) - - let openURL = InstalledApp.openAppURL(for: patchApp) - UIApplication.shared.open(openURL) { success in - guard !success else { return } - self.present(OperationError.openAppFailed(name: patchApp.name), title: String(format: NSLocalizedString("Could not open %@ placeholder.", comment: ""), patchApp.name)) - } - - #endif - } - } - - func refreshApp() - { - guard let installedApp = self.installedApp else { return } - - self.currentStep = .refresh - - self.buttonHandler = { [weak self] in - guard let self = self else { return } - DatabaseManager.shared.persistentContainer.performBackgroundTask { context in - let tempApp = context.object(with: installedApp.objectID) as! InstalledApp - tempApp.needsResign = true - - let errorTitle = String(format: NSLocalizedString("Could not install %@.", comment: ""), tempApp.name) - - do - { - try context.save() - - installedApp.managedObjectContext?.perform { - // Refreshing ensures we don't attempt to patch the app again, - // since that is only checked when installing a new app. - let refreshGroup = AppManager.shared.refresh([installedApp], presentingViewController: self, group: nil) - refreshGroup.completionHandler = { [weak refreshGroup, weak self] (results) in - guard let self = self else { return } - - do - { - guard let (bundleIdentifier, result) = results.first else { throw refreshGroup?.context.error ?? OperationError.unknown() } - _ = try result.get() - - if var patchedApps = UserDefaults.standard.patchedApps, let index = patchedApps.firstIndex(of: bundleIdentifier) - { - patchedApps.remove(at: index) - UserDefaults.standard.patchedApps = patchedApps - } - - self.finish() - } - catch - { - self.present(error, title: errorTitle) - } - } - self.setProgress(refreshGroup.progress, description: String(format: NSLocalizedString("Installing %@...", comment: ""), installedApp.name)) - } - } - catch - { - self.present(error, title: errorTitle) - } - } - } - } - - func finish() - { - guard let installedApp = self.installedApp else { return } - - self.setProgress(nil, description: nil) - self.currentStep = .finish - - self.didEnterBackgroundObservation = NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { (notification) in - self.didEnterBackgroundObservation.map { NotificationCenter.default.removeObserver($0) } - self.finish(with: .success(())) - } - - installedApp.managedObjectContext?.perform { - let appName = installedApp.name - let openURL = installedApp.openAppURL - - self.buttonHandler = { [weak self] in - guard let self = self else { return } - - #if !targetEnvironment(simulator) - - UIApplication.shared.open(openURL) { success in - guard !success else { return } - self.present(OperationError.openAppFailed(name: appName), title: String(format: NSLocalizedString("Could not open %@.", comment: ""), appName)) - } - - #endif - } - } - } -} diff --git a/AltStore/Operations/Patch App/fragmentzip.h b/AltStore/Operations/Patch App/fragmentzip.h deleted file mode 100644 index 6fe1f2eb..00000000 --- a/AltStore/Operations/Patch App/fragmentzip.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// fragmentzip.h -// AltStore -// -// Created by Riley Testut on 10/25/21. -// Copyright © 2021 Riley Testut. All rights reserved. -// - -#ifndef fragmentzip_h -#define fragmentzip_h - -typedef void fragmentzip_t; -typedef void (*fragmentzip_process_callback_t)(unsigned int progress); -fragmentzip_t *fragmentzip_open(const char *url); -int fragmentzip_download_file(fragmentzip_t *info, const char *remotepath, const char *savepath, fragmentzip_process_callback_t callback); -void fragmentzip_close(fragmentzip_t *info); - -#endif /* fragmentzip_h */ diff --git a/AltStore/TabBarController.swift b/AltStore/TabBarController.swift index 3f9ded15..a40b3b65 100644 --- a/AltStore/TabBarController.swift +++ b/AltStore/TabBarController.swift @@ -61,35 +61,6 @@ final class TabBarController: UITabBarController self.initialSegue = nil self.performSegue(withIdentifier: identifier, sender: sender) } - else if let patchedApps = UserDefaults.standard.patchedApps, !patchedApps.isEmpty - { - // Check if we need to finish installing untethered jailbreak. - let activeApps = InstalledApp.fetchActiveApps(in: DatabaseManager.shared.viewContext) - guard let patchedApp = activeApps.first(where: { patchedApps.contains($0.bundleIdentifier) }) else { return } - - self.performSegue(withIdentifier: "finishJailbreak", sender: patchedApp) - } - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) - { - guard let identifier = segue.identifier else { return } - - switch identifier - { - case "finishJailbreak": - guard let installedApp = sender as? InstalledApp else { return } - - let navigationController = segue.destination as! UINavigationController - - let patchViewController = navigationController.viewControllers.first as! PatchViewController - patchViewController.installedApp = installedApp - patchViewController.completionHandler = { [weak self] _ in - self?.dismiss(animated: true, completion: nil) - } - - default: break - } } override func performSegue(withIdentifier identifier: String, sender: Any?) diff --git a/Dependencies/libcurl/libcurl.a b/Dependencies/libcurl/libcurl.a deleted file mode 100644 index 0766ced7..00000000 Binary files a/Dependencies/libcurl/libcurl.a and /dev/null differ diff --git a/Dependencies/libfragmentzip b/Dependencies/libfragmentzip deleted file mode 160000 index b7f9272a..00000000 --- a/Dependencies/libfragmentzip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b7f9272acf99495d86f4d1ca448cf69908500213