diff --git a/StikJIT/StikJITApp.swift b/StikJIT/StikJITApp.swift index cad1bd1d..c0752ed7 100644 --- a/StikJIT/StikJITApp.swift +++ b/StikJIT/StikJITApp.swift @@ -401,6 +401,9 @@ func isPairing() -> Bool { return true } + + + func startHeartbeatInBackground() { let heartBeat = Thread { let completionHandler: @convention(block) (Int32, String?) -> Void = { result, message in diff --git a/StikJIT/Utilities/mountDDI.swift b/StikJIT/Utilities/mountDDI.swift index 926a97e1..7eda677e 100644 --- a/StikJIT/Utilities/mountDDI.swift +++ b/StikJIT/Utilities/mountDDI.swift @@ -173,7 +173,7 @@ func mountPersonalDDI(deviceIP: String = "10.7.0.1", imagePath: String, trustcac } var uniqueChipIDPlist: plist_t? - guard lockdownd_get_value(lockdownClient, "UniqueChipID".cString(using: .utf8), &uniqueChipIDPlist) == IdeviceSuccess else { + guard lockdownd_get_value(lockdownClient, "UniqueChipID".cString(using: .utf8), &uniqueChipIDPlist, nil) == IdeviceSuccess else { print("Failed to get UniqueChipID") return 8 // EC: 8 } diff --git a/StikJIT/Views/HomeView.swift b/StikJIT/Views/HomeView.swift index 749f11bd..f1aa951a 100644 --- a/StikJIT/Views/HomeView.swift +++ b/StikJIT/Views/HomeView.swift @@ -19,6 +19,7 @@ struct HomeView: View { @AppStorage("username") private var username = "User" @AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = "" @AppStorage("autoQuitAfterEnablingJIT") private var doAutoQuitAfterEnablingJIT = false + @AppStorage("enableDeveloperMode") private var doenableDeveloperMode = false @State private var selectedBackgroundColor: Color = Color(hex: UserDefaults.standard.string(forKey: "customBackgroundColor") ?? "") ?? .clear @Environment(\.colorScheme) private var colorScheme let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() @@ -275,6 +276,7 @@ struct HomeView: View { } } + private func startJITInBackground(with bundleID: String) { isProcessing = true diff --git a/StikJIT/Views/SettingsView.swift b/StikJIT/Views/SettingsView.swift index 527aa81b..6484a656 100644 --- a/StikJIT/Views/SettingsView.swift +++ b/StikJIT/Views/SettingsView.swift @@ -12,6 +12,7 @@ struct SettingsView: View { @AppStorage("selectedAppIcon") private var selectedAppIcon: String = "AppIcon" @AppStorage("autoQuitAfterEnablingJIT") private var doAutoQuitAfterEnablingJIT = false @AppStorage("skipGetTaskAllowCheck") private var doSkipGetTaskAllowCheck = false + @AppStorage("enableDeveloperMode") private var doenableDeveloperMode = false @State private var isShowingPairingFilePicker = false @Environment(\.colorScheme) private var colorScheme @@ -34,6 +35,8 @@ struct SettingsView: View { let marketingVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0" return marketingVersion } + + // Developer profile image URLs private let developerProfiles: [String: String] = [ @@ -187,6 +190,27 @@ struct SettingsView: View { Toggle("Skip get-task-allow Check", isOn: $doSkipGetTaskAllowCheck) .foregroundColor(.primary) .padding(.vertical, 6) + Toggle("Enable Developer Mode", isOn: $doenableDeveloperMode) + .foregroundColor(.primary) + .padding(.vertical, 6) + .onChange(of: doenableDeveloperMode) { dowestart in + if dowestart { + LogManager.shared.addInfoLog("Enabling developer mode") + + let success = JITEnableContext.shared.enableDeveloperMode({ message in + + if let message = message { + + LogManager.shared.addInfoLog(message) + } + }) + if (success != 0){ + LogManager.shared.addInfoLog("Failed to enable developer mode, code: \(success)") + } else { + LogManager.shared.addInfoLog("Successfully enabled developer mode") + } + } + } } .padding(.vertical, 20) .padding(.horizontal, 16) diff --git a/StikJIT/idevice/JITEnableContext.h b/StikJIT/idevice/JITEnableContext.h index a3d1870d..fa3dce1a 100644 --- a/StikJIT/idevice/JITEnableContext.h +++ b/StikJIT/idevice/JITEnableContext.h @@ -17,6 +17,7 @@ typedef void (^LogFunc)(NSString *message); - (IdevicePairingFile*)getPairingFileWithError:(NSError**)error; - (void)startHeartbeatWithCompletionHandler:(HeartbeatCompletionHandler)completionHandler logger:(LogFunc)logger; - (BOOL)debugAppWithBundleID:(NSString*)bundleID logger:(LogFunc)logger; +- (int)enableDeveloperMode:(LogFunc)logger; - (NSDictionary*)getAppListWithError:(NSError**)error; - (UIImage*)getAppIconWithBundleId:(NSString*)bundleId error:(NSError**)error; @end diff --git a/StikJIT/idevice/JITEnableContext.m b/StikJIT/idevice/JITEnableContext.m index 04ffa151..34a95efd 100644 --- a/StikJIT/idevice/JITEnableContext.m +++ b/StikJIT/idevice/JITEnableContext.m @@ -121,6 +121,22 @@ - (BOOL)debugAppWithBundleID:(NSString*)bundleID logger:(LogFunc)logger { } +- (int)enableDeveloperMode:(LogFunc)logger { + + if(!provider) { + if(logger) { + logger(@"Provider not initialized!"); + } + NSLog(@"Provider not initialized!"); + return 4; + } + + + + return enable_developer_mode(provider); + +} + // apps may have different name, so we must use BnudleId as key. [bundleId:name] - (NSDictionary*)getAppListWithError:(NSError**)error { diff --git a/StikJIT/idevice/idevice.h b/StikJIT/idevice/idevice.h index 6dab1c6f..2fc9e018 100644 --- a/StikJIT/idevice/idevice.h +++ b/StikJIT/idevice/idevice.h @@ -1,25 +1,21 @@ // Jackson Coxson // Bindings to idevice - https://github.com/jkcoxson/idevice - -#ifndef IDEVICE_H -#define IDEVICE_H - #include #include #include #include #include #include "plist.h" - +#ifndef I_DEVICE +#define I_DEVICE #define LOCKDOWN_PORT 62078 - typedef enum IdeviceErrorCode { IdeviceSuccess = 0, Socket = -1, - Ssl = -2, - SslSetup = -3, + Tls = -2, + TlsBuilderFailed = -3, Plist = -4, Utf8 = -5, UnexpectedResponse = -6, @@ -104,6 +100,11 @@ typedef struct ImageMounterHandle ImageMounterHandle; typedef struct InstallationProxyClientHandle InstallationProxyClientHandle; +/** + * Opaque handle to a ProcessControlClient + */ +typedef struct LocationSimulationAdapterHandle LocationSimulationAdapterHandle; + typedef struct LockdowndClientHandle LockdowndClientHandle; /** @@ -921,6 +922,66 @@ enum IdeviceErrorCode installation_proxy_get_apps(struct InstallationProxyClient */ void installation_proxy_client_free(struct InstallationProxyClientHandle *handle); +/** + * Creates a new ProcessControlClient from a RemoteServerClient + * + * # Arguments + * * [`server`] - The RemoteServerClient to use + * * [`handle`] - Pointer to store the newly created ProcessControlClient handle + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * `server` must be a valid pointer to a handle allocated by this library + * `handle` must be a valid pointer to a location where the handle will be stored + */ +enum IdeviceErrorCode location_simulation_new(struct RemoteServerAdapterHandle *server, + struct LocationSimulationAdapterHandle **handle); + +/** + * Frees a ProcessControlClient handle + * + * # Arguments + * * [`handle`] - The handle to free + * + * # Safety + * `handle` must be a valid pointer to a handle allocated by this library or NULL + */ +void location_simulation_free(struct LocationSimulationAdapterHandle *handle); + +/** + * Clears the location set + * + * # Arguments + * * [`handle`] - The LocationSimulation handle + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * All pointers must be valid or NULL where appropriate + */ +enum IdeviceErrorCode location_simulation_clear(struct LocationSimulationAdapterHandle *handle); + +/** + * Sets the location + * + * # Arguments + * * [`handle`] - The LocationSimulation handle + * * [`latitude`] - The latitude to set + * * [`longitude`] - The longitude to set + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * All pointers must be valid or NULL where appropriate + */ +enum IdeviceErrorCode location_simulation_set(struct LocationSimulationAdapterHandle *handle, + double latitude, + double longitude); + /** * Connects to lockdownd service using TCP provider * @@ -1016,7 +1077,8 @@ enum IdeviceErrorCode lockdownd_start_service(struct LockdowndClientHandle *clie * * # Arguments * * `client` - A valid LockdowndClient handle - * * `value` - The value to get (null-terminated string) + * * `key` - The value to get (null-terminated string) + * * `domain` - The value to get (null-terminated string) * * `out_plist` - Pointer to store the returned plist value * * # Returns @@ -1028,7 +1090,8 @@ enum IdeviceErrorCode lockdownd_start_service(struct LockdowndClientHandle *clie * `out_plist` must be a valid pointer to store the plist */ enum IdeviceErrorCode lockdownd_get_value(struct LockdowndClientHandle *client, - const char *value, + const char *key, + const char *domain, void **out_plist); /** @@ -1911,6 +1974,89 @@ enum IdeviceErrorCode xpc_device_get_service_names(struct XPCDeviceAdapterHandle */ void xpc_device_free_service_names(char **names, uintptr_t count); +/** + * Connects to the Springboard service using a TCP provider + * + * # Arguments + * * [`provider`] - A TcpProvider + * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * `provider` must be a valid pointer to a handle allocated by this library + * `client` must be a valid, non-null pointer to a location where the handle will be stored + */ +enum IdeviceErrorCode springboard_services_connect_tcp(struct TcpProviderHandle *provider, + struct SpringBoardServicesClientHandle **client); + +/** + * Connects to the Springboard service using a usbmuxd provider + * + * # Arguments + * * [`provider`] - A UsbmuxdProvider + * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * `provider` must be a valid pointer to a handle allocated by this library + * `client` must be a valid, non-null pointer to a location where the handle will be stored + */ +enum IdeviceErrorCode springboard_services_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, + struct SpringBoardServicesClientHandle **client); + +/** + * Creates a new SpringBoardServices client from an existing Idevice connection + * + * # Arguments + * * [`socket`] - An IdeviceSocket handle + * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * `socket` must be a valid pointer to a handle allocated by this library + * `client` must be a valid, non-null pointer to a location where the handle will be stored + */ +enum IdeviceErrorCode springboard_services_new(struct IdeviceHandle *socket, + struct SpringBoardServicesClientHandle **client); + +/** + * Gets the icon of the specified app by bundle identifier + * + * # Arguments + * * `client` - A valid SpringBoardServicesClient handle + * * `bundle_identifier` - The identifiers of the app to get icon + * * `out_result` - On success, will be set to point to a newly allocated png data + * + * # Returns + * An error code indicating success or failure + * + * # Safety + * `client` must be a valid pointer to a handle allocated by this library + * `out_result` must be a valid, non-null pointer to a location where the result will be stored + */ +enum IdeviceErrorCode springboard_services_get_icon(struct SpringBoardServicesClientHandle *client, + const char *bundle_identifier, + void **out_result, + size_t *out_result_len); + +/** + * Frees an SpringBoardServicesClient handle + * + * # Arguments + * * [`handle`] - The handle to free + * + * # Safety + * `handle` must be a valid pointer to the handle that was allocated by this library, + * or NULL (in which case this function does nothing) + */ +void springboard_services_free(struct SpringBoardServicesClientHandle *handle); + /** * Connects to a usbmuxd instance over TCP * @@ -2010,36 +2156,4 @@ enum IdeviceErrorCode idevice_usbmuxd_unix_addr_new(const char *addr, * or NULL (in which case this function does nothing) */ void idevice_usbmuxd_addr_free(struct UsbmuxdAddrHandle *usbmuxd_addr); - -enum IdeviceErrorCode springboard_services_connect_tcp(struct TcpProviderHandle *provider, - struct SpringBoardServicesClientHandle **client); - -enum IdeviceErrorCode springboard_services_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct SpringBoardServicesClientHandle **client); - -enum IdeviceErrorCode springboard_services_new(struct IdeviceHandle *socket, - struct SpringBoardServicesClientHandle **client); - -/** - * Gets the icon of the specified app by bundle identifier - * - * # Arguments - * * `client` - A valid SpringBoardServicesClient handle - * * `bundle_identifier` - The identifiers of the app to get icon - * * `out_result` - On success, will be set to point to a newly allocated png data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `out_result` must be a valid, non-null pointer to a location where the result will be stored - */ -enum IdeviceErrorCode springboard_services_get_icon(struct SpringBoardServicesClientHandle *client, - const char *bundle_identifier, - void **out_result, - size_t *out_result_len); - -void springboard_services_free(struct SpringBoardServicesClientHandle *handle); - #endif diff --git a/StikJIT/idevice/jit.c b/StikJIT/idevice/jit.c index b657b348..f1a94f23 100644 --- a/StikJIT/idevice/jit.c +++ b/StikJIT/idevice/jit.c @@ -16,8 +16,34 @@ #include #include + #include "jit.h" +int enable_developer_mode(TcpProviderHandle *tcp_client){ + LockdowndClientHandle* client; + IdeviceErrorCode err = lockdownd_connect_tcp(tcp_client,&client); + if (err != IdeviceSuccess){ + fprintf(stderr, "Failed to connect to lockdownd: %d\n", err); + return 3; + } + plist_t developer_mode_plist = NULL; + uint8_t enabled = 0; + err = + lockdownd_get_value(client, "DeveloperModeStatus", + "com.apple.security.mac.amfi", &developer_mode_plist); + if (err != IdeviceSuccess) { + fprintf(stderr, "Failed to get product version: %d\n", err); + return 1; + } else { + + plist_get_bool_val(developer_mode_plist, &enabled); + printf("Developer mode enabled: %s\n", enabled ? "true" : "false"); + plist_free(developer_mode_plist); + + } + return enabled ? 0 : 2; +} + int debug_app(TcpProviderHandle* tcp_provider, const char *bundle_id, LogFuncC logger) { // Initialize logger idevice_init_logger(Debug, Disabled, NULL); diff --git a/StikJIT/idevice/jit.h b/StikJIT/idevice/jit.h index c42f2fc2..efd834e3 100644 --- a/StikJIT/idevice/jit.h +++ b/StikJIT/idevice/jit.h @@ -12,5 +12,6 @@ typedef void (^LogFuncC)(const char* message, ...); int debug_app(TcpProviderHandle* provider, const char *bundle_id, LogFuncC logger); +int enable_developer_mode(TcpProviderHandle *tcp_client); #endif /* JIT_H */ diff --git a/StikJIT/idevice/libidevice_ffi.a b/StikJIT/idevice/libidevice_ffi.a index 594e0ef9..86c2f163 100644 Binary files a/StikJIT/idevice/libidevice_ffi.a and b/StikJIT/idevice/libidevice_ffi.a differ