diff options
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r-- | src/idevicerestore.c | 96 |
1 files changed, 54 insertions, 42 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 19ae8be..7982ed7 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -167,16 +167,15 @@ int main(int argc, char* argv[]) { } // choose whether this is an upgrade or a restore (default to upgrade) - plist_t tss = NULL; + client->tss = NULL; plist_t build_identity = NULL; if (client->flags & FLAG_ERASE) { build_identity = get_build_identity(client, buildmanifest, 0); if (build_identity == NULL) { - error("ERROR: Unable to find build any identities\n"); + 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 @@ -184,24 +183,33 @@ int main(int argc, char* argv[]) { int valid_builds = 0; int build_count = get_build_count(buildmanifest); for (i = 0; i < build_count; i++) { - if (client->device->index > DEVICE_IPOD2G) { - build_identity = get_build_identity(client, buildmanifest, i); - if (get_shsh_blobs(client, ecid, build_identity, &tss) < 0) { - // if this fails then no SHSH blobs have been saved - // for this build identity, so check the next one - continue; - } - valid_builds++; + build_identity = get_build_identity(client, buildmanifest, i); + valid_builds++; + } + } + + if (client->flags & FLAG_CUSTOM > 0) { + if (client->device->index > DEVICE_IPOD2G) { + if (get_shsh_blobs(client, ecid, build_identity, &client->tss) < 0) { + error("ERROR: Unable to get SHSH blobs for this device\n"); + return -1; } } + + /* verify if we have tss records if required */ + if ((client->device->index > DEVICE_IPOD2G) && (client->tss == NULL)) { + error("ERROR: Unable to proceed without a tss record.\n"); + plist_free(buildmanifest); + return -1; + } } // Extract filesystem from IPSW and return its name char* filesystem = NULL; - if (extract_filesystem(client, ipsw, build_identity, &filesystem) < 0) { + if (extract_filesystem(client, client->ipsw, build_identity, &filesystem) < 0) { error("ERROR: Unable to extract filesystem from IPSW\n"); - if (tss) - plist_free(tss); + if (client->tss) + plist_free(client->tss); plist_free(buildmanifest); return -1; } @@ -211,8 +219,8 @@ int main(int argc, char* argv[]) { info("Entering recovery mode...\n"); if (normal_enter_recovery(client) < 0) { error("ERROR: Unable to place device into recovery mode\n"); - if (tss) - plist_free(tss); + if (client->tss) + plist_free(client->tss); plist_free(buildmanifest); return -1; } @@ -220,22 +228,22 @@ int main(int argc, char* argv[]) { // if the device is in DFU mode, place device into recovery mode if (client->mode->index == MODE_DFU) { - if (dfu_enter_recovery(client) < 0) { + if (dfu_enter_recovery(client, build_identity) < 0) { error("ERROR: Unable to place device into recovery mode\n"); plist_free(buildmanifest); - if (tss) - plist_free(tss); + if (client->tss) + plist_free(client->tss); return -1; } } // if the device is in recovery mode, place device into restore mode if (client->mode->index == MODE_RECOVERY) { - if (recovery_enter_restore(uuid, ipsw, tss) < 0) { + if (recovery_enter_restore(client, build_identity) < 0) { error("ERROR: Unable to place device into restore mode\n"); plist_free(buildmanifest); - if (tss) - plist_free(tss); + if (client->tss) + plist_free(client->tss); return -1; } } @@ -243,7 +251,7 @@ int main(int argc, char* argv[]) { // device is finally in restore mode, let's do this if (client->mode->index == MODE_RESTORE) { info("Restoring device... \n"); - if (restore_device(client, uuid, ipsw, tss, filesystem) < 0) { + if (restore_device(client, build_identity, filesystem) < 0) { error("ERROR: Unable to restore device\n"); return -1; } @@ -545,7 +553,7 @@ int extract_filesystem(struct idevicerestore_client_t* client, const char* ipsw, return 0; } -int get_signed_component(struct idevicerestore_client_t* client, const char* ipsw, plist_t tss, const char* path, char** data, uint32_t* size) { +int ipsw_get_component_by_path(const char* ipsw, plist_t tss, const char* path, char** data, uint32_t* size) { img3_file* img3 = NULL; uint32_t component_size = 0; char* component_data = NULL; @@ -564,36 +572,40 @@ int get_signed_component(struct idevicerestore_client_t* client, const char* ips return -1; } - img3 = img3_parse_file(component_data, component_size); - if (img3 == NULL) { - error("ERROR: Unable to parse IMG3: %s\n", component_name); + if (tss) { + info("Signing img3...\n"); + img3 = img3_parse_file(component_data, component_size); + if (img3 == NULL) { + error("ERROR: Unable to parse IMG3: %s\n", component_name); + free(component_data); + return -1; + } free(component_data); - return -1; - } - free(component_data); - if (tss_get_blob_by_path(tss, path, &component_blob) < 0) { - error("ERROR: Unable to get SHSH blob for TSS %s entry\n", component_name); - img3_free(img3); - return -1; - } + /* sign the blob if required */ + if (tss_get_blob_by_path(tss, path, &component_blob) < 0) { + error("ERROR: Unable to get SHSH blob for TSS %s entry\n", component_name); + img3_free(img3); + return -1; + } - if (client->device->index > DEVICE_IPOD2G && (client->flags & FLAG_CUSTOM) == 0) { if (img3_replace_signature(img3, component_blob) < 0) { error("ERROR: Unable to replace IMG3 signature\n"); free(component_blob); img3_free(img3); return -1; } - } - free(component_blob); - if (img3_get_data(img3, &component_data, &component_size) < 0) { - error("ERROR: Unable to reconstruct IMG3\n"); + if (component_blob) + free(component_blob); + + if (img3_get_data(img3, &component_data, &component_size) < 0) { + error("ERROR: Unable to reconstruct IMG3\n"); + img3_free(img3); + return -1; + } img3_free(img3); - return -1; } - img3_free(img3); if (idevicerestore_debug) { write_file(component_name, component_data, component_size); |