diff --git a/external/idevicerestore b/external/idevicerestore index 65435ecb..5d39c302 160000 --- a/external/idevicerestore +++ b/external/idevicerestore @@ -1 +1 @@ -Subproject commit 65435ecb53864e3c553c6574b7b38b3b16344212 +Subproject commit 5d39c3027dc6dfe2e8146f62dab5874ae64ede05 diff --git a/futurerestore/futurerestore.cpp b/futurerestore/futurerestore.cpp index 27ac403b..da57363e 100644 --- a/futurerestore/futurerestore.cpp +++ b/futurerestore/futurerestore.cpp @@ -106,7 +106,7 @@ extern "C"{ }; #pragma mark futurerestore -futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS){ +futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, bool noRestore) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS), _noRestore(noRestore){ _client = idevicerestore_client_new(); if (_client == NULL) throw std::string("could not create idevicerestore client\n"); @@ -924,6 +924,7 @@ void futurerestore::doRestore(const char *ipsw){ plist_t build_identity = NULL; client->ipsw = strdup(ipsw); + if (_noRestore) client->flags |= FLAG_NO_RESTORE; if (!_isUpdateInstall) client->flags |= FLAG_ERASE; irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, client); @@ -1339,8 +1340,9 @@ void futurerestore::doRestore(const char *ipsw){ mutex_unlock(&client->device_event_mutex); info("About to restore device... \n"); - int result = 0; - retassure(!(result = restore_device(client, build_identity, filesystem)), "ERROR: Unable to restore device\n"); + int result = restore_device(client, build_identity, filesystem); + if (result == 2) return; + else retassure(!(result), "ERROR: Unable to restore device\n"); } int futurerestore::doJustBoot(const char *ipsw, string bootargs){ diff --git a/futurerestore/futurerestore.hpp b/futurerestore/futurerestore.hpp index 2db8ee83..48bb62ac 100644 --- a/futurerestore/futurerestore.hpp +++ b/futurerestore/futurerestore.hpp @@ -58,6 +58,7 @@ class futurerestore { bool _isUpdateInstall = false; bool _isPwnDfu = false; bool _noIBSS = false; + bool _noRestore = false; char *_firmwareJson = NULL; jssytok_t *_firmwareTokens = NULL;; @@ -84,7 +85,7 @@ class futurerestore { void enterPwnRecovery2(plist_t build_identity, std::string bootargs = ""); public: - futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false); + futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool noRestore = false); bool init(); int getDeviceMode(bool reRequest); uint64_t getDeviceEcid(); diff --git a/futurerestore/main.cpp b/futurerestore/main.cpp index 30eb47a2..e2683b30 100644 --- a/futurerestore/main.cpp +++ b/futurerestore/main.cpp @@ -44,6 +44,7 @@ static struct option longopts[] = { { "debug", no_argument, NULL, 'd' }, { "exit-recovery", no_argument, NULL, 'e' }, { "latest-sep", no_argument, NULL, '0' }, + { "no-restore", no_argument, NULL, 'z' }, { "latest-baseband", no_argument, NULL, '1' }, { "no-baseband", no_argument, NULL, '2' }, #ifdef HAVE_LIBIPATCHER @@ -61,6 +62,7 @@ static struct option longopts[] = { #define FLAG_NO_BASEBAND 1 << 4 #define FLAG_IS_PWN_DFU 1 << 5 #define FLAG_NO_IBSS 1 << 6 +#define FLAG_NO_RESTORE_FR 1 << 7 void cmd_help(){ printf("Usage: futurerestore [OPTIONS] iPSW\n"); @@ -72,6 +74,7 @@ void cmd_help(){ printf(" -w, --wait\t\t\tKeep rebooting until ApNonce matches APTicket (ApNonce collision, unreliable)\n"); printf(" -d, --debug\t\t\tShow all code, use to save a log for debug testing\n"); printf(" -e, --exit-recovery\t\tExit recovery mode and quit\n"); + printf(" -z, --no-restore\t\tDo not restore and end right before NOR data is sent\n"); #ifdef HAVE_LIBIPATCHER printf("\nOptions for downgrading with Odysseus:\n"); @@ -117,6 +120,7 @@ int main_r(int argc, const char * argv[]) { int opt = 0; long flags = 0; bool exitRecovery = false; + bool noRestore = false; int isSepManifestSigned = 0; int isBasebandSigned = 0; @@ -138,7 +142,7 @@ int main_r(int argc, const char * argv[]) { return -1; } - while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wude0123", longopts, &optindex)) > 0) { + while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez0123", longopts, &optindex)) > 0) { switch (opt) { case 't': // long option: "apticket"; can be called as short option apticketPaths.push_back(optarg); @@ -185,6 +189,9 @@ int main_r(int argc, const char * argv[]) { case 'e': // long option: "exit-recovery"; can be called as short option exitRecovery = true; break; + case 'z': // long option: "no-restore"; can be called as short option + flags |= FLAG_NO_RESTORE_FR; + break; case 'd': // long option: "debug"; can be called as short option idevicerestore_debug = 1; break; @@ -213,7 +220,7 @@ int main_r(int argc, const char * argv[]) { return -5; } - futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS); + futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_NO_RESTORE_FR); retassure(client.init(),"can't init, no device found\n"); printf("futurerestore init done\n");