mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
* Heartbeat rework * remove some debug loggings * stik mini tool poc * Saperate JITEnableContext into extensions and put each feature into their own files. Fix local pairing file is removed after switched to external device by directly loading the remote device's pairing file in place. * custom origin & xmlhttprequest * Fix some memory leak * allow background script access idevice (codes are from the old JSSupport branch) Tests are not carried out but most of the js api should work. Do we need to obfuscate some functions' name? * Fix JITEnableContext singleton initializer race condition * Fix instprox callback --------- Co-authored-by: Stephen B <158498287+StephenDev0@users.noreply.github.com>
287 lines
9.2 KiB
Objective-C
287 lines
9.2 KiB
Objective-C
//
|
|
// process.m
|
|
// StikDebug
|
|
//
|
|
// Created by s s on 2025/12/12.
|
|
//
|
|
|
|
#import "JITEnableContext.h"
|
|
#import "JITEnableContextInternal.h"
|
|
@import Foundation;
|
|
|
|
@implementation JITEnableContext(Process)
|
|
|
|
- (NSArray<NSDictionary*>*)fetchProcessesViaAppServiceWithError:(NSError **)error {
|
|
[self ensureHeartbeatWithError:error];
|
|
if(*error) {
|
|
return nil;
|
|
}
|
|
|
|
IdeviceProviderHandle *providerToUse = provider;
|
|
CoreDeviceProxyHandle *coreProxy = NULL;
|
|
AdapterHandle *adapter = NULL;
|
|
AdapterStreamHandle *stream = NULL;
|
|
RsdHandshakeHandle *handshake = NULL;
|
|
AppServiceHandle *appService = NULL;
|
|
ProcessTokenC *processes = NULL;
|
|
uintptr_t count = 0;
|
|
NSMutableArray *result = nil;
|
|
IdeviceFfiError *ffiError = NULL;
|
|
|
|
do {
|
|
|
|
ffiError = core_device_proxy_connect(providerToUse, &coreProxy);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to connect CoreDeviceProxy"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
uint16_t rsdPort = 0;
|
|
ffiError = core_device_proxy_get_server_rsd_port(coreProxy, &rsdPort);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Unable to resolve RSD port"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = core_device_proxy_create_tcp_adapter(coreProxy, &adapter);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to create adapter"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
coreProxy = NULL;
|
|
ffiError = adapter_connect(adapter, rsdPort, (ReadWriteOpaque **)&stream);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Adapter connect failed"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = rsd_handshake_new((ReadWriteOpaque *)stream, &handshake);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "RSD handshake failed"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
stream = NULL;
|
|
ffiError = app_service_connect_rsd(adapter, handshake, &appService);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Unable to open AppService"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = app_service_list_processes(appService, &processes, &count);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to list processes"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
result = [NSMutableArray arrayWithCapacity:count];
|
|
for (uintptr_t idx = 0; idx < count; idx++) {
|
|
ProcessTokenC proc = processes[idx];
|
|
NSMutableDictionary *entry = [NSMutableDictionary dictionary];
|
|
entry[@"pid"] = @(proc.pid);
|
|
if (proc.executable_url) {
|
|
entry[@"path"] = [NSString stringWithUTF8String:proc.executable_url];
|
|
}
|
|
[result addObject:entry];
|
|
}
|
|
} while (0);
|
|
|
|
if (processes && count > 0) {
|
|
app_service_free_process_list(processes, count);
|
|
}
|
|
if (appService) {
|
|
app_service_free(appService);
|
|
}
|
|
if (handshake) {
|
|
rsd_handshake_free(handshake);
|
|
}
|
|
if (stream) {
|
|
adapter_stream_close(stream);
|
|
}
|
|
if (adapter) {
|
|
adapter_free(adapter);
|
|
}
|
|
if (coreProxy) {
|
|
core_device_proxy_free(coreProxy);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
- (NSArray<NSDictionary*>*)_fetchProcessListLocked:(NSError**)error {
|
|
[self ensureHeartbeatWithError:error];
|
|
if(*error) {
|
|
return nil;
|
|
}
|
|
return [self fetchProcessesViaAppServiceWithError:error];
|
|
}
|
|
|
|
- (NSArray<NSDictionary*>*)fetchProcessListWithError:(NSError**)error {
|
|
__block NSArray *result = nil;
|
|
__block NSError *localError = nil;
|
|
dispatch_sync(processInspectorQueue, ^{
|
|
result = [self _fetchProcessListLocked:&localError];
|
|
});
|
|
if (error && localError) {
|
|
*error = localError;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
- (BOOL)killProcessWithPID:(int)pid error:(NSError **)error {
|
|
[self ensureHeartbeatWithError:error];
|
|
if(*error) {
|
|
return nil;
|
|
}
|
|
|
|
IdeviceProviderHandle *providerToUse = provider;
|
|
CoreDeviceProxyHandle *coreProxy = NULL;
|
|
AdapterHandle *adapter = NULL;
|
|
AdapterStreamHandle *stream = NULL;
|
|
RsdHandshakeHandle *handshake = NULL;
|
|
AppServiceHandle *appService = NULL;
|
|
SignalResponseC *signalResponse = NULL;
|
|
IdeviceFfiError *ffiError = NULL;
|
|
BOOL success = NO;
|
|
|
|
do {
|
|
ffiError = core_device_proxy_connect(providerToUse, &coreProxy);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to connect CoreDeviceProxy"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
uint16_t rsdPort = 0;
|
|
ffiError = core_device_proxy_get_server_rsd_port(coreProxy, &rsdPort);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Unable to resolve RSD port"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = core_device_proxy_create_tcp_adapter(coreProxy, &adapter);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to create adapter"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
coreProxy = NULL;
|
|
ffiError = adapter_connect(adapter, rsdPort, (ReadWriteOpaque **)&stream);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Adapter connect failed"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = rsd_handshake_new((ReadWriteOpaque *)stream, &handshake);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "RSD handshake failed"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
stream = NULL;
|
|
ffiError = app_service_connect_rsd(adapter, handshake, &appService);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Unable to open AppService"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
|
|
ffiError = app_service_send_signal(appService, (uint32_t)pid, SIGKILL, &signalResponse);
|
|
if (ffiError) {
|
|
if (error) {
|
|
*error = [self errorWithStr:[NSString stringWithUTF8String:ffiError->message ?: "Failed to kill process"]
|
|
code:ffiError->code];
|
|
}
|
|
idevice_error_free(ffiError);
|
|
ffiError = NULL;
|
|
break;
|
|
}
|
|
success = YES;
|
|
} while (0);
|
|
|
|
if (signalResponse) {
|
|
app_service_free_signal_response(signalResponse);
|
|
}
|
|
if (appService) {
|
|
app_service_free(appService);
|
|
}
|
|
if (handshake) {
|
|
rsd_handshake_free(handshake);
|
|
}
|
|
if (stream) {
|
|
adapter_stream_close(stream);
|
|
}
|
|
if (adapter) {
|
|
adapter_free(adapter);
|
|
}
|
|
if (coreProxy) {
|
|
core_device_proxy_free(coreProxy);
|
|
}
|
|
return success;
|
|
}
|
|
|
|
|
|
@end
|