mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[AltServer] Handles EnableUnsignedCodeExecutionRequest
Allows sideloaded apps to connect to AltServer and enable JIT execution.
This commit is contained in:
@@ -16,6 +16,7 @@ NS_SWIFT_NAME(DebugConnection)
|
||||
@property (nonatomic, copy, readonly) ALTDevice *device;
|
||||
|
||||
- (void)enableUnsignedCodeExecutionForProcessWithName:(NSString *)processName completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
||||
- (void)enableUnsignedCodeExecutionForProcessWithID:(NSInteger)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
||||
|
||||
- (void)disconnect;
|
||||
|
||||
|
||||
@@ -96,12 +96,36 @@ char *bin2hex(const unsigned char *bin, size_t length)
|
||||
}
|
||||
|
||||
- (void)enableUnsignedCodeExecutionForProcessWithName:(NSString *)processName completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler
|
||||
{
|
||||
[self _enableUnsignedCodeExecutionForProcessWithName:processName pid:0 completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)enableUnsignedCodeExecutionForProcessWithID:(NSInteger)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler
|
||||
{
|
||||
[self _enableUnsignedCodeExecutionForProcessWithName:nil pid:(int32_t)pid completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)_enableUnsignedCodeExecutionForProcessWithName:(nullable NSString *)processName pid:(int32_t)pid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler
|
||||
{
|
||||
dispatch_async(self.connectionQueue, ^{
|
||||
NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"JIT could not be enabled for %@.", comment: @""), processName];
|
||||
NSString *name = processName ?: NSLocalizedString(@"this app", @"");
|
||||
NSString *localizedFailure = [NSString stringWithFormat:NSLocalizedString(@"JIT could not be enabled for %@.", comment: @""), name];
|
||||
|
||||
NSString *encodedName = @(bin2hex((const unsigned char *)processName.UTF8String, (size_t)strlen(processName.UTF8String)));
|
||||
NSString *attachCommand = [NSString stringWithFormat:@"vAttachName;%@", encodedName];
|
||||
NSString *attachCommand = nil;
|
||||
|
||||
if (processName)
|
||||
{
|
||||
NSString *encodedName = @(bin2hex((const unsigned char *)processName.UTF8String, (size_t)strlen(processName.UTF8String)));
|
||||
attachCommand = [NSString stringWithFormat:@"vAttachName;%@", encodedName];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert to Big-endian.
|
||||
int32_t rawPID = CFSwapInt32HostToBig(pid);
|
||||
|
||||
NSString *encodedName = @(bin2hex((const unsigned char *)&rawPID, 4));
|
||||
attachCommand = [NSString stringWithFormat:@"vAttach;%@", encodedName];
|
||||
}
|
||||
|
||||
NSError *error = nil;
|
||||
if (![self sendCommand:attachCommand arguments:nil error:&error])
|
||||
|
||||
@@ -143,6 +143,37 @@ struct ServerRequestHandler: RequestHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleEnableUnsignedCodeExecutionRequest(_ request: EnableUnsignedCodeExecutionRequest, for connection: Connection, completionHandler: @escaping (Result<EnableUnsignedCodeExecutionResponse, Error>) -> Void)
|
||||
{
|
||||
guard let device = ALTDeviceManager.shared.availableDevices.first(where: { $0.identifier == request.udid }) else { return completionHandler(.failure(ALTServerError(.deviceNotFound))) }
|
||||
|
||||
ALTDeviceManager.shared.prepare(device) { result in
|
||||
switch result
|
||||
{
|
||||
case .failure(let error): completionHandler(.failure(error))
|
||||
case .success:
|
||||
ALTDeviceManager.shared.startDebugConnection(to: device) { (connection, error) in
|
||||
guard let connection = connection else { return completionHandler(.failure(error!)) }
|
||||
|
||||
connection.enableUnsignedCodeExecutionForProcess(withID: request.processID) { (success, error) in
|
||||
if let error = error, !success
|
||||
{
|
||||
print("Failed to enable unsigned code execution for process \(request.processID):", error)
|
||||
completionHandler(.failure(ALTServerError(error)))
|
||||
}
|
||||
else
|
||||
{
|
||||
print("Enabled unsigned code execution for process:", request.processID)
|
||||
|
||||
let response = EnableUnsignedCodeExecutionResponse()
|
||||
completionHandler(.success(response))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension RequestHandler
|
||||
|
||||
@@ -20,6 +20,8 @@ public protocol RequestHandler
|
||||
completionHandler: @escaping (Result<RemoveProvisioningProfilesResponse, Error>) -> Void)
|
||||
|
||||
func handleRemoveAppRequest(_ request: RemoveAppRequest, for connection: Connection, completionHandler: @escaping (Result<RemoveAppResponse, Error>) -> Void)
|
||||
|
||||
func handleEnableUnsignedCodeExecutionRequest(_ request: EnableUnsignedCodeExecutionRequest, for connection: Connection, completionHandler: @escaping (Result<EnableUnsignedCodeExecutionResponse, Error>) -> Void)
|
||||
}
|
||||
|
||||
public protocol ConnectionHandler: AnyObject
|
||||
@@ -152,6 +154,11 @@ private extension ConnectionManager
|
||||
finish(result)
|
||||
}
|
||||
|
||||
case .success(.enableUnsignedCodeExecution(let request)):
|
||||
self.requestHandler.handleEnableUnsignedCodeExecutionRequest(request, for: connection) { (result) in
|
||||
finish(result)
|
||||
}
|
||||
|
||||
case .success(.unknown):
|
||||
finish(Result<ErrorResponse, Error>.failure(ALTServerError(.unknownRequest)))
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public enum ServerRequest: Decodable
|
||||
case installProvisioningProfiles(InstallProvisioningProfilesRequest)
|
||||
case removeProvisioningProfiles(RemoveProvisioningProfilesRequest)
|
||||
case removeApp(RemoveAppRequest)
|
||||
case enableUnsignedCodeExecution(EnableUnsignedCodeExecutionRequest)
|
||||
case unknown(identifier: String, version: Int)
|
||||
|
||||
var identifier: String {
|
||||
@@ -36,6 +37,7 @@ public enum ServerRequest: Decodable
|
||||
case .installProvisioningProfiles(let request): return request.identifier
|
||||
case .removeProvisioningProfiles(let request): return request.identifier
|
||||
case .removeApp(let request): return request.identifier
|
||||
case .enableUnsignedCodeExecution(let request): return request.identifier
|
||||
case .unknown(let identifier, _): return identifier
|
||||
}
|
||||
}
|
||||
@@ -49,6 +51,7 @@ public enum ServerRequest: Decodable
|
||||
case .installProvisioningProfiles(let request): return request.version
|
||||
case .removeProvisioningProfiles(let request): return request.version
|
||||
case .removeApp(let request): return request.version
|
||||
case .enableUnsignedCodeExecution(let request): return request.version
|
||||
case .unknown(_, let version): return version
|
||||
}
|
||||
}
|
||||
@@ -92,6 +95,10 @@ public enum ServerRequest: Decodable
|
||||
let request = try RemoveAppRequest(from: decoder)
|
||||
self = .removeApp(request)
|
||||
|
||||
case "EnableUnsignedCodeExecutionRequest":
|
||||
let request = try EnableUnsignedCodeExecutionRequest(from: decoder)
|
||||
self = .enableUnsignedCodeExecution(request)
|
||||
|
||||
default:
|
||||
self = .unknown(identifier: identifier, version: version)
|
||||
}
|
||||
@@ -105,6 +112,7 @@ public enum ServerResponse: Decodable
|
||||
case installProvisioningProfiles(InstallProvisioningProfilesResponse)
|
||||
case removeProvisioningProfiles(RemoveProvisioningProfilesResponse)
|
||||
case removeApp(RemoveAppResponse)
|
||||
case enableUnsignedCodeExecution(EnableUnsignedCodeExecutionResponse)
|
||||
case error(ErrorResponse)
|
||||
case unknown(identifier: String, version: Int)
|
||||
|
||||
@@ -116,6 +124,7 @@ public enum ServerResponse: Decodable
|
||||
case .installProvisioningProfiles(let response): return response.identifier
|
||||
case .removeProvisioningProfiles(let response): return response.identifier
|
||||
case .removeApp(let response): return response.identifier
|
||||
case .enableUnsignedCodeExecution(let response): return response.identifier
|
||||
case .error(let response): return response.identifier
|
||||
case .unknown(let identifier, _): return identifier
|
||||
}
|
||||
@@ -129,6 +138,7 @@ public enum ServerResponse: Decodable
|
||||
case .installProvisioningProfiles(let response): return response.version
|
||||
case .removeProvisioningProfiles(let response): return response.version
|
||||
case .removeApp(let response): return response.version
|
||||
case .enableUnsignedCodeExecution(let response): return response.version
|
||||
case .error(let response): return response.version
|
||||
case .unknown(_, let version): return version
|
||||
}
|
||||
@@ -169,6 +179,10 @@ public enum ServerResponse: Decodable
|
||||
let response = try RemoveAppResponse(from: decoder)
|
||||
self = .removeApp(response)
|
||||
|
||||
case "EnableUnsignedCodeExecutionResponse":
|
||||
let response = try EnableUnsignedCodeExecutionResponse(from: decoder)
|
||||
self = .enableUnsignedCodeExecution(response)
|
||||
|
||||
case "ErrorResponse":
|
||||
let response = try ErrorResponse(from: decoder)
|
||||
self = .error(response)
|
||||
@@ -424,3 +438,28 @@ public struct RemoveAppResponse: ServerMessageProtocol
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public struct EnableUnsignedCodeExecutionRequest: ServerMessageProtocol
|
||||
{
|
||||
public var version = 1
|
||||
public var identifier = "EnableUnsignedCodeExecutionRequest"
|
||||
|
||||
public var udid: String
|
||||
public var processID: Int
|
||||
|
||||
public init(udid: String, processID: Int)
|
||||
{
|
||||
self.udid = udid
|
||||
self.processID = processID
|
||||
}
|
||||
}
|
||||
|
||||
public struct EnableUnsignedCodeExecutionResponse: ServerMessageProtocol
|
||||
{
|
||||
public var version = 1
|
||||
public var identifier = "EnableUnsignedCodeExecutionResponse"
|
||||
|
||||
public init()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user