mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[AltJIT] Adds AltJIT CLI tool to enable JIT on devices running iOS 17+
Commands: altjit enable [app/pid] --udid [udid] * Enables JIT for given app/process altjit mount --udid [udid] * Mounts personalized developer disk
This commit is contained in:
9
AltJIT/AltJIT-Bridging-Header.h
Normal file
9
AltJIT/AltJIT-Bridging-Header.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ALTErrorKeys.h"
|
||||||
|
|
||||||
|
// Shared
|
||||||
|
#import "ALTWrappedError.h"
|
||||||
|
#import "NSError+ALTServerError.h"
|
||||||
18
AltJIT/AltJIT.swift
Normal file
18
AltJIT/AltJIT.swift
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// AltJIT.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 8/29/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import OSLog
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct AltJIT: AsyncParsableCommand
|
||||||
|
{
|
||||||
|
static let configuration = CommandConfiguration(commandName: "altjit",
|
||||||
|
abstract: "Enable JIT for sideloaded apps.",
|
||||||
|
subcommands: [EnableJIT.self, MountDisk.self])
|
||||||
|
}
|
||||||
452
AltJIT/Commands/EnableJIT.swift
Normal file
452
AltJIT/Commands/EnableJIT.swift
Normal file
@@ -0,0 +1,452 @@
|
|||||||
|
//
|
||||||
|
// EnableJIT.swift
|
||||||
|
// AltPackage
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 8/29/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import OSLog
|
||||||
|
import RegexBuilder
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
struct EnableJIT: PythonCommand
|
||||||
|
{
|
||||||
|
static let configuration = CommandConfiguration(commandName: "enable", abstract: "Enable JIT for a specific app on your device.")
|
||||||
|
|
||||||
|
@Argument(help: "The name or PID of the app to enable JIT for.", transform: AppProcess.init)
|
||||||
|
var process: AppProcess
|
||||||
|
|
||||||
|
@Option(help: "Your iOS device's UDID.")
|
||||||
|
var udid: String
|
||||||
|
|
||||||
|
// PythonCommand
|
||||||
|
var pythonPath: String?
|
||||||
|
|
||||||
|
mutating func run() async throws
|
||||||
|
{
|
||||||
|
// Use local variables to fix "escaping autoclosure captures mutating self parameter" compiler error.
|
||||||
|
let process = self.process
|
||||||
|
let udid = self.udid
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Logger.main.info("Enabling JIT for \(process, privacy: .private(mask: .hash)) on device \(udid, privacy: .private(mask: .hash))...")
|
||||||
|
|
||||||
|
try await self.prepare()
|
||||||
|
|
||||||
|
let rsdTunnel = try await self.startRSDTunnel()
|
||||||
|
defer { rsdTunnel.process.terminate() }
|
||||||
|
print("Connected to device \(self.udid)!", rsdTunnel)
|
||||||
|
|
||||||
|
let port = try await self.startDebugServer(rsdTunnel: rsdTunnel)
|
||||||
|
print("Started debugserver on port \(port).")
|
||||||
|
|
||||||
|
print("Attaching debugger...")
|
||||||
|
let lldb = try await self.attachDebugger(ipAddress: rsdTunnel.ipAddress, port: port)
|
||||||
|
defer { lldb.terminate() }
|
||||||
|
print("Attached debugger to \(process).")
|
||||||
|
|
||||||
|
try await self.detachDebugger(lldb)
|
||||||
|
print("Detached debugger from \(process).")
|
||||||
|
|
||||||
|
print("✅ Successfully enabled JIT for \(process) on device \(udid)!")
|
||||||
|
}
|
||||||
|
catch let error as ProcessError
|
||||||
|
{
|
||||||
|
if let output = error.output
|
||||||
|
{
|
||||||
|
print(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
print("❌ Unable to enable JIT for \(process) on device \(udid).")
|
||||||
|
print(error.localizedDescription)
|
||||||
|
|
||||||
|
Logger.main.error("Failed to enable JIT for \(process, privacy: .private(mask: .hash)) on device \(udid, privacy: .private(mask: .hash)). \(error, privacy: .public)")
|
||||||
|
|
||||||
|
throw ExitCode.failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension EnableJIT
|
||||||
|
{
|
||||||
|
func startRSDTunnel() async throws -> RemoteServiceDiscoveryTunnel
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Logger.main.info("Starting RSD tunnel...")
|
||||||
|
|
||||||
|
let process = try Process.launch(.python3, arguments: ["-u", "-m", "pymobiledevice3", "remote", "start-quic-tunnel", "--udid", self.udid], environment: self.processEnvironment)
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
let rsdTunnel = try await withTimeout(seconds: 20) {
|
||||||
|
let regex = Regex {
|
||||||
|
"--rsd"
|
||||||
|
|
||||||
|
OneOrMore(.whitespace)
|
||||||
|
|
||||||
|
Capture {
|
||||||
|
OneOrMore(.anyGraphemeCluster)
|
||||||
|
}
|
||||||
|
|
||||||
|
OneOrMore(.whitespace)
|
||||||
|
|
||||||
|
TryCapture {
|
||||||
|
OneOrMore(.digit)
|
||||||
|
} transform: { match in
|
||||||
|
Int(match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for try await line in process.outputLines
|
||||||
|
{
|
||||||
|
if let match = line.firstMatch(of: regex)
|
||||||
|
{
|
||||||
|
let rsdTunnel = RemoteServiceDiscoveryTunnel(ipAddress: String(match.1), port: match.2, process: process)
|
||||||
|
return rsdTunnel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ProcessError.unexpectedOutput(executableURL: .python3, output: process.output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST close standardOutput in order to stream output later.
|
||||||
|
process.stopOutput()
|
||||||
|
|
||||||
|
return rsdTunnel
|
||||||
|
}
|
||||||
|
catch is TimedOutError
|
||||||
|
{
|
||||||
|
process.terminate()
|
||||||
|
|
||||||
|
let error = ProcessError.timedOut(executableURL: .python3, output: process.output)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
process.terminate()
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as NSError
|
||||||
|
{
|
||||||
|
let localizedFailure = NSLocalizedString("Could not connect to device \(self.udid).", comment: "")
|
||||||
|
throw error.withLocalizedFailure(localizedFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startDebugServer(rsdTunnel: RemoteServiceDiscoveryTunnel) async throws -> Int
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Logger.main.info("Starting debugserver...")
|
||||||
|
|
||||||
|
return try await withTimeout(seconds: 10) {
|
||||||
|
let arguments = ["-u", "-m", "pymobiledevice3", "developer", "debugserver", "start-server"] + rsdTunnel.commandArguments
|
||||||
|
|
||||||
|
let output = try await Process.launchAndWait(.python3, arguments: arguments, environment: self.processEnvironment)
|
||||||
|
|
||||||
|
let port = Reference(Int.self)
|
||||||
|
let regex = Regex {
|
||||||
|
"connect://"
|
||||||
|
|
||||||
|
OneOrMore(.anyGraphemeCluster, .eager)
|
||||||
|
|
||||||
|
":"
|
||||||
|
|
||||||
|
TryCapture(as: port) {
|
||||||
|
OneOrMore(.digit)
|
||||||
|
} transform: { match in
|
||||||
|
Int(match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let match = output.firstMatch(of: regex)
|
||||||
|
{
|
||||||
|
return match[port]
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ProcessError.unexpectedOutput(executableURL: .python3, output: output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as NSError
|
||||||
|
{
|
||||||
|
let localizedFailure = NSLocalizedString("Could not start debugserver on device \(self.udid).", comment: "")
|
||||||
|
throw error.withLocalizedFailure(localizedFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func attachDebugger(ipAddress: String, port: Int) async throws -> Process
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Logger.main.info("Attaching debugger...")
|
||||||
|
|
||||||
|
let processID: Int
|
||||||
|
|
||||||
|
switch self.process
|
||||||
|
{
|
||||||
|
case .pid(let pid): processID = pid
|
||||||
|
case .name(let name):
|
||||||
|
guard let pid = try await self.getPID(for: name) else { throw JITError.processNotRunning(self.process) }
|
||||||
|
processID = pid
|
||||||
|
}
|
||||||
|
|
||||||
|
let process = try Process.launch(.lldb, environment: self.processEnvironment)
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try await withThrowingTaskGroup(of: Void.self) { taskGroup in
|
||||||
|
|
||||||
|
// // Throw error if program terminates.
|
||||||
|
// taskGroup.addTask {
|
||||||
|
// try await withCheckedThrowingContinuation { continuation in
|
||||||
|
// process.terminationHandler = { process in
|
||||||
|
// Task {
|
||||||
|
// // Should NEVER be called unless an error occurs.
|
||||||
|
// continuation.resume(throwing: ProcessError.terminated(executableURL: .lldb, exitCode: process.terminationStatus, output: process.output))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
taskGroup.addTask {
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try await self.sendDebuggerCommand("platform select remote-ios", to: process, timeout: 5) {
|
||||||
|
ChoiceOf {
|
||||||
|
"SDK Roots:"
|
||||||
|
"unable to locate SDK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ipAddress = "[\(ipAddress)]"
|
||||||
|
let connectCommand = "process connect connect://\(ipAddress):\(port)"
|
||||||
|
try await self.sendDebuggerCommand(connectCommand, to: process, timeout: 10)
|
||||||
|
|
||||||
|
try await self.sendDebuggerCommand("settings set target.memory-module-load-level minimal", to: process, timeout: 5)
|
||||||
|
|
||||||
|
let attachCommand = "attach -p \(processID)"
|
||||||
|
let failureMessage = "attach failed"
|
||||||
|
let output = try await self.sendDebuggerCommand(attachCommand, to: process, timeout: 120) {
|
||||||
|
|
||||||
|
ChoiceOf {
|
||||||
|
failureMessage
|
||||||
|
|
||||||
|
Regex {
|
||||||
|
"Process "
|
||||||
|
OneOrMore(.digit)
|
||||||
|
" stopped"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if output.contains(failureMessage)
|
||||||
|
{
|
||||||
|
throw ProcessError.failed(executableURL: .lldb, exitCode: -1, output: process.output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch is TimedOutError
|
||||||
|
{
|
||||||
|
let error = ProcessError.timedOut(executableURL: .lldb, output: process.output)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until first child task returns
|
||||||
|
_ = try await taskGroup.next()!
|
||||||
|
|
||||||
|
// Cancel remaining tasks
|
||||||
|
taskGroup.cancelAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
return process
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
process.terminate()
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as NSError
|
||||||
|
{
|
||||||
|
let localizedFailure = String(format: NSLocalizedString("Could not attach debugger to %@.", comment: ""), self.process.description)
|
||||||
|
throw error.withLocalizedFailure(localizedFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func detachDebugger(_ process: Process) async throws
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Logger.main.info("Detaching debugger...")
|
||||||
|
|
||||||
|
try await withThrowingTaskGroup(of: Void.self) { taskGroup in
|
||||||
|
|
||||||
|
// // Throw error if program terminates.
|
||||||
|
// taskGroup.addTask {
|
||||||
|
// try await withCheckedThrowingContinuation { continuation in
|
||||||
|
// process.terminationHandler = { process in
|
||||||
|
// if process.terminationStatus == 0
|
||||||
|
// {
|
||||||
|
// continuation.resume()
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// continuation.resume(throwing: ProcessError.terminated(executableURL: .lldb, exitCode: process.terminationStatus, output: process.output))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
taskGroup.addTask {
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try await self.sendDebuggerCommand("c", to: process, timeout: 10) {
|
||||||
|
"Process "
|
||||||
|
OneOrMore(.digit)
|
||||||
|
" resuming"
|
||||||
|
}
|
||||||
|
|
||||||
|
try await self.sendDebuggerCommand("detach", to: process, timeout: 10) {
|
||||||
|
"Process "
|
||||||
|
OneOrMore(.digit)
|
||||||
|
" detached"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch is TimedOutError
|
||||||
|
{
|
||||||
|
let error = ProcessError.timedOut(executableURL: .lldb, output: process.output)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until first child task returns
|
||||||
|
_ = try await taskGroup.next()!
|
||||||
|
|
||||||
|
// Cancel remaining tasks
|
||||||
|
taskGroup.cancelAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as NSError
|
||||||
|
{
|
||||||
|
let localizedFailure = NSLocalizedString("Could not detach debugger from \(self.process).", comment: "")
|
||||||
|
throw error.withLocalizedFailure(localizedFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension EnableJIT
|
||||||
|
{
|
||||||
|
func getPID(for name: String) async throws -> Int?
|
||||||
|
{
|
||||||
|
Logger.main.info("Retrieving PID for \(name, privacy: .private(mask: .hash))...")
|
||||||
|
|
||||||
|
let arguments = ["-m", "pymobiledevice3", "processes", "pgrep", name, "--udid", self.udid]
|
||||||
|
let output = try await Process.launchAndWait(.python3, arguments: arguments, environment: self.processEnvironment)
|
||||||
|
|
||||||
|
let regex = Regex {
|
||||||
|
"INFO"
|
||||||
|
|
||||||
|
OneOrMore(.whitespace)
|
||||||
|
|
||||||
|
TryCapture {
|
||||||
|
OneOrMore(.digit)
|
||||||
|
} transform: { match in
|
||||||
|
Int(match)
|
||||||
|
}
|
||||||
|
|
||||||
|
OneOrMore(.whitespace)
|
||||||
|
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
if let match = output.firstMatch(of: regex)
|
||||||
|
{
|
||||||
|
Logger.main.info("\(name, privacy: .private(mask: .hash)) PID is \(match.1)")
|
||||||
|
return match.1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func sendDebuggerCommand(_ command: String, to process: Process, timeout: TimeInterval,
|
||||||
|
@RegexComponentBuilder regex: @escaping () -> (some RegexComponent<Substring>)? = { Optional<Regex<Substring>>.none }) async throws -> String
|
||||||
|
{
|
||||||
|
guard let inputPipe = process.standardInput as? Pipe else { preconditionFailure("`process` must have a Pipe as its standardInput") }
|
||||||
|
defer {
|
||||||
|
inputPipe.fileHandleForWriting.writeabilityHandler = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let initialOutput = process.output
|
||||||
|
|
||||||
|
let data = (command + "\n").data(using: .utf8)! // Will always succeed.
|
||||||
|
Logger.main.info("Sending lldb command: \(command, privacy: .public)")
|
||||||
|
|
||||||
|
let output = try await withTimeout(seconds: timeout) {
|
||||||
|
// Wait until process is ready to receive input.
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
inputPipe.fileHandleForWriting.writeabilityHandler = { fileHandle in
|
||||||
|
inputPipe.fileHandleForWriting.writeabilityHandler = nil
|
||||||
|
|
||||||
|
let result = Result { try fileHandle.write(contentsOf: data) }
|
||||||
|
continuation.resume(with: result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until we receive at least one line of output.
|
||||||
|
for try await _ in process.outputLines
|
||||||
|
{
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep waiting until output doesn't change.
|
||||||
|
// If regex is provided, we keep waiting until a match is found.
|
||||||
|
var previousOutput = process.output
|
||||||
|
while true
|
||||||
|
{
|
||||||
|
try await Task.sleep(for: .seconds(0.2))
|
||||||
|
|
||||||
|
let output = process.output
|
||||||
|
if output == previousOutput
|
||||||
|
{
|
||||||
|
guard let regex = regex() else {
|
||||||
|
// No regex, so break as soon as output stops changing.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if output.contains(regex)
|
||||||
|
{
|
||||||
|
// Found a match, so exit while loop.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Output hasn't changed, but regex does not match (yet).
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previousOutput = output
|
||||||
|
}
|
||||||
|
|
||||||
|
return previousOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract initialOutput from output to get just this command's output.
|
||||||
|
let commandOutput = output.replacingOccurrences(of: initialOutput, with: "")
|
||||||
|
return commandOutput
|
||||||
|
}
|
||||||
|
}
|
||||||
75
AltJIT/Commands/MountDisk.swift
Normal file
75
AltJIT/Commands/MountDisk.swift
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// MountDisk.swift
|
||||||
|
// AltPackage
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 8/31/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import OSLog
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
typealias MountError = MountErrorCode.Error
|
||||||
|
enum MountErrorCode: Int, ALTErrorEnum
|
||||||
|
{
|
||||||
|
case alreadyMounted
|
||||||
|
|
||||||
|
var errorFailureReason: String {
|
||||||
|
switch self
|
||||||
|
{
|
||||||
|
case .alreadyMounted: return NSLocalizedString("A personalized Developer Disk is already mounted.", comment: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MountDisk: PythonCommand
|
||||||
|
{
|
||||||
|
static let configuration = CommandConfiguration(commandName: "mount", abstract: "Mount a personalized developer disk image onto an iOS device.")
|
||||||
|
|
||||||
|
@Option(help: "The iOS device's UDID.")
|
||||||
|
var udid: String
|
||||||
|
|
||||||
|
// PythonCommand
|
||||||
|
var pythonPath: String?
|
||||||
|
|
||||||
|
mutating func run() async throws
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
print("Mounting personalized developer disk...")
|
||||||
|
|
||||||
|
try await self.prepare()
|
||||||
|
|
||||||
|
let output = try await Process.launchAndWait(.python3, arguments: ["-m", "pymobiledevice3", "mounter", "auto-mount", "--udid", self.udid])
|
||||||
|
if !output.contains("DeveloperDiskImage")
|
||||||
|
{
|
||||||
|
throw ProcessError.unexpectedOutput(executableURL: .python3, output: output)
|
||||||
|
}
|
||||||
|
|
||||||
|
if output.contains("already mounted")
|
||||||
|
{
|
||||||
|
throw MountError(.alreadyMounted)
|
||||||
|
}
|
||||||
|
|
||||||
|
print("✅ Successfully mounted personalized Developer Disk!")
|
||||||
|
}
|
||||||
|
catch let error as MountError where error.code == .alreadyMounted
|
||||||
|
{
|
||||||
|
// Prepend ⚠️ since this is not really an error.
|
||||||
|
let localizedDescription = "⚠️ " + error.localizedDescription
|
||||||
|
print(localizedDescription)
|
||||||
|
|
||||||
|
throw ExitCode.success
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Output failure message first before error.
|
||||||
|
print("❌ Unable to mount personalized Developer Disk.")
|
||||||
|
print(error.localizedDescription)
|
||||||
|
|
||||||
|
throw ExitCode.failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
AltJIT/Extensions/Logger+AltJIT.swift
Normal file
16
AltJIT/Extensions/Logger+AltJIT.swift
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Logger+AltJIT.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 8/29/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import OSLog
|
||||||
|
|
||||||
|
public extension Logger
|
||||||
|
{
|
||||||
|
static let altjitSubsystem = Bundle.main.bundleIdentifier!
|
||||||
|
|
||||||
|
static let main = Logger(subsystem: altjitSubsystem, category: "AltJIT")
|
||||||
|
}
|
||||||
57
AltJIT/Extensions/Task+Timeout.swift
Normal file
57
AltJIT/Extensions/Task+Timeout.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// Task+Timeout.swift
|
||||||
|
// AltPackage
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 8/31/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
// Based heavily on https://forums.swift.org/t/running-an-async-task-with-a-timeout/49733/13
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct TimedOutError: LocalizedError
|
||||||
|
{
|
||||||
|
var duration: TimeInterval
|
||||||
|
|
||||||
|
public var errorDescription: String? {
|
||||||
|
//TODO: Change pluralization for 1 second.
|
||||||
|
let errorDescription = String(format: NSLocalizedString("The task timed out after %@ seconds.", comment: ""), self.duration.formatted())
|
||||||
|
return errorDescription
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Execute an operation in the current task subject to a timeout.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - seconds: The duration in seconds `operation` is allowed to run before timing out.
|
||||||
|
/// - operation: The async operation to perform.
|
||||||
|
/// - Returns: Returns the result of `operation` if it completed in time.
|
||||||
|
/// - Throws: Throws ``TimedOutError`` if the timeout expires before `operation` completes.
|
||||||
|
/// If `operation` throws an error before the timeout expires, that error is propagated to the caller.
|
||||||
|
func withTimeout<R>(seconds: TimeInterval, file: StaticString = #file, line: Int = #line, operation: @escaping @Sendable () async throws -> R) async throws -> R
|
||||||
|
{
|
||||||
|
return try await withThrowingTaskGroup(of: R.self) { group in
|
||||||
|
let deadline = Date(timeIntervalSinceNow: seconds)
|
||||||
|
|
||||||
|
// Start actual work.
|
||||||
|
group.addTask {
|
||||||
|
return try await operation()
|
||||||
|
}
|
||||||
|
// Start timeout child task.
|
||||||
|
group.addTask {
|
||||||
|
let interval = deadline.timeIntervalSinceNow
|
||||||
|
if interval > 0 {
|
||||||
|
try await Task.sleep(for: .seconds(interval))
|
||||||
|
}
|
||||||
|
try Task.checkCancellation()
|
||||||
|
// We’ve reached the timeout.
|
||||||
|
throw TimedOutError(duration: seconds)
|
||||||
|
}
|
||||||
|
// First finished child task wins, cancel the other task.
|
||||||
|
let result = try await group.next()!
|
||||||
|
group.cancelAll()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
15
AltJIT/Extensions/URL+Tools.swift
Normal file
15
AltJIT/Extensions/URL+Tools.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// URL+Tools.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/3/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension URL
|
||||||
|
{
|
||||||
|
static let python3 = URL(fileURLWithPath: "/usr/bin/python3")
|
||||||
|
static let lldb = URL(fileURLWithPath: "/usr/bin/lldb")
|
||||||
|
}
|
||||||
14
AltJIT/Types/ALTErrorKeys.h
Normal file
14
AltJIT/Types/ALTErrorKeys.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// ALTErrorKeys.h
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/1/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@import Foundation;
|
||||||
|
|
||||||
|
// Can't import AltSign (for reasons), so re-declare these constants here instead.
|
||||||
|
extern NSErrorUserInfoKey const ALTSourceFileErrorKey;
|
||||||
|
extern NSErrorUserInfoKey const ALTSourceLineErrorKey;
|
||||||
|
extern NSErrorUserInfoKey const ALTAppNameErrorKey;
|
||||||
13
AltJIT/Types/ALTErrorKeys.m
Normal file
13
AltJIT/Types/ALTErrorKeys.m
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// ALTErrorKeys.m
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/1/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ALTErrorKeys.h"
|
||||||
|
|
||||||
|
NSErrorUserInfoKey const ALTSourceFileErrorKey = @"ALTSourceFile";
|
||||||
|
NSErrorUserInfoKey const ALTSourceLineErrorKey = @"ALTSourceLine";
|
||||||
|
NSErrorUserInfoKey const ALTAppNameErrorKey = @"appName";
|
||||||
58
AltJIT/Types/PythonCommand.swift
Normal file
58
AltJIT/Types/PythonCommand.swift
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// PythonCommand.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/6/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
protocol PythonCommand: AsyncParsableCommand
|
||||||
|
{
|
||||||
|
var pythonPath: String? { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PythonCommand
|
||||||
|
{
|
||||||
|
var processEnvironment: [String: String] {
|
||||||
|
var environment = ProcessInfo.processInfo.environment
|
||||||
|
|
||||||
|
if let pythonPath
|
||||||
|
{
|
||||||
|
environment["PYTHONPATH"] = pythonPath
|
||||||
|
}
|
||||||
|
|
||||||
|
return environment
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func prepare() async throws
|
||||||
|
{
|
||||||
|
let pythonPath = try await self.readPythonPath()
|
||||||
|
self.pythonPath = pythonPath.path(percentEncoded: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension PythonCommand
|
||||||
|
{
|
||||||
|
func readPythonPath() async throws -> URL
|
||||||
|
{
|
||||||
|
let processOutput: String
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
processOutput = try await Process.launchAndWait(.python3, arguments: ["-m", "site", "--user-site"])
|
||||||
|
}
|
||||||
|
catch let error as ProcessError where error.exitCode == 2
|
||||||
|
{
|
||||||
|
// Ignore exit code 2.
|
||||||
|
guard let output = error.output else { throw error }
|
||||||
|
processOutput = output
|
||||||
|
}
|
||||||
|
|
||||||
|
let sanitizedOutput = processOutput.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
let pythonURL = URL(filePath: sanitizedOutput)
|
||||||
|
return pythonURL
|
||||||
|
}
|
||||||
|
}
|
||||||
41
AltJIT/Types/RemoteServiceDiscoveryTunnel.swift
Normal file
41
AltJIT/Types/RemoteServiceDiscoveryTunnel.swift
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// RemoteServiceDiscoveryTunnel.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/3/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
final class RemoteServiceDiscoveryTunnel
|
||||||
|
{
|
||||||
|
let ipAddress: String
|
||||||
|
let port: Int
|
||||||
|
|
||||||
|
let process: Process
|
||||||
|
|
||||||
|
var commandArguments: [String] {
|
||||||
|
["--rsd", self.ipAddress, String(self.port)]
|
||||||
|
}
|
||||||
|
|
||||||
|
init(ipAddress: String, port: Int, process: Process)
|
||||||
|
{
|
||||||
|
self.ipAddress = ipAddress
|
||||||
|
self.port = port
|
||||||
|
|
||||||
|
self.process = process
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit
|
||||||
|
{
|
||||||
|
self.process.terminate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RemoteServiceDiscoveryTunnel: CustomStringConvertible
|
||||||
|
{
|
||||||
|
var description: String {
|
||||||
|
"\(self.ipAddress) \(self.port)"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -355,9 +355,12 @@
|
|||||||
D51AD27F29356B7B00967AAA /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
|
D51AD27F29356B7B00967AAA /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
|
||||||
D51AD28029356B8000967AAA /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
|
D51AD28029356B8000967AAA /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
|
||||||
D52C08EE28AEC37A006C4AE5 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52C08ED28AEC37A006C4AE5 /* AppVersion.swift */; };
|
D52C08EE28AEC37A006C4AE5 /* AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52C08ED28AEC37A006C4AE5 /* AppVersion.swift */; };
|
||||||
|
D52DD35E2AAA89A600A7F2B6 /* AltSign-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = D52DD35D2AAA89A600A7F2B6 /* AltSign-Dynamic */; };
|
||||||
|
D52DD35F2AAA89A700A7F2B6 /* AltSign-Dynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = D52DD35D2AAA89A600A7F2B6 /* AltSign-Dynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
D52EF2BE2A0594550096C377 /* AppDetailCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52EF2BD2A0594550096C377 /* AppDetailCollectionViewController.swift */; };
|
D52EF2BE2A0594550096C377 /* AppDetailCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52EF2BD2A0594550096C377 /* AppDetailCollectionViewController.swift */; };
|
||||||
D533E8B72727841800A9B5DD /* libAppleArchive.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8B62727841800A9B5DD /* libAppleArchive.tbd */; settings = {ATTRIBUTES = (Weak, ); }; };
|
D533E8B72727841800A9B5DD /* libAppleArchive.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8B62727841800A9B5DD /* libAppleArchive.tbd */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
D533E8BE2727BBF800A9B5DD /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8BD2727BBF800A9B5DD /* libcurl.a */; };
|
D533E8BE2727BBF800A9B5DD /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D533E8BD2727BBF800A9B5DD /* libcurl.a */; };
|
||||||
|
D537C85B2AA9507A009A1E08 /* libcorecrypto.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D537C85A2AA95066009A1E08 /* libcorecrypto.tbd */; platformFilters = (macos, ); };
|
||||||
D53D84022A2158FC00543C3B /* Permissions.plist in Resources */ = {isa = PBXBuildFile; fileRef = D53D84012A2158FC00543C3B /* Permissions.plist */; };
|
D53D84022A2158FC00543C3B /* Permissions.plist in Resources */ = {isa = PBXBuildFile; fileRef = D53D84012A2158FC00543C3B /* Permissions.plist */; };
|
||||||
D54058B92A1D6269008CCC58 /* AppPermissionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54058B82A1D6269008CCC58 /* AppPermissionProtocol.swift */; };
|
D54058B92A1D6269008CCC58 /* AppPermissionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54058B82A1D6269008CCC58 /* AppPermissionProtocol.swift */; };
|
||||||
D54058BB2A1D8FE3008CCC58 /* UIColor+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54058BA2A1D8FE3008CCC58 /* UIColor+AltStore.swift */; };
|
D54058BB2A1D8FE3008CCC58 /* UIColor+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54058BA2A1D8FE3008CCC58 /* UIColor+AltStore.swift */; };
|
||||||
@@ -392,7 +395,15 @@
|
|||||||
D5935AED29C39DE300C157EF /* SourceDetailsComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5935AEC29C39DE300C157EF /* SourceDetailsComponents.swift */; };
|
D5935AED29C39DE300C157EF /* SourceDetailsComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5935AEC29C39DE300C157EF /* SourceDetailsComponents.swift */; };
|
||||||
D5935AEF29C3B23600C157EF /* Sources.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D5935AEE29C3B23600C157EF /* Sources.storyboard */; };
|
D5935AEF29C3B23600C157EF /* Sources.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D5935AEE29C3B23600C157EF /* Sources.storyboard */; };
|
||||||
D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; };
|
D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; };
|
||||||
|
D59A6B7B2AA91B8E00F61259 /* PythonCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59A6B7A2AA91B8E00F61259 /* PythonCommand.swift */; };
|
||||||
|
D59A6B7F2AA9226C00F61259 /* AppProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59A6B7D2AA9226C00F61259 /* AppProcess.swift */; };
|
||||||
|
D59A6B822AA92D1C00F61259 /* Process+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59A6B802AA92D1C00F61259 /* Process+Conveniences.swift */; };
|
||||||
|
D59A6B842AA932F700F61259 /* Logger+AltServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59A6B832AA932F700F61259 /* Logger+AltServer.swift */; };
|
||||||
D5A0537329B91DB400997551 /* SourceDetailContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A0537229B91DB400997551 /* SourceDetailContentViewController.swift */; };
|
D5A0537329B91DB400997551 /* SourceDetailContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A0537229B91DB400997551 /* SourceDetailContentViewController.swift */; };
|
||||||
|
D5A1D2E42AA50EB60066CACC /* JITError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A1D2E32AA50EB60066CACC /* JITError.swift */; };
|
||||||
|
D5A1D2E92AA512940066CACC /* RemoteServiceDiscoveryTunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A1D2E82AA512940066CACC /* RemoteServiceDiscoveryTunnel.swift */; };
|
||||||
|
D5A1D2EB2AA513410066CACC /* URL+Tools.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A1D2EA2AA513410066CACC /* URL+Tools.swift */; };
|
||||||
|
D5A1D2EC2AA51D490066CACC /* ProcessError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A1B2AA284ED00EF863D /* ProcessError.swift */; };
|
||||||
D5A2193429B14F94002229FC /* DeprecatedAPIs.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A2193329B14F94002229FC /* DeprecatedAPIs.swift */; };
|
D5A2193429B14F94002229FC /* DeprecatedAPIs.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A2193329B14F94002229FC /* DeprecatedAPIs.swift */; };
|
||||||
D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */; };
|
D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */; };
|
||||||
D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; };
|
D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; };
|
||||||
@@ -414,6 +425,18 @@
|
|||||||
D5F99A1828D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */; };
|
D5F99A1828D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */; };
|
||||||
D5F99A1A28D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */; };
|
D5F99A1A28D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */; };
|
||||||
D5FB7A0E2AA25A4E00EF863D /* Previews.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D5FB7A0D2AA25A4E00EF863D /* Previews.xcassets */; };
|
D5FB7A0E2AA25A4E00EF863D /* Previews.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D5FB7A0D2AA25A4E00EF863D /* Previews.xcassets */; };
|
||||||
|
D5FB7A212AA284ED00EF863D /* EnableJIT.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A1A2AA284ED00EF863D /* EnableJIT.swift */; };
|
||||||
|
D5FB7A242AA284ED00EF863D /* Logger+AltJIT.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A1D2AA284ED00EF863D /* Logger+AltJIT.swift */; };
|
||||||
|
D5FB7A252AA284ED00EF863D /* AltJIT.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A1E2AA284ED00EF863D /* AltJIT.swift */; };
|
||||||
|
D5FB7A262AA284ED00EF863D /* MountDisk.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A1F2AA284ED00EF863D /* MountDisk.swift */; };
|
||||||
|
D5FB7A272AA284ED00EF863D /* Task+Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A202AA284ED00EF863D /* Task+Timeout.swift */; };
|
||||||
|
D5FB7A2A2AA2854100EF863D /* ALTLocalizedError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5DB145828F9DC1000A8F606 /* ALTLocalizedError.swift */; };
|
||||||
|
D5FB7A2B2AA2854400EF863D /* UserInfoValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5189C002A01BC6800F44625 /* UserInfoValue.swift */; };
|
||||||
|
D5FB7A2E2AA2859400EF863D /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = D5FB7A2D2AA2859400EF863D /* ArgumentParser */; };
|
||||||
|
D5FB7A312AA28A2900EF863D /* NSError+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6C336124197D700034FD24 /* NSError+AltStore.swift */; };
|
||||||
|
D5FB7A322AA28A4000EF863D /* ALTWrappedError.m in Sources */ = {isa = PBXBuildFile; fileRef = D51AD27D29356B7B00967AAA /* ALTWrappedError.m */; };
|
||||||
|
D5FB7A392AA28D8300EF863D /* NSError+ALTServerError.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314922A060F400370A3C /* NSError+ALTServerError.m */; };
|
||||||
|
D5FB7A472AA293D000EF863D /* ALTErrorKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = D5FB7A462AA293D000EF863D /* ALTErrorKeys.m */; };
|
||||||
D5FD4EC52A952EAD0097BEE8 /* AltWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4EC42A952EAD0097BEE8 /* AltWidgetBundle.swift */; };
|
D5FD4EC52A952EAD0097BEE8 /* AltWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4EC42A952EAD0097BEE8 /* AltWidgetBundle.swift */; };
|
||||||
D5FD4EC92A9530C00097BEE8 /* AppSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4EC82A9530C00097BEE8 /* AppSnapshot.swift */; };
|
D5FD4EC92A9530C00097BEE8 /* AppSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4EC82A9530C00097BEE8 /* AppSnapshot.swift */; };
|
||||||
D5FD4ECB2A9532960097BEE8 /* DatabaseManager+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4ECA2A9532960097BEE8 /* DatabaseManager+Async.swift */; };
|
D5FD4ECB2A9532960097BEE8 /* DatabaseManager+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5FD4ECA2A9532960097BEE8 /* DatabaseManager+Async.swift */; };
|
||||||
@@ -546,6 +569,13 @@
|
|||||||
remoteGlobalIDString = BF66EE7D2501AE50007EE018;
|
remoteGlobalIDString = BF66EE7D2501AE50007EE018;
|
||||||
remoteInfo = AltStoreCore;
|
remoteInfo = AltStoreCore;
|
||||||
};
|
};
|
||||||
|
D537C8562AA94D4A009A1E08 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = BFD247622284B9A500981D42 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = D5FB7A122AA284BE00EF863D;
|
||||||
|
remoteInfo = AltJIT;
|
||||||
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@@ -572,6 +602,28 @@
|
|||||||
name = "Embed Foundation Extensions";
|
name = "Embed Foundation Extensions";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
BFF7C910257844C900E55F36 /* Embed XPC Services */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices";
|
||||||
|
dstSubfolderSpec = 16;
|
||||||
|
files = (
|
||||||
|
BFF7C90F257844C900E55F36 /* AltXPC.xpc in Embed XPC Services */,
|
||||||
|
);
|
||||||
|
name = "Embed XPC Services";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D52DD3602AAA89A700A7F2B6 /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
D52DD35F2AAA89A700A7F2B6 /* AltSign-Dynamic in Embed Frameworks */,
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
D561B2EC28EF5A4F006752E4 /* Embed Frameworks */ = {
|
D561B2EC28EF5A4F006752E4 /* Embed Frameworks */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -583,6 +635,15 @@
|
|||||||
name = "Embed Frameworks";
|
name = "Embed Frameworks";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
D5FB7A112AA284BE00EF863D /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -935,6 +996,7 @@
|
|||||||
D533E8B82727B61400A9B5DD /* fragmentzip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fragmentzip.h; sourceTree = "<group>"; };
|
D533E8B82727B61400A9B5DD /* fragmentzip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fragmentzip.h; sourceTree = "<group>"; };
|
||||||
D533E8BB2727BBEE00A9B5DD /* libfragmentzip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfragmentzip.a; path = Dependencies/fragmentzip/libfragmentzip.a; sourceTree = SOURCE_ROOT; };
|
D533E8BB2727BBEE00A9B5DD /* libfragmentzip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfragmentzip.a; path = Dependencies/fragmentzip/libfragmentzip.a; sourceTree = SOURCE_ROOT; };
|
||||||
D533E8BD2727BBF800A9B5DD /* libcurl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcurl.a; path = Dependencies/libcurl/libcurl.a; sourceTree = SOURCE_ROOT; };
|
D533E8BD2727BBF800A9B5DD /* libcurl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcurl.a; path = Dependencies/libcurl/libcurl.a; sourceTree = SOURCE_ROOT; };
|
||||||
|
D537C85A2AA95066009A1E08 /* libcorecrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcorecrypto.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/lib/system/libcorecrypto.tbd; sourceTree = DEVELOPER_DIR; };
|
||||||
D53D84012A2158FC00543C3B /* Permissions.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Permissions.plist; sourceTree = "<group>"; };
|
D53D84012A2158FC00543C3B /* Permissions.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Permissions.plist; sourceTree = "<group>"; };
|
||||||
D54058B82A1D6269008CCC58 /* AppPermissionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPermissionProtocol.swift; sourceTree = "<group>"; };
|
D54058B82A1D6269008CCC58 /* AppPermissionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPermissionProtocol.swift; sourceTree = "<group>"; };
|
||||||
D54058BA2A1D8FE3008CCC58 /* UIColor+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+AltStore.swift"; sourceTree = "<group>"; };
|
D54058BA2A1D8FE3008CCC58 /* UIColor+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+AltStore.swift"; sourceTree = "<group>"; };
|
||||||
@@ -970,7 +1032,13 @@
|
|||||||
D5935AEC29C39DE300C157EF /* SourceDetailsComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceDetailsComponents.swift; sourceTree = "<group>"; };
|
D5935AEC29C39DE300C157EF /* SourceDetailsComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceDetailsComponents.swift; sourceTree = "<group>"; };
|
||||||
D5935AEE29C3B23600C157EF /* Sources.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Sources.storyboard; sourceTree = "<group>"; };
|
D5935AEE29C3B23600C157EF /* Sources.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Sources.storyboard; sourceTree = "<group>"; };
|
||||||
D593F1932717749A006E82DE /* PatchAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchAppOperation.swift; sourceTree = "<group>"; };
|
D593F1932717749A006E82DE /* PatchAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchAppOperation.swift; sourceTree = "<group>"; };
|
||||||
|
D59A6B7A2AA91B8E00F61259 /* PythonCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PythonCommand.swift; sourceTree = "<group>"; };
|
||||||
|
D59A6B7D2AA9226C00F61259 /* AppProcess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppProcess.swift; sourceTree = "<group>"; };
|
||||||
|
D59A6B802AA92D1C00F61259 /* Process+Conveniences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Process+Conveniences.swift"; sourceTree = "<group>"; };
|
||||||
D5A0537229B91DB400997551 /* SourceDetailContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceDetailContentViewController.swift; sourceTree = "<group>"; };
|
D5A0537229B91DB400997551 /* SourceDetailContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceDetailContentViewController.swift; sourceTree = "<group>"; };
|
||||||
|
D5A1D2E32AA50EB60066CACC /* JITError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JITError.swift; sourceTree = "<group>"; };
|
||||||
|
D5A1D2E82AA512940066CACC /* RemoteServiceDiscoveryTunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteServiceDiscoveryTunnel.swift; sourceTree = "<group>"; };
|
||||||
|
D5A1D2EA2AA513410066CACC /* URL+Tools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Tools.swift"; sourceTree = "<group>"; };
|
||||||
D5A2193329B14F94002229FC /* DeprecatedAPIs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeprecatedAPIs.swift; sourceTree = "<group>"; };
|
D5A2193329B14F94002229FC /* DeprecatedAPIs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeprecatedAPIs.swift; sourceTree = "<group>"; };
|
||||||
D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearAppCacheOperation.swift; sourceTree = "<group>"; };
|
D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearAppCacheOperation.swift; sourceTree = "<group>"; };
|
||||||
D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = "<group>"; };
|
D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = "<group>"; };
|
||||||
@@ -991,6 +1059,16 @@
|
|||||||
D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore10ToAltStore11.xcmappingmodel; sourceTree = "<group>"; };
|
D5F99A1728D11DB500476A16 /* AltStore10ToAltStore11.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore10ToAltStore11.xcmappingmodel; sourceTree = "<group>"; };
|
||||||
D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreApp10ToStoreApp11Policy.swift; sourceTree = "<group>"; };
|
D5F99A1928D12B1400476A16 /* StoreApp10ToStoreApp11Policy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreApp10ToStoreApp11Policy.swift; sourceTree = "<group>"; };
|
||||||
D5FB7A0D2AA25A4E00EF863D /* Previews.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Previews.xcassets; sourceTree = "<group>"; };
|
D5FB7A0D2AA25A4E00EF863D /* Previews.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Previews.xcassets; sourceTree = "<group>"; };
|
||||||
|
D5FB7A132AA284BE00EF863D /* altjit */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = altjit; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
D5FB7A1A2AA284ED00EF863D /* EnableJIT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnableJIT.swift; path = AltJIT/Commands/EnableJIT.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A1B2AA284ED00EF863D /* ProcessError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProcessError.swift; path = Shared/Errors/ProcessError.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A1D2AA284ED00EF863D /* Logger+AltJIT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Logger+AltJIT.swift"; path = "AltJIT/Extensions/Logger+AltJIT.swift"; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A1E2AA284ED00EF863D /* AltJIT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AltJIT.swift; path = AltJIT/AltJIT.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A1F2AA284ED00EF863D /* MountDisk.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MountDisk.swift; path = AltJIT/Commands/MountDisk.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A202AA284ED00EF863D /* Task+Timeout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Task+Timeout.swift"; path = "AltJIT/Extensions/Task+Timeout.swift"; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A382AA28AC700EF863D /* AltJIT-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "AltJIT-Bridging-Header.h"; path = "AltJIT/AltJIT-Bridging-Header.h"; sourceTree = SOURCE_ROOT; };
|
||||||
|
D5FB7A452AA293D000EF863D /* ALTErrorKeys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTErrorKeys.h; sourceTree = "<group>"; };
|
||||||
|
D5FB7A462AA293D000EF863D /* ALTErrorKeys.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ALTErrorKeys.m; sourceTree = "<group>"; };
|
||||||
D5FD4EC42A952EAD0097BEE8 /* AltWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltWidgetBundle.swift; sourceTree = "<group>"; };
|
D5FD4EC42A952EAD0097BEE8 /* AltWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltWidgetBundle.swift; sourceTree = "<group>"; };
|
||||||
D5FD4EC82A9530C00097BEE8 /* AppSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSnapshot.swift; sourceTree = "<group>"; };
|
D5FD4EC82A9530C00097BEE8 /* AppSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSnapshot.swift; sourceTree = "<group>"; };
|
||||||
D5FD4ECA2A9532960097BEE8 /* DatabaseManager+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DatabaseManager+Async.swift"; sourceTree = "<group>"; };
|
D5FD4ECA2A9532960097BEE8 /* DatabaseManager+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DatabaseManager+Async.swift"; sourceTree = "<group>"; };
|
||||||
@@ -1087,6 +1165,16 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
D5FB7A102AA284BE00EF863D /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D52DD35E2AAA89A600A7F2B6 /* AltSign-Dynamic in Frameworks */,
|
||||||
|
D537C85B2AA9507A009A1E08 /* libcorecrypto.tbd in Frameworks */,
|
||||||
|
D5FB7A2E2AA2859400EF863D /* ArgumentParser in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@@ -1249,6 +1337,7 @@
|
|||||||
0EE7FDBF2BE8BBBF00D1E390 /* Errors */,
|
0EE7FDBF2BE8BBBF00D1E390 /* Errors */,
|
||||||
BFF767C32489A6800097E58C /* Extensions */,
|
BFF767C32489A6800097E58C /* Extensions */,
|
||||||
BFF767C42489A6980097E58C /* Categories */,
|
BFF767C42489A6980097E58C /* Categories */,
|
||||||
|
D59A6B7C2AA9225C00F61259 /* Types */,
|
||||||
);
|
);
|
||||||
path = Shared;
|
path = Shared;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1722,6 +1811,9 @@
|
|||||||
19104DB32909C06D00C49C7B /* EmotionalDamage */,
|
19104DB32909C06D00C49C7B /* EmotionalDamage */,
|
||||||
191E5FAC290A5D92001A3B7C /* minimuxer */,
|
191E5FAC290A5D92001A3B7C /* minimuxer */,
|
||||||
B343F886295F7F9B002B1159 /* libfragmentzip.xcodeproj */,
|
B343F886295F7F9B002B1159 /* libfragmentzip.xcodeproj */,
|
||||||
|
BFF7C905257844C900E55F36 /* AltXPC */,
|
||||||
|
D5FB7A142AA284BE00EF863D /* AltJIT */,
|
||||||
|
D586D39928EF58B0000E101F /* AltTests */,
|
||||||
BFD247852284BB3300981D42 /* Frameworks */,
|
BFD247852284BB3300981D42 /* Frameworks */,
|
||||||
B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */,
|
B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */,
|
||||||
BFD2476B2284B9A500981D42 /* Products */,
|
BFD2476B2284B9A500981D42 /* Products */,
|
||||||
@@ -1740,6 +1832,9 @@
|
|||||||
BF989167250AABF3002ACF50 /* AltWidgetExtension.appex */,
|
BF989167250AABF3002ACF50 /* AltWidgetExtension.appex */,
|
||||||
19104DB22909C06C00C49C7B /* libEmotionalDamage.a */,
|
19104DB22909C06C00C49C7B /* libEmotionalDamage.a */,
|
||||||
191E5FAB290A5D92001A3B7C /* libminimuxer.a */,
|
191E5FAB290A5D92001A3B7C /* libminimuxer.a */,
|
||||||
|
BFF7C904257844C900E55F36 /* AltXPC.xpc */,
|
||||||
|
D586D39828EF58B0000E101F /* AltTests.xctest */,
|
||||||
|
D5FB7A132AA284BE00EF863D /* altjit */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1782,6 +1877,7 @@
|
|||||||
children = (
|
children = (
|
||||||
B343F86C295F759E002B1159 /* libresolv.tbd */,
|
B343F86C295F759E002B1159 /* libresolv.tbd */,
|
||||||
B39575F4284F29E20080B4FF /* Roxas.framework */,
|
B39575F4284F29E20080B4FF /* Roxas.framework */,
|
||||||
|
D537C85A2AA95066009A1E08 /* libcorecrypto.tbd */,
|
||||||
D533E8B62727841800A9B5DD /* libAppleArchive.tbd */,
|
D533E8B62727841800A9B5DD /* libAppleArchive.tbd */,
|
||||||
BF580497246A3D19008AE704 /* UIKit.framework */,
|
BF580497246A3D19008AE704 /* UIKit.framework */,
|
||||||
BF4588872298DD3F00BD7491 /* libxml2.tbd */,
|
BF4588872298DD3F00BD7491 /* libxml2.tbd */,
|
||||||
@@ -1940,6 +2036,7 @@
|
|||||||
BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */,
|
BFF435D7255CBDAB00DD724F /* ALTApplication+AltStoreApp.swift */,
|
||||||
BF6C336124197D700034FD24 /* NSError+AltStore.swift */,
|
BF6C336124197D700034FD24 /* NSError+AltStore.swift */,
|
||||||
D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */,
|
D5708416292448DA00D42D34 /* OperatingSystemVersion+Comparable.swift */,
|
||||||
|
D59A6B802AA92D1C00F61259 /* Process+Conveniences.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2011,6 +2108,17 @@
|
|||||||
path = Model;
|
path = Model;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D522F9562AA509E9003E57D1 /* Types */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D5FB7A452AA293D000EF863D /* ALTErrorKeys.h */,
|
||||||
|
D5FB7A462AA293D000EF863D /* ALTErrorKeys.m */,
|
||||||
|
D5A1D2E82AA512940066CACC /* RemoteServiceDiscoveryTunnel.swift */,
|
||||||
|
D59A6B7A2AA91B8E00F61259 /* PythonCommand.swift */,
|
||||||
|
);
|
||||||
|
path = Types;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D54058B72A1D6251008CCC58 /* Previews */ = {
|
D54058B72A1D6251008CCC58 /* Previews */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2065,6 +2173,14 @@
|
|||||||
path = "Error Log";
|
path = "Error Log";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D59A6B7C2AA9225C00F61259 /* Types */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D59A6B7D2AA9226C00F61259 /* AppProcess.swift */,
|
||||||
|
);
|
||||||
|
path = Types;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D5DB145728F9DC0300A8F606 /* Errors */ = {
|
D5DB145728F9DC0300A8F606 /* Errors */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2072,10 +2188,43 @@
|
|||||||
D5189C002A01BC6800F44625 /* UserInfoValue.swift */,
|
D5189C002A01BC6800F44625 /* UserInfoValue.swift */,
|
||||||
D51AD27C29356B7B00967AAA /* ALTWrappedError.h */,
|
D51AD27C29356B7B00967AAA /* ALTWrappedError.h */,
|
||||||
D51AD27D29356B7B00967AAA /* ALTWrappedError.m */,
|
D51AD27D29356B7B00967AAA /* ALTWrappedError.m */,
|
||||||
|
D5FB7A1B2AA284ED00EF863D /* ProcessError.swift */,
|
||||||
|
D5A1D2E32AA50EB60066CACC /* JITError.swift */,
|
||||||
);
|
);
|
||||||
path = Errors;
|
path = Errors;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D5FB7A142AA284BE00EF863D /* AltJIT */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D5FB7A1E2AA284ED00EF863D /* AltJIT.swift */,
|
||||||
|
D5FB7A382AA28AC700EF863D /* AltJIT-Bridging-Header.h */,
|
||||||
|
D5FB7A282AA2851200EF863D /* Commands */,
|
||||||
|
D522F9562AA509E9003E57D1 /* Types */,
|
||||||
|
D5FB7A292AA2851C00EF863D /* Extensions */,
|
||||||
|
);
|
||||||
|
path = AltJIT;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D5FB7A282AA2851200EF863D /* Commands */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D5FB7A1A2AA284ED00EF863D /* EnableJIT.swift */,
|
||||||
|
D5FB7A1F2AA284ED00EF863D /* MountDisk.swift */,
|
||||||
|
);
|
||||||
|
path = Commands;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D5FB7A292AA2851C00EF863D /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D5FB7A1D2AA284ED00EF863D /* Logger+AltJIT.swift */,
|
||||||
|
D5A1D2EA2AA513410066CACC /* URL+Tools.swift */,
|
||||||
|
D5FB7A202AA284ED00EF863D /* Task+Timeout.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
@@ -2298,6 +2447,28 @@
|
|||||||
productReference = BFD2476A2284B9A500981D42 /* SideStore.app */;
|
productReference = BFD2476A2284B9A500981D42 /* SideStore.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
D5FB7A122AA284BE00EF863D /* AltJIT */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = D5FB7A172AA284BE00EF863D /* Build configuration list for PBXNativeTarget "AltJIT" */;
|
||||||
|
buildPhases = (
|
||||||
|
D5FB7A0F2AA284BE00EF863D /* Sources */,
|
||||||
|
D5FB7A102AA284BE00EF863D /* Frameworks */,
|
||||||
|
D5FB7A112AA284BE00EF863D /* CopyFiles */,
|
||||||
|
D52DD3602AAA89A700A7F2B6 /* Embed Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = AltJIT;
|
||||||
|
packageProductDependencies = (
|
||||||
|
D5FB7A2D2AA2859400EF863D /* ArgumentParser */,
|
||||||
|
D52DD35D2AAA89A600A7F2B6 /* AltSign-Dynamic */,
|
||||||
|
);
|
||||||
|
productName = AltJIT;
|
||||||
|
productReference = D5FB7A132AA284BE00EF863D /* altjit */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
@@ -2343,6 +2514,17 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
BFF7C903257844C900E55F36 = {
|
||||||
|
CreatedOnToolsVersion = 12.3;
|
||||||
|
LastSwiftMigration = 1230;
|
||||||
|
};
|
||||||
|
D586D39728EF58B0000E101F = {
|
||||||
|
CreatedOnToolsVersion = 14.0.1;
|
||||||
|
TestTargetID = BFD247692284B9A500981D42;
|
||||||
|
};
|
||||||
|
D5FB7A122AA284BE00EF863D = {
|
||||||
|
CreatedOnToolsVersion = 15.0;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = BFD247652284B9A500981D42 /* Build configuration list for PBXProject "AltStore" */;
|
buildConfigurationList = BFD247652284B9A500981D42 /* Build configuration list for PBXProject "AltStore" */;
|
||||||
@@ -2365,6 +2547,7 @@
|
|||||||
4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */,
|
4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */,
|
||||||
99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */,
|
99C4EF472978D52400CB538D /* XCRemoteSwiftPackageReference "SemanticVersion" */,
|
||||||
9922FFEA29B501C50020F868 /* XCRemoteSwiftPackageReference "Starscream" */,
|
9922FFEA29B501C50020F868 /* XCRemoteSwiftPackageReference "Starscream" */,
|
||||||
|
D5FB7A2C2AA2859400EF863D /* XCRemoteSwiftPackageReference "swift-argument-parser" */,
|
||||||
);
|
);
|
||||||
productRefGroup = BFD2476B2284B9A500981D42 /* Products */;
|
productRefGroup = BFD2476B2284B9A500981D42 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@@ -2396,6 +2579,9 @@
|
|||||||
BF989166250AABF3002ACF50 /* AltWidgetExtension */,
|
BF989166250AABF3002ACF50 /* AltWidgetExtension */,
|
||||||
19104DB12909C06C00C49C7B /* EmotionalDamage */,
|
19104DB12909C06C00C49C7B /* EmotionalDamage */,
|
||||||
191E5FAA290A5D92001A3B7C /* minimuxer */,
|
191E5FAA290A5D92001A3B7C /* minimuxer */,
|
||||||
|
BFF7C903257844C900E55F36 /* AltXPC */,
|
||||||
|
D5FB7A122AA284BE00EF863D /* AltJIT */,
|
||||||
|
D586D39728EF58B0000E101F /* AltTests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@@ -2948,6 +3134,51 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
BFF7C900257844C900E55F36 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
BFF7C9342578492100E55F36 /* ALTAnisetteData.m in Sources */,
|
||||||
|
BFF7C920257844FA00E55F36 /* ALTPluginService.m in Sources */,
|
||||||
|
BF77A67E25795BBE00BFE477 /* main.swift in Sources */,
|
||||||
|
BF77A67025795A5600BFE477 /* AltXPC.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D586D39428EF58B0000E101F /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D586D39B28EF58B0000E101F /* AltTests.swift in Sources */,
|
||||||
|
D5F5AF2E28FDD2EC00C938F5 /* TestErrors.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
D5FB7A0F2AA284BE00EF863D /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D5A1D2EB2AA513410066CACC /* URL+Tools.swift in Sources */,
|
||||||
|
D5FB7A212AA284ED00EF863D /* EnableJIT.swift in Sources */,
|
||||||
|
D5FB7A312AA28A2900EF863D /* NSError+AltStore.swift in Sources */,
|
||||||
|
D59A6B7B2AA91B8E00F61259 /* PythonCommand.swift in Sources */,
|
||||||
|
D5A1D2EC2AA51D490066CACC /* ProcessError.swift in Sources */,
|
||||||
|
D5FB7A262AA284ED00EF863D /* MountDisk.swift in Sources */,
|
||||||
|
D5FB7A392AA28D8300EF863D /* NSError+ALTServerError.m in Sources */,
|
||||||
|
D5FB7A472AA293D000EF863D /* ALTErrorKeys.m in Sources */,
|
||||||
|
D59A6B7F2AA9226C00F61259 /* AppProcess.swift in Sources */,
|
||||||
|
D5FB7A272AA284ED00EF863D /* Task+Timeout.swift in Sources */,
|
||||||
|
D59A6B822AA92D1C00F61259 /* Process+Conveniences.swift in Sources */,
|
||||||
|
D5FB7A2A2AA2854100EF863D /* ALTLocalizedError.swift in Sources */,
|
||||||
|
D5A1D2E92AA512940066CACC /* RemoteServiceDiscoveryTunnel.swift in Sources */,
|
||||||
|
D5FB7A2B2AA2854400EF863D /* UserInfoValue.swift in Sources */,
|
||||||
|
D5FB7A242AA284ED00EF863D /* Logger+AltJIT.swift in Sources */,
|
||||||
|
D5A1D2E42AA50EB60066CACC /* JITError.swift in Sources */,
|
||||||
|
D5FB7A252AA284ED00EF863D /* AltJIT.swift in Sources */,
|
||||||
|
D5FB7A322AA28A4000EF863D /* ALTWrappedError.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
@@ -3740,6 +3971,80 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
D5FB7A182AA284BE00EF863D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_TEAM = 6XVY5G3U44;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
"ALTJIT=1",
|
||||||
|
);
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(SDKROOT)/usr/lib/system",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
OTHER_SWIFT_FLAGS = "";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltJIT;
|
||||||
|
PRODUCT_NAME = altjit;
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = NO;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "AltJIT/AltJIT-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
D5FB7A192AA284BE00EF863D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
|
||||||
|
DEVELOPMENT_TEAM = 6XVY5G3U44;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"ALTJIT=1",
|
||||||
|
);
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(SDKROOT)/usr/lib/system",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
OTHER_SWIFT_FLAGS = "";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.AltJIT;
|
||||||
|
PRODUCT_NAME = altjit;
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = NO;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "AltJIT/AltJIT-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
@@ -3824,6 +4129,15 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
D5FB7A172AA284BE00EF863D /* Build configuration list for PBXNativeTarget "AltJIT" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
D5FB7A182AA284BE00EF863D /* Debug */,
|
||||||
|
D5FB7A192AA284BE00EF863D /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
@@ -3907,6 +4221,14 @@
|
|||||||
minimumVersion = 4.1.0;
|
minimumVersion = 4.1.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
D5FB7A2C2AA2859400EF863D /* XCRemoteSwiftPackageReference "swift-argument-parser" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/apple/swift-argument-parser.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMinorVersion;
|
||||||
|
minimumVersion = 1.2.3;
|
||||||
|
};
|
||||||
|
};
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
@@ -3925,7 +4247,11 @@
|
|||||||
package = 4879A95D2861046500FC1BBD /* XCRemoteSwiftPackageReference "AltSign" */;
|
package = 4879A95D2861046500FC1BBD /* XCRemoteSwiftPackageReference "AltSign" */;
|
||||||
productName = AltSign;
|
productName = AltSign;
|
||||||
};
|
};
|
||||||
4879A9612861049C00FC1BBD /* OpenSSL */ = {
|
D52DD35D2AAA89A600A7F2B6 /* AltSign-Dynamic */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = "AltSign-Dynamic";
|
||||||
|
};
|
||||||
|
D561B2EA28EF5A4F006752E4 /* AltSign-Dynamic */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */;
|
package = 4879A9602861049C00FC1BBD /* XCRemoteSwiftPackageReference "OpenSSL" */;
|
||||||
productName = OpenSSL;
|
productName = OpenSSL;
|
||||||
@@ -3965,6 +4291,11 @@
|
|||||||
package = B3C395F5284F362400DA9E2F /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */;
|
package = B3C395F5284F362400DA9E2F /* XCRemoteSwiftPackageReference "appcenter-sdk-apple" */;
|
||||||
productName = AppCenterCrashes;
|
productName = AppCenterCrashes;
|
||||||
};
|
};
|
||||||
|
D5FB7A2D2AA2859400EF863D /* ArgumentParser */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = D5FB7A2C2AA2859400EF863D /* XCRemoteSwiftPackageReference "swift-argument-parser" */;
|
||||||
|
productName = ArgumentParser;
|
||||||
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
|
|||||||
101
AltStore.xcodeproj/xcshareddata/xcschemes/AltJIT.xcscheme
Normal file
101
AltStore.xcodeproj/xcshareddata/xcschemes/AltJIT.xcscheme
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1500"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "D5FB7A122AA284BE00EF863D"
|
||||||
|
BuildableName = "altjit"
|
||||||
|
BlueprintName = "AltJIT"
|
||||||
|
ReferencedContainer = "container:AltStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
debugAsWhichUser = "root"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES"
|
||||||
|
viewDebuggingEnabled = "No">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "D5FB7A122AA284BE00EF863D"
|
||||||
|
BuildableName = "altjit"
|
||||||
|
BlueprintName = "AltJIT"
|
||||||
|
ReferencedContainer = "container:AltStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
<CommandLineArguments>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "enable"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "mount"
|
||||||
|
isEnabled = "NO">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "DolphiniOS"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "--udid"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
<CommandLineArgument
|
||||||
|
argument = "00008030-001948590202802E"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</CommandLineArgument>
|
||||||
|
</CommandLineArguments>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "D5FB7A122AA284BE00EF863D"
|
||||||
|
BuildableName = "altjit"
|
||||||
|
BlueprintName = "AltJIT"
|
||||||
|
ReferencedContainer = "container:AltStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
@@ -14,7 +14,16 @@
|
|||||||
#import "AltStoreCore/AltStoreCore-Swift.h"
|
#import "AltStoreCore/AltStoreCore-Swift.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ALTJIT
|
||||||
|
#import "AltJIT-Swift.h"
|
||||||
@import AltSign;
|
@import AltSign;
|
||||||
|
#elif TARGET_OS_OSX
|
||||||
|
#import "AltServer-Swift.h"
|
||||||
|
@import AltSign;
|
||||||
|
#elif !TARGET_OS_OSX
|
||||||
|
#import <AltStoreCore/AltStoreCore-Swift.h>
|
||||||
|
@import AltSign;
|
||||||
|
#endif
|
||||||
|
|
||||||
NSErrorDomain const AltServerErrorDomain = @"AltServer.ServerError";
|
NSErrorDomain const AltServerErrorDomain = @"AltServer.ServerError";
|
||||||
NSErrorDomain const AltServerInstallationErrorDomain = @"AltServer.InstallationError";
|
NSErrorDomain const AltServerInstallationErrorDomain = @"AltServer.InstallationError";
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
#if !ALTJIT
|
||||||
import AltSign
|
import AltSign
|
||||||
|
#endif
|
||||||
|
|
||||||
public let ALTLocalizedTitleErrorKey = "ALTLocalizedTitle"
|
public let ALTLocalizedTitleErrorKey = "ALTLocalizedTitle"
|
||||||
public let ALTLocalizedDescriptionKey = "ALTLocalizedDescription"
|
public let ALTLocalizedDescriptionKey = "ALTLocalizedDescription"
|
||||||
|
|||||||
52
Shared/Errors/JITError.swift
Normal file
52
Shared/Errors/JITError.swift
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// JITError.swift
|
||||||
|
// AltJIT
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/3/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension JITError
|
||||||
|
{
|
||||||
|
enum Code: Int, ALTErrorCode
|
||||||
|
{
|
||||||
|
typealias Error = JITError
|
||||||
|
|
||||||
|
case processNotRunning
|
||||||
|
}
|
||||||
|
|
||||||
|
static func processNotRunning(_ process: AppProcess, file: StaticString = #file, line: Int = #line) -> JITError {
|
||||||
|
JITError(code: .processNotRunning, process: process, sourceFile: file, sourceLine: UInt(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JITError: ALTLocalizedError
|
||||||
|
{
|
||||||
|
let code: Code
|
||||||
|
|
||||||
|
var errorTitle: String?
|
||||||
|
var errorFailure: String?
|
||||||
|
|
||||||
|
@UserInfoValue var process: AppProcess?
|
||||||
|
|
||||||
|
var sourceFile: StaticString?
|
||||||
|
var sourceLine: UInt?
|
||||||
|
|
||||||
|
var errorFailureReason: String {
|
||||||
|
switch self.code
|
||||||
|
{
|
||||||
|
case .processNotRunning:
|
||||||
|
let targetName = self.process?.description ?? NSLocalizedString("The target app", comment: "")
|
||||||
|
return String(format: NSLocalizedString("%@ is not running.", comment: ""), targetName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var recoverySuggestion: String? {
|
||||||
|
switch self.code
|
||||||
|
{
|
||||||
|
case .processNotRunning: return NSLocalizedString("Make sure the app is running in the foreground on your device then try again.", comment: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
Shared/Errors/ProcessError.swift
Normal file
88
Shared/Errors/ProcessError.swift
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
//
|
||||||
|
// ProcessError.swift
|
||||||
|
// AltPackage
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/1/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension ProcessError
|
||||||
|
{
|
||||||
|
enum Code: Int, ALTErrorCode
|
||||||
|
{
|
||||||
|
typealias Error = ProcessError
|
||||||
|
|
||||||
|
case failed
|
||||||
|
case timedOut
|
||||||
|
case unexpectedOutput
|
||||||
|
case terminated
|
||||||
|
}
|
||||||
|
|
||||||
|
static func failed(executableURL: URL, exitCode: Int32, output: String?, file: StaticString = #file, line: Int = #line) -> ProcessError {
|
||||||
|
ProcessError(code: .failed, executableURL: executableURL, exitCode: exitCode, output: output, sourceFile: file, sourceLine: UInt(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func timedOut(executableURL: URL, exitCode: Int32? = nil, output: String? = nil, file: StaticString = #file, line: Int = #line) -> ProcessError {
|
||||||
|
ProcessError(code: .timedOut, executableURL: executableURL, exitCode: exitCode, output: output, sourceFile: file, sourceLine: UInt(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func unexpectedOutput(executableURL: URL, output: String, exitCode: Int32? = nil, file: StaticString = #file, line: Int = #line) -> ProcessError {
|
||||||
|
ProcessError(code: .unexpectedOutput, executableURL: executableURL, exitCode: exitCode, output: output, sourceFile: file, sourceLine: UInt(line))
|
||||||
|
}
|
||||||
|
|
||||||
|
static func terminated(executableURL: URL, exitCode: Int32, output: String, file: StaticString = #file, line: Int = #line) -> ProcessError {
|
||||||
|
ProcessError(code: .terminated, executableURL: executableURL, exitCode: exitCode, output: output, sourceFile: file, sourceLine: UInt(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProcessError: ALTLocalizedError
|
||||||
|
{
|
||||||
|
let code: Code
|
||||||
|
|
||||||
|
var errorTitle: String?
|
||||||
|
var errorFailure: String?
|
||||||
|
|
||||||
|
@UserInfoValue var executableURL: URL?
|
||||||
|
@UserInfoValue var exitCode: Int32?
|
||||||
|
@UserInfoValue var output: String?
|
||||||
|
|
||||||
|
var sourceFile: StaticString?
|
||||||
|
var sourceLine: UInt?
|
||||||
|
|
||||||
|
var errorFailureReason: String {
|
||||||
|
switch self.code
|
||||||
|
{
|
||||||
|
case .failed:
|
||||||
|
guard let exitCode else { return String(format: NSLocalizedString("%@ failed.", comment: ""), self.processName) }
|
||||||
|
|
||||||
|
let baseMessage = String(format: NSLocalizedString("%@ failed with code %@.", comment: ""), self.processName, NSNumber(value: exitCode))
|
||||||
|
guard let lastLine = self.lastOutputLine else { return baseMessage }
|
||||||
|
|
||||||
|
let failureReason = baseMessage + " " + lastLine
|
||||||
|
return failureReason
|
||||||
|
|
||||||
|
case .timedOut: return String(format: NSLocalizedString("%@ timed out.", comment: ""), self.processName)
|
||||||
|
case .terminated: return String(format: NSLocalizedString("%@ unexpectedly quit.", comment: ""), self.processName)
|
||||||
|
case .unexpectedOutput:
|
||||||
|
let baseMessage = String(format: NSLocalizedString("%@ returned unexpected output.", comment: ""), self.processName)
|
||||||
|
guard let lastLine = self.lastOutputLine else { return baseMessage }
|
||||||
|
|
||||||
|
let failureReason = baseMessage + " " + lastLine
|
||||||
|
return failureReason
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var processName: String {
|
||||||
|
guard let executableName = self.executableURL?.lastPathComponent else { return NSLocalizedString("The process", comment: "") }
|
||||||
|
return String(format: NSLocalizedString("The process '%@'", comment: ""), executableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var lastOutputLine: String? {
|
||||||
|
guard let output else { return nil }
|
||||||
|
|
||||||
|
let lastLine = output.components(separatedBy: .newlines).last(where: { !$0.isEmpty })
|
||||||
|
return lastLine
|
||||||
|
}
|
||||||
|
}
|
||||||
151
Shared/Extensions/Process+Conveniences.swift
Normal file
151
Shared/Extensions/Process+Conveniences.swift
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
//
|
||||||
|
// Process+Conveniences.swift
|
||||||
|
// AltStore
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/6/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import OSLog
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
extension Process
|
||||||
|
{
|
||||||
|
// Based loosely off of https://developer.apple.com/forums/thread/690310
|
||||||
|
class func launch(_ toolURL: URL, arguments: [String] = [], environment: [String: String] = ProcessInfo.processInfo.environment) throws -> Process
|
||||||
|
{
|
||||||
|
let inputPipe = Pipe()
|
||||||
|
let outputPipe = Pipe()
|
||||||
|
|
||||||
|
let process = Process()
|
||||||
|
process.executableURL = toolURL
|
||||||
|
process.arguments = arguments
|
||||||
|
process.environment = environment
|
||||||
|
process.standardInput = inputPipe
|
||||||
|
process.standardOutput = outputPipe
|
||||||
|
process.standardError = outputPipe
|
||||||
|
|
||||||
|
func posixErr(_ error: Int32) -> Error { NSError(domain: NSPOSIXErrorDomain, code: Int(error), userInfo: nil) }
|
||||||
|
|
||||||
|
// If you write to a pipe whose remote end has closed, the OS raises a
|
||||||
|
// `SIGPIPE` signal whose default disposition is to terminate your
|
||||||
|
// process. Helpful! `F_SETNOSIGPIPE` disables that feature, causing
|
||||||
|
// the write to fail with `EPIPE` instead.
|
||||||
|
|
||||||
|
let fcntlResult = fcntl(inputPipe.fileHandleForWriting.fileDescriptor, F_SETNOSIGPIPE, 1)
|
||||||
|
guard fcntlResult >= 0 else { throw posixErr(errno) }
|
||||||
|
|
||||||
|
// Actually run the process.
|
||||||
|
try process.run()
|
||||||
|
|
||||||
|
let outputTask = Task {
|
||||||
|
do
|
||||||
|
{
|
||||||
|
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: toolURL.lastPathComponent)
|
||||||
|
|
||||||
|
// Automatically cancels when fileHandle closes.
|
||||||
|
for try await line in outputPipe.fileHandleForReading.bytes.lines
|
||||||
|
{
|
||||||
|
process.output += line + "\n"
|
||||||
|
process.outputPublisher.send(line)
|
||||||
|
|
||||||
|
logger.notice("\(line, privacy: .public)")
|
||||||
|
}
|
||||||
|
|
||||||
|
try Task.checkCancellation()
|
||||||
|
process.outputPublisher.send(completion: .finished)
|
||||||
|
}
|
||||||
|
catch let error as CancellationError
|
||||||
|
{
|
||||||
|
process.outputPublisher.send(completion: .failure(error))
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.main.error("Failed to read process output. \(error.localizedDescription, privacy: .public)")
|
||||||
|
|
||||||
|
try Task.checkCancellation()
|
||||||
|
process.outputPublisher.send(completion: .failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.terminationHandler = { process in
|
||||||
|
Logger.main.notice("Process \(toolURL, privacy: .public) terminated with exit code \(process.terminationStatus).")
|
||||||
|
|
||||||
|
outputTask.cancel()
|
||||||
|
process.outputPublisher.send(completion: .finished)
|
||||||
|
}
|
||||||
|
|
||||||
|
return process
|
||||||
|
}
|
||||||
|
|
||||||
|
class func launchAndWait(_ toolURL: URL, arguments: [String] = [], environment: [String: String] = ProcessInfo.processInfo.environment) async throws -> String
|
||||||
|
{
|
||||||
|
let process = try self.launch(toolURL, arguments: arguments, environment: environment)
|
||||||
|
|
||||||
|
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
||||||
|
let previousHandler = process.terminationHandler
|
||||||
|
process.terminationHandler = { process in
|
||||||
|
previousHandler?(process)
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard process.terminationStatus == 0 else {
|
||||||
|
throw ProcessError.failed(executableURL: toolURL, exitCode: process.terminationStatus, output: process.output)
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 12, *)
|
||||||
|
extension Process
|
||||||
|
{
|
||||||
|
private static var outputKey: Int = 0
|
||||||
|
private static var publisherKey: Int = 0
|
||||||
|
|
||||||
|
fileprivate(set) var output: String {
|
||||||
|
get {
|
||||||
|
let output = objc_getAssociatedObject(self, &Process.outputKey) as? String ?? ""
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
objc_setAssociatedObject(self, &Process.outputKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be type-erased, but oh well.
|
||||||
|
var outputLines: AsyncThrowingPublisher<some Publisher<String, Error>> {
|
||||||
|
return self.outputPublisher
|
||||||
|
.buffer(size: 100, prefetch: .byRequest, whenFull: .dropOldest)
|
||||||
|
.values
|
||||||
|
}
|
||||||
|
|
||||||
|
private var outputPublisher: PassthroughSubject<String, Error> {
|
||||||
|
if let publisher = objc_getAssociatedObject(self, &Process.publisherKey) as? PassthroughSubject<String, Error>
|
||||||
|
{
|
||||||
|
return publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
let publisher = PassthroughSubject<String, Error>()
|
||||||
|
objc_setAssociatedObject(self, &Process.publisherKey, publisher, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||||
|
return publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must manually close outputPipe in order for us to read a second Process' standardOutput via async-await 🤷♂️
|
||||||
|
func stopOutput()
|
||||||
|
{
|
||||||
|
guard let outputPipe = self.standardOutput as? Pipe else { return }
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try outputPipe.fileHandleForReading.close()
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.main.error("Failed to close \(self.executableURL?.lastPathComponent ?? "process", privacy: .public)'s standardOutput. \(error.localizedDescription, privacy: .public)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Shared/Types/AppProcess.swift
Normal file
35
Shared/Types/AppProcess.swift
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// AppProcess.swift
|
||||||
|
// AltStore
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/6/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum AppProcess: CustomStringConvertible
|
||||||
|
{
|
||||||
|
case name(String)
|
||||||
|
case pid(Int)
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self
|
||||||
|
{
|
||||||
|
case .name(let name): return name
|
||||||
|
case .pid(let pid): return "Process \(pid)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(_ value: String)
|
||||||
|
{
|
||||||
|
if let pid = Int(value)
|
||||||
|
{
|
||||||
|
self = .pid(pid)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self = .name(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user