diff options
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r-- | src/idevicerestore.c | 126 |
1 files changed, 88 insertions, 38 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 7982ed7..00c35c1 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -81,20 +81,20 @@ int main(int argc, char* argv[]) { return 0; case 'd': - client->flags &= FLAG_DEBUG; + client->flags |= FLAG_DEBUG; idevicerestore_debug = 1; break; case 'e': - client->flags &= FLAG_ERASE; + client->flags |= FLAG_ERASE; break; case 'c': - client->flags &= FLAG_CUSTOM; + client->flags |= FLAG_CUSTOM; break; case 'x': - client->flags &= FLAG_EXCLUDE; + client->flags |= FLAG_EXCLUDE; break; case 'u': @@ -149,15 +149,18 @@ int main(int argc, char* argv[]) { // extract buildmanifest plist_t buildmanifest = NULL; info("Extracting BuildManifest from IPSW\n"); - if (extract_buildmanifest(client, ipsw, &buildmanifest) < 0) { + if (ipsw_extract_build_manifest(ipsw, &buildmanifest) < 0) { error("ERROR: Unable to extract BuildManifest from %s\n", ipsw); return -1; } + /* print iOS information from the manifest */ + build_manifest_print_information(buildmanifest); + // devices are listed in order from oldest to newest // so we'll need their ECID if (client->device->index > DEVICE_IPOD2G) { - debug("Creating TSS request\n"); + debug("Getting device's ECID for TSS request\n"); // fetch the device's ECID for the TSS request if (get_ecid(client, &client->ecid) < 0) { error("ERROR: Unable to find device ECID\n"); @@ -170,7 +173,7 @@ int main(int argc, char* argv[]) { client->tss = NULL; plist_t build_identity = NULL; if (client->flags & FLAG_ERASE) { - build_identity = get_build_identity(client, buildmanifest, 0); + build_identity = build_manifest_get_build_identity(buildmanifest, 0); if (build_identity == NULL) { error("ERROR: Unable to find any build identities\n"); plist_free(buildmanifest); @@ -181,13 +184,16 @@ int main(int argc, char* argv[]) { // and list the valid ones int i = 0; int valid_builds = 0; - int build_count = get_build_count(buildmanifest); + int build_count = build_manifest_get_identity_count(buildmanifest); for (i = 0; i < build_count; i++) { - build_identity = get_build_identity(client, buildmanifest, i); + build_identity = build_manifest_get_build_identity(buildmanifest, i); valid_builds++; } } + /* print information about current build identity */ + build_identity_print_information(build_identity); + if (client->flags & FLAG_CUSTOM > 0) { if (client->device->index > DEVICE_IPOD2G) { if (get_shsh_blobs(client, ecid, build_identity, &client->tss) < 0) { @@ -206,7 +212,7 @@ int main(int argc, char* argv[]) { // Extract filesystem from IPSW and return its name char* filesystem = NULL; - if (extract_filesystem(client, client->ipsw, build_identity, &filesystem) < 0) { + if (ipsw_extract_filesystem(client->ipsw, build_identity, &filesystem) < 0) { error("ERROR: Unable to extract filesystem from IPSW\n"); if (client->tss) plist_free(client->tss); @@ -455,32 +461,9 @@ int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { return 0; } -int extract_buildmanifest(struct idevicerestore_client_t* client, const char* ipsw, plist_t* buildmanifest) { - int size = 0; - char* data = NULL; - int device = client->device->index; - - /* older devices don't require personalized firmwares and use a BuildManifesto.plist */ - if (ipsw_extract_to_memory(ipsw, "BuildManifesto.plist", &data, &size) == 0) { - plist_from_xml(data, size, buildmanifest); - return 0; - } - - data = NULL; - size = 0; - - /* whereas newer devices do not require personalized firmwares and use a BuildManifest.plist */ - if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", &data, &size) == 0) { - plist_from_xml(data, size, buildmanifest); - return 0; - } - - return -1; -} - -plist_t get_build_identity(struct idevicerestore_client_t* client, plist_t buildmanifest, uint32_t identity) { +plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t identity) { // fetch build identities array from BuildManifest - plist_t build_identities_array = plist_dict_get_item(buildmanifest, "BuildIdentities"); + 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; @@ -523,9 +506,9 @@ int get_shsh_blobs(struct idevicerestore_client_t* client, uint64_t ecid, plist_ return 0; } -int get_build_count(plist_t buildmanifest) { +int build_manifest_get_identity_count(plist_t build_manifest) { // fetch build identities array from BuildManifest - plist_t build_identities_array = plist_dict_get_item(buildmanifest, "BuildIdentities"); + 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 -1; @@ -535,7 +518,7 @@ int get_build_count(plist_t buildmanifest) { return plist_array_get_size(build_identities_array); } -int extract_filesystem(struct idevicerestore_client_t* client, const char* ipsw, plist_t build_identity, char** filesystem) { +int ipsw_extract_filesystem(const char* ipsw, plist_t build_identity, char** filesystem) { char* filename = NULL; if (build_identity_get_component_path(build_identity, "OS", &filename) < 0) { @@ -616,6 +599,73 @@ int ipsw_get_component_by_path(const char* ipsw, plist_t tss, const char* path, return 0; } +void build_manifest_print_information(plist_t build_manifest) { + char* value = NULL; + plist_t node = NULL; + + node = plist_dict_get_item(build_manifest, "ProductVersion"); + if (!node || plist_get_node_type(node) != PLIST_STRING) { + error("ERROR: Unable to find ProductVersion node\n"); + return; + } + plist_get_string_val(node, &value); + + info("Product Version: %s\n", value); + free(value); + + node = plist_dict_get_item(build_manifest, "ProductBuildVersion"); + if (!node || plist_get_node_type(node) != PLIST_STRING) { + error("ERROR: Unable to find ProductBuildVersion node\n"); + return; + } + plist_get_string_val(node, &value); + + info("Product Build: %s\n", value); + free(value); + + node = NULL; +} + +void build_identity_print_information(plist_t build_identity) { + char* value = NULL; + plist_t info_node = NULL; + plist_t node = NULL; + + info_node = plist_dict_get_item(build_identity, "Info"); + if (!info_node || plist_get_node_type(info_node) != PLIST_DICT) { + error("ERROR: Unable to find Info node\n"); + return; + } + + node = plist_dict_get_item(info_node, "Variant"); + if (!node || plist_get_node_type(node) != PLIST_STRING) { + error("ERROR: Unable to find Variant node\n"); + return; + } + plist_get_string_val(node, &value); + + info("Variant: %s\n", value); + free(value); + + node = plist_dict_get_item(info_node, "RestoreBehavior"); + if (!node || plist_get_node_type(node) != PLIST_STRING) { + error("ERROR: Unable to find RestoreBehavior node\n"); + return; + } + plist_get_string_val(node, &value); + + if (!strcmp(value, "Erase")) + info("This restore will erase your device data.\n"); + + if (!strcmp(value, "Update")) + info("This restore will update your device without loosing data.\n"); + + free(value); + + info_node = NULL; + node = NULL; +} + int build_identity_get_component_path(plist_t build_identity, const char* component, char** path) { char* filename = NULL; |