diff options
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r-- | src/idevicerestore.c | 79 |
1 files changed, 57 insertions, 22 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 0ee2bde..5601082 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -73,6 +73,8 @@ static struct option longopts[] = { { "no-action", no_argument, NULL, 'n' }, { "cache-path", required_argument, NULL, 'C' }, { "no-input", no_argument, NULL, 'y' }, + { "restore-mode", no_argument, NULL, 'R' }, + { "ticket", required_argument, NULL, 'T' }, { NULL, 0, NULL, 0 } }; @@ -117,6 +119,8 @@ static void usage(int argc, char* argv[], int err) " -t, --shsh Fetch TSS record and save to .shsh file, then exit\n" \ " -k, --keep-pers Write personalized components to files for debugging\n" \ " -p, --pwn Put device in pwned DFU mode and exit (limera1n devices only)\n" \ + " -R, --restore-mode Allow restoring from Restore mode\n" \ + " -T, --ticket PATH Use file at PATH to send as AP ticket\n" \ "\n" \ "Homepage: <" PACKAGE_URL ">\n", (name ? name + 1 : argv[0])); @@ -557,21 +561,29 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } if (client->mode->index == MODE_RESTORE) { - if (restore_reboot(client) < 0) { - error("ERROR: Unable to exit restore mode\n"); - return -2; - } + if (client->flags & FLAG_ALLOW_RESTORE_MODE) { + tss_enabled = 0; + if (!client->root_ticket) { + client->root_ticket = (void*)strdup(""); + client->root_ticket_len = 0; + } + } else { + if (restore_reboot(client) < 0) { + error("ERROR: Unable to exit restore mode\n"); + return -2; + } - // we need to refresh the current mode again - mutex_lock(&client->device_event_mutex); - cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 60000); - if (client->mode == &idevicerestore_modes[MODE_UNKNOWN] || (client->flags & FLAG_QUIT)) { + // we need to refresh the current mode again + mutex_lock(&client->device_event_mutex); + cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 60000); + if (client->mode == &idevicerestore_modes[MODE_UNKNOWN] || (client->flags & FLAG_QUIT)) { + mutex_unlock(&client->device_event_mutex); + error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n"); + return -1; + } + info("Found device in %s mode\n", client->mode->string); mutex_unlock(&client->device_event_mutex); - error("ERROR: Unable to discover device mode. Please make sure a device is attached.\n"); - return -1; } - info("Found device in %s mode\n", client->mode->string); - mutex_unlock(&client->device_event_mutex); } // verify if ipsw file exists @@ -1302,17 +1314,19 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.9); - mutex_lock(&client->device_event_mutex); - info("Waiting for device to enter restore mode...\n"); - cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 180000); - if (client->mode != &idevicerestore_modes[MODE_RESTORE] || (client->flags & FLAG_QUIT)) { + if (client->mode->index != MODE_RESTORE) { + mutex_lock(&client->device_event_mutex); + info("Waiting for device to enter restore mode...\n"); + cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 180000); + if (client->mode != &idevicerestore_modes[MODE_RESTORE] || (client->flags & FLAG_QUIT)) { + mutex_unlock(&client->device_event_mutex); + error("ERROR: Device failed to enter restore mode.\n"); + if (delete_fs && filesystem) + unlink(filesystem); + return -1; + } mutex_unlock(&client->device_event_mutex); - error("ERROR: Device failed to enter restore mode.\n"); - if (delete_fs && filesystem) - unlink(filesystem); - return -1; } - mutex_unlock(&client->device_event_mutex); // device is finally in restore mode, let's do this if (client->mode->index == MODE_RESTORE) { @@ -1418,6 +1432,9 @@ void idevicerestore_client_free(struct idevicerestore_client_t* client) if (client->cache_dir) { free(client->cache_dir); } + if (client->root_ticket) { + free(client->root_ticket); + } free(client); } @@ -1528,7 +1545,7 @@ int main(int argc, char* argv[]) { client->flags |= FLAG_INTERACTIVE; } - while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:nC:ky", longopts, &optindex)) > 0) { + while ((opt = getopt_long(argc, argv, "dhcesxtpli:u:nC:kyRT:", longopts, &optindex)) > 0) { switch (opt) { case 'h': usage(argc, argv, 0); @@ -1605,6 +1622,21 @@ int main(int argc, char* argv[]) { client->flags &= ~FLAG_INTERACTIVE; break; + case 'R': + client->flags |= FLAG_ALLOW_RESTORE_MODE; + break; + + case 'T': { + size_t root_ticket_len = 0; + unsigned char* root_ticket = NULL; + if (read_file(optarg, (void**)&root_ticket, &root_ticket_len) != 0) { + return -1; + } + client->root_ticket = root_ticket; + client->root_ticket_len = (int)root_ticket_len; + info("Using ApTicket found at %s length %u\n", optarg, client->root_ticket_len); + break; + } default: usage(argc, argv, 1); return -1; @@ -1706,6 +1738,9 @@ int is_image4_supported(struct idevicerestore_client_t* client) case MODE_NORMAL: res = normal_is_image4_supported(client); break; + case MODE_RESTORE: + res = restore_is_image4_supported(client); + break; case MODE_DFU: res = dfu_is_image4_supported(client); break; |