From d8b69365ecb78414d8a6bf024d449133f581b6d4 Mon Sep 17 00:00:00 2001 From: tihmstar Date: Sun, 2 Apr 2017 13:42:27 +0200 Subject: [PATCH] fully supporting 32bit devices now -autodetecting 32bit devices (removing --is-32bit parameter) --- futurerestore/futurerestore.cpp | 46 ++++++++++++++++++--------------- futurerestore/futurerestore.hpp | 10 ++++--- futurerestore/main.cpp | 16 ++++-------- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/futurerestore/futurerestore.cpp b/futurerestore/futurerestore.cpp index e2318e78..21b1298b 100644 --- a/futurerestore/futurerestore.cpp +++ b/futurerestore/futurerestore.cpp @@ -59,15 +59,14 @@ #define safePlistFree(buf) if (buf) plist_free(buf), buf = NULL futurerestore::futurerestore(){ - futurerestore(false); -} - -futurerestore::futurerestore(bool is32bit) : _is32bit(is32bit) { _client = idevicerestore_client_new(); if (_client == NULL) throw std::string("could not create idevicerestore client\n"); struct stat st{0}; if (stat(FUTURERESTORE_TMP_PATH, &st) == -1) __mkdir(FUTURERESTORE_TMP_PATH, 0755); + if (!_client->image4supported){ + info("[INFO] 32bit device detected\n"); + } //tsschecker nocache nocache = 1; @@ -149,13 +148,13 @@ plist_t futurerestore::nonceMatchesApTickets(){ vectornonces; - if (!_is32bit){ + if (_client->image4supported){ for (int i=0; i< _im4ms.size(); i++){ if (memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4ms[i],NULL), realNonceSize) == 0) return _aptickets[i]; } }else{ for (int i=0; i< _im4ms.size(); i++){ - if (memcmp(realnonce, (unsigned const char*)getNonceFromSCAB(_im4ms[i],NULL), realNonceSize) == 0) return _aptickets[i]; + if (memcmp(realnonce, (unsigned const char*)getNonceFromSCAB(_im4ms[i],(size_t*)&realNonceSize), realNonceSize) == 0) return _aptickets[i]; } } @@ -173,13 +172,13 @@ const char *futurerestore::nonceMatchesIM4Ms(){ vectornonces; - if (_is32bit) { + if (_client->image4supported) { for (int i=0; i< _im4ms.size(); i++){ - if (memcmp(realnonce, (unsigned const char*)getNonceFromSCAB(_im4ms[i],NULL), realNonceSize) == 0) return _im4ms[i]; + if (memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4ms[i],NULL), realNonceSize) == 0) return _im4ms[i]; } }else{ for (int i=0; i< _im4ms.size(); i++){ - if (memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4ms[i],NULL), realNonceSize) == 0) return _im4ms[i]; + if (memcmp(realnonce, (unsigned const char*)getNonceFromSCAB(_im4ms[i],(size_t*)&realNonceSize), realNonceSize) == 0) return _im4ms[i]; } } @@ -234,8 +233,11 @@ void futurerestore::waitForNonce(){ size_t nonceSize = 0; vectornonces; + if (!_client->image4supported) + reterror(-77, "Error: waitForNonce is not supported on 32bit devices\n"); + for (auto im4m : _im4ms){ - nonces.push_back(_is32bit ? getNonceFromSCAB(im4m,&nonceSize) : getNonceFromIM4M(im4m,&nonceSize)); + nonces.push_back(getNonceFromIM4M(im4m,&nonceSize)); } waitForNonce(nonces,nonceSize); @@ -270,7 +272,7 @@ void futurerestore::loadAPTickets(const vector &apticketPaths){ plist_from_xml(buf, (uint32_t)fSize, &apticket); - plist_t ticket = plist_dict_get_item(apticket, (_is32bit) ? "APTicket" : "ApImg4Ticket"); + plist_t ticket = plist_dict_get_item(apticket, (_client->image4supported) ? "ApImg4Ticket" : "APTicket"); uint64_t im4msize=0; plist_get_data_val(ticket, &im4m, &im4msize); @@ -358,7 +360,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ if (!(build_identity = getBuildidentityWithBoardconfig(buildmanifest, client->device->hardware_model, noerase))) reterror(-5,"ERROR: Unable to find any build identities for IPSW\n"); - if (!_is32bit && !(sep_build_identity = getBuildidentityWithBoardconfig(_sepbuildmanifest, client->device->hardware_model, noerase))) + if (_client->image4supported && !(sep_build_identity = getBuildidentityWithBoardconfig(_sepbuildmanifest, client->device->hardware_model, noerase))) reterror(-5,"ERROR: Unable to find any build identities for SEP\n"); //this is the buildidentity used for restore @@ -368,7 +370,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ const char * im4m = nonceMatchesIM4Ms(); uint64_t deviceEcid = getDeviceEcid(); - uint64_t im4mEcid = (_is32bit) ? getEcidFromSCAB(im4m) : getEcidFromIM4M(im4m); + uint64_t im4mEcid = (_client->image4supported) ? getEcidFromIM4M(im4m) : getEcidFromSCAB(im4m); if (!im4mEcid) reterror(-46, "Failed to read ECID from APTicket\n"); @@ -379,12 +381,12 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ }else printf("Verified ECID in APTicket matches device ECID\n"); - if (!_is32bit) { + if (_client->image4supported) { printf("checking APTicket to be valid for this restore...\n"); const char * im4m = nonceMatchesIM4Ms(); uint64_t deviceEcid = getDeviceEcid(); - uint64_t im4mEcid = (_is32bit) ? getEcidFromSCAB(im4m) : getEcidFromIM4M(im4m); + uint64_t im4mEcid = (_client->image4supported) ? getEcidFromIM4M(im4m) : getEcidFromSCAB(im4m); if (!im4mEcid) reterror(-46, "Failed to read ECID from APTicket\n"); @@ -445,7 +447,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ warning("WARNING: we don't have a basebandbuildmanifest, not flashing baseband!\n"); } - if (!_is32bit) { + if (_client->image4supported) { plist_t sep_manifest = plist_dict_get_item(sep_build_identity, "Manifest"); plist_t sep_sep = plist_copy(plist_dict_get_item(sep_manifest, "SEP")); plist_dict_set_item(manifest, "SEP", sep_sep); @@ -572,7 +574,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ reterror(-15, "failed to reconnect to device in recovery (iBEC) mode\n"); //do magic - if (!_is32bit) get_sep_nonce(client, &client->sepnonce, &client->sepnonce_size); + if (_client->image4supported) get_sep_nonce(client, &client->sepnonce, &client->sepnonce_size); get_ap_nonce(client, &client->nonce, &client->nonce_size); get_ecid(client, &client->ecid); if (client->mode->index == MODE_RECOVERY) { @@ -593,13 +595,13 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){ } - if (!_is32bit && get_tss_response(client, sep_build_identity, &client->septss) < 0) { + if (_client->image4supported && get_tss_response(client, sep_build_identity, &client->septss) < 0) { reterror(-11,"ERROR: Unable to get SHSH blobs for SEP\n"); } - if (!_is32bit && (!_client->sepfwdatasize || !_client->sepfwdata)) + if (_client->image4supported && (!_client->sepfwdatasize || !_client->sepfwdata)) reterror(-55, "SEP not loaded, refusing to continue"); @@ -742,12 +744,12 @@ void futurerestore::loadLatestSep(){ } void futurerestore::setSepManifestPath(const char *sepManifestPath){ - if (!(_sepbuildmanifest = loadPlistFromFile(sepManifestPath))) + if (!(_sepbuildmanifest = loadPlistFromFile(_sepbuildmanifestPath = sepManifestPath))) reterror(-14, "failed to load SEPManifest"); } void futurerestore::setBasebandManifestPath(const char *basebandManifestPath){ - if (!(_basebandbuildmanifest = loadPlistFromFile(basebandManifestPath))) + if (!(_basebandbuildmanifest = loadPlistFromFile(_basebandbuildmanifestPath = basebandManifestPath))) reterror(-14, "failed to load BasebandManifest"); }; @@ -805,6 +807,8 @@ char *futurerestore::getNonceFromSCAB(const char* scab, size_t *nonceSize){ error("unexpected number of Elements in SCAB sequence\n"); goto error; } + if (nonceSize) *nonceSize = 0; + mainSet = asn1ElementAtIndex(scab, 1); elems = asn1ElementsInObject(mainSet); diff --git a/futurerestore/futurerestore.hpp b/futurerestore/futurerestore.hpp index 65e95454..9216f2fe 100644 --- a/futurerestore/futurerestore.hpp +++ b/futurerestore/futurerestore.hpp @@ -35,7 +35,6 @@ public: class futurerestore { struct idevicerestore_client_t* _client; bool _didInit = false; - bool _is32bit = false; vector _aptickets; vector_im4ms; int _foundnonce = -1; @@ -48,11 +47,13 @@ class futurerestore { plist_t _sepbuildmanifest = NULL; plist_t _basebandbuildmanifest = NULL; - const char *_basebandPath; + const char *_basebandPath = NULL;; + const char *_sepbuildmanifestPath = NULL; + const char *_basebandbuildmanifestPath = NULL; + public: futurerestore(); - futurerestore(bool is32bit); bool init(); int getDeviceMode(bool reRequest); uint64_t getDeviceEcid(); @@ -81,6 +82,9 @@ public: plist_t sepManifest(){return _sepbuildmanifest;}; plist_t basebandManifest(){return _basebandbuildmanifest;}; + const char *sepManifestPath(){return _sepbuildmanifestPath;}; + const char *basebandManifestPath(){return _basebandbuildmanifestPath;}; + bool is32bit(){return !is_image4_supported(_client);}; uint64_t getBasebandGoldCertIDFromDevice(); diff --git a/futurerestore/main.cpp b/futurerestore/main.cpp index 7f81a34b..1d561692 100644 --- a/futurerestore/main.cpp +++ b/futurerestore/main.cpp @@ -32,7 +32,6 @@ static struct option longopts[] = { { "latest-sep", no_argument, NULL, '0' }, { "latest-baseband", no_argument, NULL, '1' }, { "no-baseband", no_argument, NULL, '2' }, - { "is-32bit", no_argument, NULL, '3' }, { NULL, 0, NULL, 0 } }; @@ -41,7 +40,6 @@ static struct option longopts[] = { #define FLAG_LATEST_SEP 1 << 2 #define FLAG_LATEST_BASEBAND 1 << 3 #define FLAG_NO_BASEBAND 1 << 4 -#define FLAG_IS_32_BIT 1 << 5 void cmd_help(){ printf("Usage: futurerestore [OPTIONS] IPSW\n"); @@ -124,10 +122,6 @@ int main(int argc, const char * argv[]) { case '2': // long option: "no-baseband"; flags |= FLAG_NO_BASEBAND; break; - case '3': // long option: "is-32bit"; - flags |= FLAG_IS_32_BIT; - printf("[INFO] setting 32bit device flag\n"); - break; case 'd': // long option: "debug"; can be called as short option idevicerestore_debug = 1; break; @@ -153,7 +147,7 @@ int main(int argc, const char * argv[]) { return -5; } - futurerestore client(flags & FLAG_IS_32_BIT); + futurerestore client; if (!client.init()) reterror(-3,"can't init, no device found\n"); printf("futurerestore init done\n"); @@ -163,7 +157,7 @@ int main(int argc, const char * argv[]) { if (!((apticketPaths.size() && ipsw) && ((basebandPath && basebandManifestPath) || ((flags & FLAG_LATEST_BASEBAND) || (flags & FLAG_NO_BASEBAND))) - && ((sepPath && sepManifestPath) || (flags & (FLAG_LATEST_SEP|FLAG_IS_32_BIT))) )) { + && ((sepPath && sepManifestPath) || (flags & FLAG_LATEST_SEP) || client.is32bit()) )) { if (!(flags & FLAG_WAIT) || ipsw){ error("missing argument\n"); cmd_help(); @@ -181,13 +175,13 @@ int main(int argc, const char * argv[]) { if (flags & FLAG_LATEST_SEP){ info("user specified to use latest signed sep\n"); client.loadLatestSep(); - }else if (!(flags & FLAG_IS_32_BIT)){ + }else if (!client.is32bit()){ client.loadSep(sepPath); client.setSepManifestPath(sepManifestPath); } versVals.basebandMode = kBasebandModeWithoutBaseband; - if (!(flags & FLAG_IS_32_BIT) && !(isSepManifestSigned = isManifestSignedForDevice(sepManifestPath, &devVals, &versVals))){ + if (!client.is32bit() && !(isSepManifestSigned = isManifestSignedForDevice(client.sepManifestPath(), &devVals, &versVals))){ reterror(-3,"sep firmware isn't signed\n"); } @@ -216,7 +210,7 @@ int main(int argc, const char * argv[]) { if (!(devVals.bbgcid = client.getBasebandGoldCertIDFromDevice())){ printf("[WARNING] using tsschecker's fallback to get BasebandGoldCertID. This might result in invalid baseband signing status information\n"); } - if (!(isBasebandSigned = isManifestSignedForDevice(basebandManifestPath, &devVals, &versVals))) { + if (!(isBasebandSigned = isManifestSignedForDevice(client.basebandManifestPath(), &devVals, &versVals))) { reterror(-3,"baseband firmware isn't signed\n"); } }