From 71561a452a238eb7fa7aae8f1e2752fb357e4756 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Tue, 12 Apr 2022 13:36:19 +0200 Subject: Use proper detection for macOS restore path (instead of version number comparison) --- src/common.h | 1 + src/dfu.c | 2 +- src/idevicerestore.c | 21 ++++++++++++++------- src/recovery.c | 2 +- src/restore.c | 12 ++++-------- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/common.h b/src/common.h index cce63a4..634fc09 100644 --- a/src/common.h +++ b/src/common.h @@ -123,6 +123,7 @@ struct idevicerestore_client_t { mutex_t device_event_mutex; cond_t device_event_cond; int ignore_device_add_events; + plist_t macos_variant; }; extern struct idevicerestore_mode_t idevicerestore_modes[]; diff --git a/src/dfu.c b/src/dfu.c index a675c53..fc2622e 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -484,7 +484,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide mutex_lock(&client->device_event_mutex); // Now, before sending iBEC, we must send necessary firmwares on new versions. - if (client->build_major >= 20) { + if (client->macos_variant) { // Without this empty policy file & its special signature, iBEC won't start. if (dfu_send_component_and_command(client, build_identity, "Ap,LocalPolicy", "lpolrestore") < 0) { mutex_unlock(&client->device_event_mutex); diff --git a/src/idevicerestore.c b/src/idevicerestore.c index c6403d3..c25d98e 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -671,8 +671,10 @@ int idevicerestore_start(struct idevicerestore_client_t* client) // choose whether this is an upgrade or a restore (default to upgrade) client->tss = NULL; plist_t build_identity = NULL; + int build_identity_needs_free = 0; if (client->flags & FLAG_CUSTOM) { build_identity = plist_new_dict(); + build_identity_needs_free = 1; { plist_t node; plist_t comp; @@ -699,6 +701,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) uint32_t msize = 0; if (ipsw_extract_to_memory(client->ipsw, tmpstr, (unsigned char**)&fmanifest, &msize) < 0) { error("ERROR: could not extract %s from IPSW\n", tmpstr); + free(build_identity); return -1; } @@ -835,9 +838,15 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } } + client->macos_variant = build_manifest_get_build_identity_for_model_with_variant(client->build_manifest, client->device->hardware_model, RESTORE_VARIANT_MACOS_RECOVERY_OS); + /* print information about current build identity */ build_identity_print_information(build_identity); + if (client->macos_variant) { + info("Performing macOS restore\n"); + } + if (client->mode == MODE_NORMAL && !(client->flags & FLAG_ERASE) && !(client->flags & FLAG_SHSHONLY)) { plist_t pver = normal_get_lockdown_value(client, NULL, "ProductVersion"); char *device_version = NULL; @@ -1092,7 +1101,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) error("ERROR: Unable to get SHSH blobs for this device\n"); return -1; } - if (client->build_major >= 20) { + if (client->macos_variant) { if (get_local_policy_tss_response(client, build_identity, &client->tss_localpolicy) < 0) { error("ERROR: Unable to get SHSH blobs for this device (local policy)\n"); return -1; @@ -1412,7 +1421,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) idevicerestore_progress(client, RESTORE_NUM_STEPS-1, 1.0); } - if (build_identity) + if (build_identity_needs_free) plist_free(build_identity); return result; @@ -1991,14 +2000,14 @@ plist_t build_manifest_get_build_identity_for_model_with_variant(plist_t build_m if (strcmp(str, variant) != 0) { /* if it's not a full match, let's try a partial match */ if (strstr(str, variant)) { - return plist_copy(ident); + return ident; } continue; } else { - return plist_copy(ident); + return ident; } } else { - return plist_copy(ident); + return ident; } } @@ -2591,8 +2600,6 @@ int build_manifest_get_identity_count(plist_t build_manifest) error("ERROR: Unable to find build identities node\n"); return -1; } - - // check and make sure this identity exists in buildmanifest return plist_array_get_size(build_identities_array); } diff --git a/src/recovery.c b/src/recovery.c index b6a6f51..bcdd945 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -124,7 +124,7 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build { if (client->build_major >= 8) { client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress"); - } else if (client->build_major >= 20) { + } else if (client->macos_variant) { client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress -restore"); } diff --git a/src/restore.c b/src/restore.c index 78315cf..3942745 100644 --- a/src/restore.c +++ b/src/restore.c @@ -3135,11 +3135,11 @@ static int restore_send_bootability_bundle_data(restored_client_t restore, struc return 0; } -plist_t restore_get_build_identity(struct idevicerestore_client_t* client, uint8_t is_recover_os) +plist_t restore_get_build_identity(struct idevicerestore_client_t* client, uint8_t is_recovery_os) { const char *variant; - if (is_recover_os) + if (is_recovery_os) variant = RESTORE_VARIANT_MACOS_RECOVERY_OS; else if (client->flags & FLAG_ERASE) variant = RESTORE_VARIANT_ERASE_INSTALL; @@ -3160,11 +3160,7 @@ plist_t restore_get_build_identity(struct idevicerestore_client_t* client, uint8 plist_t restore_get_build_identity_from_request(struct idevicerestore_client_t* client, plist_t msg) { plist_t args = plist_dict_get_item(msg, "Arguments"); - plist_t is_recovery_node = plist_dict_get_item(args, "IsRecoveryOS"); - uint8_t is_recovery = 0; - plist_get_bool_val(is_recovery_node, &is_recovery); - - return restore_get_build_identity(client, is_recovery); + return restore_get_build_identity(client, _plist_dict_get_bool(args, "IsRecoveryOS")); } int extract_macos_variant(plist_t build_identity, char** output) @@ -3958,7 +3954,7 @@ int restore_device(struct idevicerestore_client_t* client, plist_t build_identit plist_dict_set_item(opts, "SupportedMessageTypes", restore_supported_message_types()); // FIXME: Should be adjusted for update behaviors - if (client->build_major >= 20) { + if (client->macos_variant) { plist_dict_set_item(opts, "AddSystemPartitionPadding", plist_new_bool(1)); plist_dict_set_item(opts, "AllowUntetheredRestore", plist_new_bool(0)); plist_dict_set_item(opts, "AuthInstallEnableSso", plist_new_bool(0)); -- cgit v1.1-32-gdbae