refactor minimuxer to use swift-bridge (#321)

also add team ID to the end of the bundle ID for Debug builds to mirror SideServer
This commit is contained in:
naturecodevoid
2023-04-01 16:02:12 -07:00
committed by GitHub
parent 6d0f4bb3da
commit 0c171122b2
14 changed files with 186 additions and 266 deletions

View File

@@ -11,17 +11,18 @@
19104D952909BAEA00C49C7B /* libimobiledevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF45872B2298D31600BD7491 /* libimobiledevice.a */; };
19104DB52909C06D00C49C7B /* EmotionalDamage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19104DB42909C06D00C49C7B /* EmotionalDamage.swift */; };
19104DBC2909C4E500C49C7B /* libEmotionalDamage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19104DB22909C06C00C49C7B /* libEmotionalDamage.a */; };
191E5FAE290A5D92001A3B7C /* minimuxer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FAD290A5D92001A3B7C /* minimuxer.swift */; };
191E5FB4290A5DA0001A3B7C /* libminimuxer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191E5FAB290A5D92001A3B7C /* libminimuxer.a */; };
191E5FDC290AFA5C001A3B7C /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 191E5FDB290AFA5C001A3B7C /* OpenSSL */; };
191E607D290B2EA5001A3B7C /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FD0290A651D001A3B7C /* jsmn.c */; };
191E607E290B2EA7001A3B7C /* jplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FCF290A651D001A3B7C /* jplist.c */; };
191E6087290C7B50001A3B7C /* libminimuxer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191E5FB5290A5E1F001A3B7C /* libminimuxer.a */; };
1920B04F2924AC8300744F60 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1920B04E2924AC8300744F60 /* Settings.bundle */; };
19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; };
4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; };
4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; };
99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = 99C4EF4C2979132100CB538D /* SemanticVersion */; };
99F87D0529D8B4E200B40039 /* minimuxer-helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9961EC2D29BE9F2E00AF2C6F /* minimuxer-helpers.swift */; };
99F87D1829D8E4C900B40039 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1629D8E4C900B40039 /* SwiftBridgeCore.swift */; };
99F87D1929D8E4C900B40039 /* minimuxer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1729D8E4C900B40039 /* minimuxer.swift */; };
B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; };
B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B343F894295F7F9B002B1159 /* libfragmentzip.a */; };
@@ -504,13 +505,14 @@
19104DB22909C06C00C49C7B /* libEmotionalDamage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libEmotionalDamage.a; sourceTree = BUILT_PRODUCTS_DIR; };
19104DB42909C06D00C49C7B /* EmotionalDamage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmotionalDamage.swift; sourceTree = "<group>"; };
191E5FAB290A5D92001A3B7C /* libminimuxer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libminimuxer.a; sourceTree = BUILT_PRODUCTS_DIR; };
191E5FAD290A5D92001A3B7C /* minimuxer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = minimuxer.swift; sourceTree = "<group>"; };
191E5FB5290A5E1F001A3B7C /* libminimuxer.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libminimuxer.a; path = "Dependencies/minimuxer/target/aarch64-apple-ios/debug/libminimuxer.a"; sourceTree = "<group>"; };
191E5FCF290A651D001A3B7C /* jplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jplist.c; path = Dependencies/libplist/src/jplist.c; sourceTree = SOURCE_ROOT; };
191E5FD0290A651D001A3B7C /* jsmn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jsmn.c; path = Dependencies/libplist/src/jsmn.c; sourceTree = SOURCE_ROOT; };
191E5FD1290A651D001A3B7C /* jsmn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jsmn.h; path = Dependencies/libplist/src/jsmn.h; sourceTree = SOURCE_ROOT; };
1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = "<group>"; };
9961EC2D29BE9F2E00AF2C6F /* minimuxer-helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "minimuxer-helpers.swift"; path = "Dependencies/minimuxer/minimuxer-helpers.swift"; sourceTree = SOURCE_ROOT; };
99F87D1629D8E4C900B40039 /* SwiftBridgeCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftBridgeCore.swift; path = Dependencies/minimuxer/SwiftBridgeCore.swift; sourceTree = SOURCE_ROOT; };
99F87D1729D8E4C900B40039 /* minimuxer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = minimuxer.swift; path = Dependencies/minimuxer/minimuxer.swift; sourceTree = SOURCE_ROOT; };
B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Roxas.xcodeproj; path = Dependencies/Roxas/Roxas.xcodeproj; sourceTree = "<group>"; };
B33FFBA9295F8F78002259E6 /* preboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = preboard.c; path = src/preboard.c; sourceTree = "<group>"; };
B33FFBAB295F8F98002259E6 /* companion_proxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = companion_proxy.c; path = src/companion_proxy.c; sourceTree = "<group>"; };
@@ -914,7 +916,6 @@
buildActionMask = 2147483647;
files = (
B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */,
191E6087290C7B50001A3B7C /* libminimuxer.a in Frameworks */,
191E5FB4290A5DA0001A3B7C /* libminimuxer.a in Frameworks */,
19104DBC2909C4E500C49C7B /* libEmotionalDamage.a in Frameworks */,
19104D952909BAEA00C49C7B /* libimobiledevice.a in Frameworks */,
@@ -945,8 +946,9 @@
191E5FAC290A5D92001A3B7C /* minimuxer */ = {
isa = PBXGroup;
children = (
9961EC2D29BE9F2E00AF2C6F /* minimuxer-helpers.swift */,
99F87D1429D8E3F100B40039 /* Generated */,
B343F847295F6321002B1159 /* minimuxer.xcodeproj */,
191E5FAD290A5D92001A3B7C /* minimuxer.swift */,
);
path = minimuxer;
sourceTree = "<group>";
@@ -968,6 +970,15 @@
path = "libimobiledevice-glue/src";
sourceTree = "<group>";
};
99F87D1429D8E3F100B40039 /* Generated */ = {
isa = PBXGroup;
children = (
99F87D1629D8E4C900B40039 /* SwiftBridgeCore.swift */,
99F87D1729D8E4C900B40039 /* minimuxer.swift */,
);
name = Generated;
sourceTree = "<group>";
};
B3146EC7284F580500BBC3FD /* Products */ = {
isa = PBXGroup;
children = (
@@ -1567,7 +1578,6 @@
isa = PBXGroup;
children = (
B343F86C295F759E002B1159 /* libresolv.tbd */,
191E5FB5290A5E1F001A3B7C /* libminimuxer.a */,
B39575F4284F29E20080B4FF /* Roxas.framework */,
D533E8B62727841800A9B5DD /* libAppleArchive.tbd */,
BF580497246A3D19008AE704 /* UIKit.framework */,
@@ -1766,13 +1776,6 @@
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
191E5FD4290A6EE0001A3B7C /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
BF4587272298D31600BD7491 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@@ -1853,7 +1856,6 @@
isa = PBXNativeTarget;
buildConfigurationList = 191E5FAF290A5D92001A3B7C /* Build configuration list for PBXNativeTarget "minimuxer" */;
buildPhases = (
191E5FD4290A6EE0001A3B7C /* Headers */,
191E5FA7290A5D92001A3B7C /* Sources */,
191E5FA8290A5D92001A3B7C /* Frameworks */,
);
@@ -1969,6 +1971,7 @@
isa = PBXNativeTarget;
buildConfigurationList = BFD2477E2284B9A700981D42 /* Build configuration list for PBXNativeTarget "SideStore" */;
buildPhases = (
99F87D0629D8B51400B40039 /* ShellScript */,
BFD247662284B9A500981D42 /* Sources */,
BFD247672284B9A500981D42 /* Frameworks */,
BFD247682284B9A500981D42 /* Resources */,
@@ -2220,6 +2223,27 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
99F87D0629D8B51400B40039 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
"./Dependencies/minimuxer/minimuxer-helpers.swift",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "bash ./Dependencies/fetch-prebuilt.sh minimuxer\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
19104DAE2909C06C00C49C7B /* Sources */ = {
isa = PBXSourcesBuildPhase;
@@ -2233,7 +2257,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
191E5FAE290A5D92001A3B7C /* minimuxer.swift in Sources */,
99F87D1929D8E4C900B40039 /* minimuxer.swift in Sources */,
99F87D1829D8E4C900B40039 /* SwiftBridgeCore.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2484,6 +2509,7 @@
BFB39B5C252BC10E00D1BE50 /* Managed.swift in Sources */,
BF770E5822BC3D0F002A40FE /* RefreshGroup.swift in Sources */,
19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */,
99F87D0529D8B4E200B40039 /* minimuxer-helpers.swift in Sources */,
BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */,
BF3D649F22E7B24C00E9056B /* CollapsingTextView.swift in Sources */,
BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */,
@@ -2673,7 +2699,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = Dependencies/minimuxer/minimuxer.h;
SWIFT_OBJC_BRIDGING_HEADER = "Dependencies/minimuxer/minimuxer-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -2695,7 +2721,7 @@
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = Dependencies/minimuxer/minimuxer.h;
SWIFT_OBJC_BRIDGING_HEADER = "Dependencies/minimuxer/minimuxer-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};

View File

@@ -14,6 +14,8 @@ import minimuxer
import AltStoreCore
import UniformTypeIdentifiers
let pairingFileName = "ALTPairingFile.mobiledevicepairing"
final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate
{
private var didFinishLaunching = false
@@ -125,14 +127,11 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
}
// Save to a file for next launch
let filename = "ALTPairingFile.mobiledevicepairing"
let fm = FileManager.default
let documentsPath = fm.documentsDirectory.appendingPathComponent("/\(filename)")
try pairing_string?.write(to: documentsPath, atomically: true, encoding: String.Encoding.utf8)
let pairingFile = FileManager.default.documentsDirectory.appendingPathComponent("\(pairingFileName)")
try pairing_string?.write(to: pairingFile, atomically: true, encoding: String.Encoding.utf8)
// Start minimuxer now that we have a file
start_minimuxer_threads(pairing_string!)
} catch {
displayError("Unable to read pairing file")
}
@@ -148,22 +147,15 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
}
func start_minimuxer_threads(_ pairing_file: String) {
set_usbmuxd_socket()
#if false // Retries
var res = start_minimuxer(pairing_file: pairing_file)
var attempts = 10
while (attempts != 0 && res != 0) {
print("start_minimuxer `res` != 0, retry #\(attempts)")
res = start_minimuxer(pairing_file: pairing_file)
attempts -= 1
target_minimuxer_address()
let documentsDirectory = FileManager.default.documentsDirectory.absoluteString
do {
try start(pairing_file, documentsDirectory)
} catch {
try! FileManager.default.removeItem(at: FileManager.default.documentsDirectory.appendingPathComponent("\(pairingFileName)"))
displayError("minimuxer failed to start, please restart SideStore. \(minimuxerToOperationError(error).failureReason ?? "UNKNOWN ERROR!!!!!! REPORT TO GITHUB ISSUES!")")
}
#else
let res = start_minimuxer(pairing_file: pairing_file)
#endif
if res != 0 {
displayError("minimuxer failed to start. Incorrect arguments were passed.")
}
auto_mount_dev_image()
start_auto_mounter(documentsDirectory)
}
}

View File

@@ -44,14 +44,9 @@ final class DeactivateAppOperation: ResultOperation<InstalledApp>
for profile in allIdentifiers {
do {
let res = try remove_provisioning_profile(id: profile)
if case Uhoh.Bad(let code) = res {
self.finish(.failure(minimuxer_to_operation(code: code)))
}
} catch Uhoh.Bad(let code) {
self.finish(.failure(minimuxer_to_operation(code: code)))
try remove_provisioning_profile(profile)
} catch {
self.finish(.failure(ALTServerError(.unknownResponse)))
return self.finish(.failure(minimuxerToOperationError(error)))
}
}

View File

@@ -45,23 +45,13 @@ final class EnableJITOperation<Context: EnableJITContext>: ResultOperation<Void>
guard let installedApp = self.context.installedApp else { return self.finish(.failure(OperationError.invalidParameters)) }
installedApp.managedObjectContext?.perform {
let v = minimuxer_to_operation(code: 1)
do {
var x = try debug_app(app_id: installedApp.resignedBundleIdentifier)
switch x {
case .Good:
self.finish(.success(()))
case .Bad(let code):
self.finish(.failure(minimuxer_to_operation(code: code)))
}
} catch Uhoh.Bad(let code) {
self.finish(.failure(minimuxer_to_operation(code: code)))
try debug_app(installedApp.resignedBundleIdentifier)
} catch {
self.finish(.failure(OperationError.unknown))
return self.finish(.failure(minimuxerToOperationError(error)))
}
self.finish(.success(()))
}
}
}

View File

@@ -11,6 +11,7 @@ import Network
import AltStoreCore
import AltSign
import Roxas
import minimuxer
@objc(InstallAppOperation)
final class InstallAppOperation: ResultOperation<InstalledApp>
@@ -148,17 +149,14 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
})
}
let ns_bundle = NSString(string: installedApp.bundleIdentifier)
let ns_bundle_ptr = UnsafeMutablePointer<CChar>(mutating: ns_bundle.utf8String)
let res = minimuxer_install_ipa(ns_bundle_ptr)
if res == 0 {
installedApp.refreshedDate = Date()
self.finish(.success(installedApp))
} else {
self.finish(.failure(minimuxer_to_operation(code: res)))
do {
try install_ipa(installedApp.bundleIdentifier)
} catch {
return self.finish(.failure(minimuxerToOperationError(error)))
}
installedApp.refreshedDate = Date()
self.finish(.success(installedApp))
}
}
@@ -174,10 +172,11 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
do
{
try FileManager.default.removeItem(at: fileURL)
print("Removed refreshed IPA")
}
catch
{
print("Failed to remove refreshed .ipa:", error)
print("Failed to remove refreshed .ipa: \(error)")
}
}

View File

@@ -8,6 +8,7 @@
import Foundation
import AltSign
import minimuxer
enum OperationError: LocalizedError
{
@@ -42,9 +43,11 @@ enum OperationError: LocalizedError
case uninstall
case lookupApps
case detach
case attach
case functionArguments
case profileInstall
case profileManage
case noConnection
case invalidPairingFile
var failureReason: String? {
switch self {
@@ -70,9 +73,11 @@ enum OperationError: LocalizedError
case .uninstall: return NSLocalizedString("Unable to uninstall the app", comment: "")
case .lookupApps: return NSLocalizedString("Unable to fetch apps from the device", comment: "")
case .detach: return NSLocalizedString("Unable to detach from the app's process", comment: "")
case .attach: return NSLocalizedString("Unable to attach to the app's process", comment: "")
case .functionArguments: return NSLocalizedString("A function was passed invalid arguments", comment: "")
case .profileInstall: return NSLocalizedString("Unable to manage profiles on the device", comment: "")
case .profileManage: return NSLocalizedString("Unable to manage profiles on the device", comment: "")
case .noConnection: return NSLocalizedString("Unable to connect to the device, make sure Wireguard is enabled and you're connected to WiFi", comment: "")
case .invalidPairingFile: return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use jitterbugpair to generate it", comment: "")
}
}
@@ -118,49 +123,50 @@ enum OperationError: LocalizedError
}
}
func minimuxer_to_operation(code: Int32) -> OperationError {
switch code {
case 1:
/// crashes if error is not a MinimuxerError
func minimuxerToOperationError(_ error: Error) -> OperationError {
switch error as! MinimuxerError {
case .NoDevice:
return OperationError.noDevice
case 2:
return OperationError.createService(name: "debug")
case 3:
return OperationError.createService(name: "instproxy")
case 4:
return OperationError.getFromDevice(name: "installed apps")
case 5:
return OperationError.getFromDevice(name: "path to the app")
case 6:
return OperationError.getFromDevice(name: "bundle path")
case 7:
return OperationError.setArgument(name: "max packet")
case 8:
return OperationError.setArgument(name: "working directory")
case 9:
return OperationError.setArgument(name: "argv")
case 10:
return OperationError.getFromDevice(name: "launch success")
case 11:
return OperationError.detach
case 12:
return OperationError.functionArguments
case 13:
return OperationError.createService(name: "AFC")
case 14:
return OperationError.afc
case 15:
return OperationError.install
case 16:
return OperationError.uninstall
case 17:
return OperationError.createService(name: "misagent")
case 18:
return OperationError.profileInstall
case 19:
return OperationError.profileInstall
case 20:
case .NoConnection:
return OperationError.noConnection
default:
return OperationError.unknown
case .PairingFile:
return OperationError.invalidPairingFile
case .CreateDebug:
return OperationError.createService(name: "debug")
case .CreateInstproxy:
return OperationError.createService(name: "instproxy")
case .LookupApps:
return OperationError.getFromDevice(name: "installed apps")
case .FindApp:
return OperationError.getFromDevice(name: "path to the app")
case .BundlePath:
return OperationError.getFromDevice(name: "bundle path")
case .MaxPacket:
return OperationError.setArgument(name: "max packet")
case .WorkingDirectory:
return OperationError.setArgument(name: "working directory")
case .Argv:
return OperationError.setArgument(name: "argv")
case .LaunchSuccess:
return OperationError.getFromDevice(name: "launch success")
case .Detach:
return OperationError.detach
case .Attach:
return OperationError.attach
case .CreateAfc:
return OperationError.createService(name: "AFC")
case .RwAfc:
return OperationError.afc
case .InstallApp:
return OperationError.install
case .UninstallApp:
return OperationError.uninstall
case .CreateMisagent:
return OperationError.createService(name: "misagent")
case .ProfileInstall:
return OperationError.profileManage
case .ProfileRemove:
return OperationError.profileManage
}
}

View File

@@ -49,15 +49,12 @@ final class RefreshAppOperation: ResultOperation<InstalledApp>
for p in profiles {
do {
let x = try install_provisioning_profile(plist: p.value.data)
if case .Bad(let code) = x {
self.finish(.failure(minimuxer_to_operation(code: code)))
}
} catch Uhoh.Bad(let code) {
self.finish(.failure(minimuxer_to_operation(code: code)))
let bytes = p.value.data.toRustByteSlice()
try install_provisioning_profile(bytes.forRust())
} catch {
self.finish(.failure(OperationError.unknown))
return self.finish(.failure(minimuxerToOperationError(error)))
}
self.progress.completedUnitCount += 1
let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.bundleIdentifier), app.bundleIdentifier)

View File

@@ -39,15 +39,11 @@ final class RemoveAppOperation: ResultOperation<InstalledApp>
let resignedBundleIdentifier = installedApp.resignedBundleIdentifier
do {
let res = try remove_app(app_id: resignedBundleIdentifier)
if case Uhoh.Bad(let code) = res {
self.finish(.failure(minimuxer_to_operation(code: code)))
}
} catch Uhoh.Bad(let code) {
self.finish(.failure(minimuxer_to_operation(code: code)))
try remove_app(resignedBundleIdentifier)
} catch {
self.finish(.failure(ALTServerError(.appDeletionFailed)))
return self.finish(.failure(minimuxerToOperationError(error)))
}
DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
self.progress.completedUnitCount += 1

View File

@@ -61,6 +61,7 @@ final class ResignAppOperation: ResultOperation<ALTApplication>
{
let destinationURL = InstalledApp.refreshedIPAURL(for: app)
try FileManager.default.copyItem(at: resignedURL, to: destinationURL, shouldReplace: true)
print("Successfully resigned app to \(destinationURL.absoluteString)")
// Use appBundleURL since we need an app bundle, not .ipa.
guard let resignedApplication = ALTApplication(fileURL: appBundleURL) else { throw OperationError.invalidApp }

View File

@@ -9,6 +9,7 @@ import Foundation
import Network
import AltStoreCore
import minimuxer
@objc(SendAppOperation)
final class SendAppOperation: ResultOperation<()>
@@ -44,24 +45,18 @@ final class SendAppOperation: ResultOperation<()>
print("AFC App `fileURL`: \(fileURL.absoluteString)")
let ns_bundle = NSString(string: app.bundleIdentifier)
let ns_bundle_ptr = UnsafeMutablePointer<CChar>(mutating: ns_bundle.utf8String)
if let data = NSData(contentsOf: fileURL) {
let pls = UnsafeMutablePointer<UInt8>.allocate(capacity: data.length)
for (index, data) in data.enumerated() {
pls[index] = data
}
let res = minimuxer_yeet_app_afc(ns_bundle_ptr, pls, UInt(data.length))
if res == 0 {
print("minimuxer_yeet_app_afc `res` == \(res)")
self.progress.completedUnitCount += 1
self.finish(.success(()))
} else {
self.finish(.failure(minimuxer_to_operation(code: res)))
do {
let bytes = Data(data).toRustByteSlice()
try yeet_app_afc(app.bundleIdentifier, bytes.forRust())
} catch {
return self.finish(.failure(minimuxerToOperationError(error)))
}
self.progress.completedUnitCount += 1
self.finish(.success(()))
} else {
print("IPA doesn't exist????")
self.finish(.failure(ALTServerError(.underlyingError)))
}
}

View File

@@ -14,11 +14,14 @@ ORG_IDENTIFIER = com.SideStore
ORG_PREFIX = $(ORG_IDENTIFIER)
PRODUCT_NAME = SideStore
EXTENSION_PREFIX = $(ORG_PREFIX).SideStore
//PRODUCT_NAME[configuration=Debug] = Prov Debug
PRODUCT_BUNDLE_IDENTIFIER = $(ORG_PREFIX).SideStore
//PRODUCT_BUNDLE_IDENTIFIER[configuration=Debug] = $(ORG_PREFIX).$(PROJECT_NAME:lower)-debug
// add team ID to bundle ID for debug builds since these will most likely be installed via Xcode
// SideStore will expect the team ID to be at the end of the bundle ID, but this doesn't happen when we install via Xcode
// we don't want to do this for release since those builds will most likely be installed via SideServer, which adds the team ID
PRODUCT_BUNDLE_IDENTIFIER[config=Debug] = $(ORG_PREFIX).SideStore.$(DEVELOPMENT_TEAM)
APP_GROUP_IDENTIFIER = $(ORG_PREFIX).SideStore
EXTENSION_PREFIX = $(PRODUCT_BUNDLE_IDENTIFIER)
APP_GROUP_IDENTIFIER = $(PRODUCT_BUNDLE_IDENTIFIER)
ICLOUD_CONTAINER_IDENTIFIER = iCloud.$(ORG_PREFIX).$(PROJECT_NAME)

View File

@@ -16,8 +16,8 @@ check_for_update() {
LAST_FETCH=`cat .last-prebuilt-fetch-$1 | perl -n -e '/([0-9]*),([^ ]*)$/ && print $1'`
LAST_COMMIT=`cat .last-prebuilt-fetch-$1 | perl -n -e '/([0-9]*),([^ ]*)$/ && print $2'`
# fetch if last fetch was over 6 hours ago
if [[ $LAST_FETCH -lt $(expr $(date +%s) - 21600) ]] || [[ "$2" == "force" ]]; then
# fetch if last fetch was over 1 hour ago
if [[ $LAST_FETCH -lt $(expr $(date +%s) - 3600) ]] || [[ "$2" == "force" ]]; then
echo "Checking $1 for update"
echo
LATEST_COMMIT=`curl https://api.github.com/repos/SideStore/$1/releases/latest | perl -n -e '/Commit: https:\\/\\/github\\.com\\/[^\\/]*\\/[^\\/]*\\/commit\\/([^"]*)/ && print $1'`
@@ -27,16 +27,30 @@ check_for_update() {
if [[ "$LAST_COMMIT" != "$LATEST_COMMIT" ]]; then
echo "Found update, downloading binaries"
echo
wget -O "$1/lib$1.a" "https://github.com/SideStore/$1/releases/latest/download/lib$1.a"
wget -O "$1/lib$1-sim.a" "https://github.com/SideStore/$1/releases/latest/download/lib$1-sim.a"
wget -O "$1/$1.h" "https://github.com/SideStore/$1/releases/latest/download/$1.h"
echo
if [[ "$1" != "minimuxer" ]]; then
wget -O "$1/lib$1.a" "https://github.com/SideStore/$1/releases/latest/download/lib$1.a"
wget -O "$1/$1.h" "https://github.com/SideStore/$1/releases/latest/download/$1.h"
echo
else
wget -O "$1/lib$1-ios.a" "https://github.com/SideStore/$1/releases/latest/download/lib$1-ios.a"
wget -O "$1/generated.zip" "https://github.com/SideStore/$1/releases/latest/download/generated.zip"
echo
echo "Unzipping generated.zip"
cd "$1"
unzip ./generated.zip
mv -v generated/* .
rm generated.zip
rmdir generated/
cd ..
echo "Done"
fi
else
echo "Up-to-date"
fi
echo "$(date +%s),$LATEST_COMMIT" > ".last-prebuilt-fetch-$1"
else
echo "It hasn't been 6 hours and force was not specified, skipping update check for $1"
echo "It hasn't been 1 hour and force was not specified, skipping update check for $1"
fi
}

View File

@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
9961EC2829BE9C2000AF2C6F /* SwiftBridgeCore.h in Sources */ = {isa = PBXBuildFile; fileRef = 9961EC2729BE9C1200AF2C6F /* SwiftBridgeCore.h */; };
9987603329A454B500818586 /* minimuxer.h in Sources */ = {isa = PBXBuildFile; fileRef = 9987603229A454B500818586 /* minimuxer.h */; };
/* End PBXBuildFile section */
@@ -28,12 +29,22 @@
/* End PBXBuildRule section */
/* Begin PBXFileReference section */
9961EC2729BE9C1200AF2C6F /* SwiftBridgeCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SwiftBridgeCore.h; path = minimuxer/SwiftBridgeCore.h; sourceTree = "<group>"; };
9987603229A454B500818586 /* minimuxer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = minimuxer.h; path = minimuxer/minimuxer.h; sourceTree = "<group>"; };
ADDEDBA66A6E1 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
CA609C732349C7AAD9FA67C4 /* libminimuxer_static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libminimuxer_static.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
99F87D1529D8E41100B40039 /* Generated */ = {
isa = PBXGroup;
children = (
9961EC2729BE9C1200AF2C6F /* SwiftBridgeCore.h */,
9987603229A454B500818586 /* minimuxer.h */,
);
name = Generated;
sourceTree = "<group>";
};
ADDEDBA66A6E2 /* Required for static linking */ = {
isa = PBXGroup;
children = (
@@ -61,7 +72,7 @@
CA6012A875F9D65BC3C892A8 = {
isa = PBXGroup;
children = (
9987603229A454B500818586 /* minimuxer.h */,
99F87D1529D8E41100B40039 /* Generated */,
CA6012A875F922869D176AE5 /* Products */,
CA6012A875F998AF0B5890DB /* Frameworks */,
);
@@ -74,7 +85,7 @@
isa = PBXNativeTarget;
buildConfigurationList = CA600589A243A560B9642892 /* Build configuration list for PBXNativeTarget "minimuxer-staticlib" */;
buildPhases = (
9987603629A4611D00818586 /* ShellScript */,
9987603629A4611D00818586 /* Run Script */,
CA600F638141A560B9642892 /* Sources */,
CA6012A875F9AF6EBB7F357C /* Universal Binary lipo */,
);
@@ -121,7 +132,7 @@
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
9987603629A4611D00818586 /* ShellScript */ = {
9987603629A4611D00818586 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -130,10 +141,15 @@
);
inputPaths = (
);
name = "Run Script";
outputFileListPaths = (
);
outputPaths = (
./minimuxer/minimuxer.h,
./minimuxer/SwiftBridgeCore.h,
./minimuxer/minimuxer.swift,
./minimuxer/SwiftBridgeCore.swift,
"./minimuxer/minimuxer-Bridging-Header.h",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -166,6 +182,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9961EC2829BE9C2000AF2C6F /* SwiftBridgeCore.h in Sources */,
9987603329A454B500818586 /* minimuxer.h in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -182,7 +199,7 @@
INSTALL_MODE_FLAG = "";
INSTALL_OWNER = "";
LIB_FILE_NAME = "";
"LIB_FILE_NAME[sdk=iphoneos*]" = libminimuxer;
"LIB_FILE_NAME[sdk=iphoneos*]" = "libminimuxer-ios";
"LIB_FILE_NAME[sdk=iphonesimulator*]" = "libminimuxer-sim";
PRODUCT_NAME = minimuxer_static;
SKIP_INSTALL = YES;
@@ -199,7 +216,7 @@
INSTALL_MODE_FLAG = "";
INSTALL_OWNER = "";
LIB_FILE_NAME = "";
"LIB_FILE_NAME[sdk=iphoneos*]" = libminimuxer;
"LIB_FILE_NAME[sdk=iphoneos*]" = "libminimuxer-ios";
"LIB_FILE_NAME[sdk=iphonesimulator*]" = "libminimuxer-sim";
PRODUCT_NAME = minimuxer_static;
SKIP_INSTALL = YES;

View File

@@ -1,111 +0,0 @@
//
// minimuxer.swift
// minimuxer
//
// Created by Jackson Coxson on 10/27/22.
//
import Foundation
public enum Uhoh: Error {
case Good
case Bad(code: Int32)
}
public func start_minimuxer(pairing_file: String) -> Int32 {
let pf = NSString(string: pairing_file)
let pf_pointer = UnsafeMutablePointer<CChar>(mutating: pf.utf8String)
let u = NSString(string: getDocumentsDirectory().absoluteString)
let u_ptr = UnsafeMutablePointer<CChar>(mutating: u.utf8String)
return minimuxer_c_start(pf_pointer, u_ptr)
}
public func set_usbmuxd_socket() {
target_minimuxer_address()
}
public func debug_app(app_id: String) throws -> Uhoh {
let ai = NSString(string: app_id)
let ai_pointer = UnsafeMutablePointer<CChar>(mutating: ai.utf8String)
#if false // Retries
var res = minimuxer_debug_app(ai_pointer)
var attempts = 10
while (attempts != 0 && res != 0) {
print("(JIT) ATTEMPTS: \(attempts)")
res = minimuxer_debug_app(ai_pointer)
attempts -= 1
}
#else
let res = minimuxer_debug_app(ai_pointer)
#endif
if res != 0 {
throw Uhoh.Bad(code: res)
}
return Uhoh.Good
}
public func install_provisioning_profile(plist: Data) throws -> Uhoh {
let pls = String(decoding: plist, as: UTF8.self)
print(pls)
print(plist)
#if false // Retries
var res = minimuxer_install_provisioning_profile(x, UInt32(plist.count))
var attempts = 10
while (attempts != 0 && res != 0) {
print("(INSTALL) ATTEMPTS: \(attempts)")
res = minimuxer_install_provisioning_profile(x, UInt32(plist.count))
attempts -= 1
}
#else
let x = plist.withUnsafeBytes { buf in UnsafeMutableRawPointer(mutating: buf) }
#endif
let res = minimuxer_install_provisioning_profile(x, UInt32(plist.count))
if res != 0 {
throw Uhoh.Bad(code: res)
}
return Uhoh.Good
}
public func remove_provisioning_profile(id: String) throws -> Uhoh {
let id_ns = NSString(string: id)
let id_pointer = UnsafeMutablePointer<CChar>(mutating: id_ns.utf8String)
#if false // Retries
var res = minimuxer_remove_provisioning_profile(id_pointer)
var attempts = 10
while (attempts != 0 && res != 0) {
print("(REMOVE PROFILE) ATTEMPTS: \(attempts)")
res = minimuxer_remove_provisioning_profile(id_pointer)
attempts -= 1
}
#else
let res = minimuxer_remove_provisioning_profile(id_pointer)
#endif
if res != 0 {
throw Uhoh.Bad(code: res)
}
return Uhoh.Good
}
public func remove_app(app_id: String) throws -> Uhoh {
let ai = NSString(string: app_id)
let ai_pointer = UnsafeMutablePointer<CChar>(mutating: ai.utf8String)
let res = minimuxer_remove_app(ai_pointer)
if res != 0 {
throw Uhoh.Bad(code: res)
}
return Uhoh.Good
}
public func auto_mount_dev_image() {
let u = NSString(string: getDocumentsDirectory().absoluteString)
let u_ptr = UnsafeMutablePointer<CChar>(mutating: u.utf8String)
minimuxer_auto_mount(u_ptr)
}
func getDocumentsDirectory() -> URL {
// find all possible documents directories for this user
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
// just send back the first one, which ought to be the only one
return paths[0]
}