diff options
author | Nikias Bassen | 2015-10-09 03:07:34 +0200 |
---|---|---|
committer | Nikias Bassen | 2015-10-09 03:07:34 +0200 |
commit | 7336b600a160d731231d3ab05506e7be0c05f4e0 (patch) | |
tree | 0d6f362a80b4f1c33f97f278be925ab655bb7155 /src | |
parent | 46ead9b3afd6e79fa05a391b94bc929e94101e33 (diff) | |
download | idevicerestore-7336b600a160d731231d3ab05506e7be0c05f4e0.tar.gz idevicerestore-7336b600a160d731231d3ab05506e7be0c05f4e0.tar.bz2 |
Select build identity based on hardware model instead of first or last identity in manifest
While this might have worked in the past it didn't work anymore with the
iPhone 6S (plus) since it comes with two different CPUs (Samsung & TSMC A9).
Therefore the BuildManifest.plist has multiple build identities and for a
successful restore the correct build identity has to be selected for the
actual hardware model of the corresponding device.
Diffstat (limited to 'src')
-rw-r--r-- | src/idevicerestore.c | 70 | ||||
-rw-r--r-- | src/idevicerestore.h | 2 |
2 files changed, 63 insertions, 9 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index f02e7b0..ed1f53f 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -540,21 +540,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client) plist_dict_set_item(build_identity, "Manifest", manifest); } } else if (client->flags & FLAG_ERASE) { - build_identity = build_manifest_get_build_identity(buildmanifest, 0); + build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Erase"); if (build_identity == NULL) { error("ERROR: Unable to find any build identities\n"); plist_free(buildmanifest); return -1; } } else { - // loop through all build identities in the build manifest - // and list the valid ones - int i = 0; - int valid_builds = 0; - int build_count = build_manifest_get_identity_count(buildmanifest); - for (i = 0; i < build_count; i++) { - build_identity = build_manifest_get_build_identity(buildmanifest, i); - valid_builds++; + build_identity = build_manifest_get_build_identity_for_model_with_restore_behavior(buildmanifest, client->device->hardware_model, "Update"); + if (!build_identity) { + build_identity = build_manifest_get_build_identity_for_model(buildmanifest, client->device->hardware_model); } } @@ -1366,6 +1361,63 @@ plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t ident return plist_copy(build_identity); } +plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_t build_manifest, const char *hardware_model, const char *behavior) +{ + plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); + if (!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { + error("ERROR: Unable to find build identities node\n"); + return NULL; + } + + uint32_t i; + for (i = 0; i < plist_array_get_size(build_identities_array); i++) { + plist_t ident = plist_array_get_item(build_identities_array, i); + if (!ident || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t info_dict = plist_dict_get_item(ident, "Info"); + if (!info_dict || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t devclass = plist_dict_get_item(info_dict, "DeviceClass"); + if (!devclass || plist_get_node_type(devclass) != PLIST_STRING) { + continue; + } + char *str = NULL; + plist_get_string_val(devclass, &str); + if (strcasecmp(str, hardware_model) != 0) { + free(str); + continue; + } + free(str); + str = NULL; + if (behavior) { + plist_t rbehavior = plist_dict_get_item(info_dict, "RestoreBehavior"); + if (!rbehavior || plist_get_node_type(rbehavior) != PLIST_STRING) { + continue; + } + plist_get_string_val(rbehavior, &str); + if (strcasecmp(str, behavior) != 0) { + free(str); + continue; + } else { + free(str); + return plist_copy(ident); + } + free(str); + } else { + return plist_copy(ident); + } + } + + return NULL; +} + +plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model) +{ + return build_manifest_get_build_identity_for_model_with_restore_behavior(build_manifest, hardware_model, NULL); +} + int get_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss) { plist_t request = NULL; plist_t response = NULL; diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 931604c..7b23c87 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -84,6 +84,8 @@ int build_manifest_get_identity_count(plist_t build_manifest); int build_manifest_check_compatibility(plist_t build_manifest, const char* product); void build_manifest_get_version_information(plist_t build_manifest, struct idevicerestore_client_t* client); plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t identity); +plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model); +plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_t build_manifest, const char *hardware_model, const char *behavior); int build_manifest_get_build_count(plist_t build_manifest); void build_identity_print_information(plist_t build_identity); int build_identity_has_component(plist_t build_identity, const char* component); |