added support for re-restoring to iOS 9 with noNonce bug from DFU mode

This commit is contained in:
tihmstar 2017-06-26 21:19:48 +02:00
parent 32932a396c
commit 373ddcdffe
2 changed files with 63 additions and 18 deletions

View file

@ -142,6 +142,8 @@ void futurerestore::putDeviceIntoRecovery(){
#endif
){
info("requesting to get into pwnRecovery later\n");
}else if (!_client->image4supported){
info("32bit device in DFU mode found, assuming user wants to use iOS9 re-restore bug. Not failing here\n");
}else{
reterror(-3, "unsupported devicemode, please put device in recovery mode or normal mode\n");
}
@ -173,10 +175,19 @@ void futurerestore::setAutoboot(bool val){
plist_t futurerestore::nonceMatchesApTickets(){
if (!_didInit) reterror(-1, "did not init\n");
if (getDeviceMode(true) != MODE_RECOVERY) reterror(-10, "Device not in recovery mode, can't check apnonce\n");
if (getDeviceMode(true) != MODE_RECOVERY){
if (getDeviceMode(false) != MODE_DFU || *_client->version != '9')
reterror(-10, "Device not in recovery mode, can't check apnonce\n");
else
_rerestoreiOS9 = (info("Detected iOS 9 re-restore, proceeding in DFU mode\n"),true);
}
unsigned char* realnonce;
int realNonceSize = 0;
if (_rerestoreiOS9) {
info("Skipping APNonce check\n");
}else{
recovery_get_ap_nonce(_client, &realnonce, &realNonceSize);
info("Got APNonce from device: ");
@ -185,6 +196,7 @@ plist_t futurerestore::nonceMatchesApTickets(){
info("%02x ", ((unsigned char *)realnonce)[i]);
}
info("\n");
}
vector<const char*>nonces;
@ -196,7 +208,13 @@ plist_t futurerestore::nonceMatchesApTickets(){
for (int i=0; i< _im4ms.size(); i++){
size_t ticketNonceSize = 0;
if (memcmp(realnonce, (unsigned const char*)getNonceFromSCAB(_im4ms[i], &ticketNonceSize), ticketNonceSize) == 0 &&
( ticketNonceSize == realNonceSize || (!ticketNonceSize && *_client->version == '9' && !strncmp(getiBootBuild(), "iBoot-2817", strlen("iBoot-2817"))) )
( (ticketNonceSize == realNonceSize && realNonceSize+ticketNonceSize > 0) ||
(!ticketNonceSize && *_client->version == '9' &&
(getDeviceMode(false) == MODE_DFU ||
( getDeviceMode(false) == MODE_RECOVERY && !strncmp(getiBootBuild(), "iBoot-2817", strlen("iBoot-2817")) )
)
)
)
)
//either nonce needs to match or using re-restore bug in iOS 9
return _aptickets[i];
@ -575,7 +593,7 @@ int futurerestore::doRestore(const char *ipsw){
printf("checking APTicket to be valid for this restore...\n");
//if we are in pwnDFU, just use first apticket. no need to check nonces
const char * im4m = (!_enterPwnRecoveryRequested) ? nonceMatchesIM4Ms() : _im4ms.at(0);
const char * im4m = (_enterPwnRecoveryRequested || _rerestoreiOS9) ? _im4ms.at(0) : nonceMatchesIM4Ms();
uint64_t deviceEcid = getDeviceEcid();
uint64_t im4mEcid = (_client->image4supported) ? getEcidFromIM4M(im4m) : getEcidFromSCAB(im4m);
@ -796,6 +814,27 @@ int futurerestore::doRestore(const char *ipsw){
}
}
if (_rerestoreiOS9) {
if (dfu_send_component(client, build_identity, "iBSS") < 0) {
error("ERROR: Unable to send iBSS to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
}
/* reconnect */
dfu_client_free(client);
sleep(2);
dfu_client_new(client);
/* send iBEC */
if (dfu_send_component(client, build_identity, "iBEC") < 0) {
error("ERROR: Unable to send iBEC to device\n");
irecv_close(client->dfu->client);
client->dfu->client = NULL;
return -1;
}
}else{
if ((client->build_major > 8)) {
if (!client->image4supported) {
/* send ApTicket */
@ -804,8 +843,13 @@ int futurerestore::doRestore(const char *ipsw){
}
}
}
}
if (!_enterPwnRecoveryRequested) {
if (_enterPwnRecoveryRequested) //if pwnrecovery send all components decrypted
client->recovery_custom_component_function = get_custom_component;
else if (!_rerestoreiOS9){
/* now we load the iBEC */
if (recovery_send_ibec(client, build_identity) < 0) {
reterror(-8,"ERROR: Unable to send iBEC\n");
@ -815,8 +859,8 @@ int futurerestore::doRestore(const char *ipsw){
/* this must be long enough to allow the device to run the iBEC */
/* FIXME: Probably better to detect if the device is back then */
sleep(7);
}else //if pwnrecovery send all components decrypted
client->recovery_custom_component_function = get_custom_component;
}
for (int i=0;getDeviceMode(true) != MODE_RECOVERY && i<40; i++) putchar('.'),usleep(USEC_PER_SEC*0.5);
putchar('\n');

View file

@ -60,6 +60,7 @@ class futurerestore {
const char *_basebandbuildmanifestPath = NULL;
bool _enterPwnRecoveryRequested = false;
bool _rerestoreiOS9 = false;
//methods
void enterPwnRecovery(plist_t build_identity);