added an option to specify multiple aptickets at once by using -t <FILE> parameter multiple times

This commit is contained in:
tihmstar 2016-12-29 13:27:35 +01:00
parent 22cc9a54d1
commit 4cf4a52c2d
3 changed files with 80 additions and 52 deletions

View file

@ -55,6 +55,7 @@ futurerestore::futurerestore(){
//tsschecker nocache
nocache = 1;
_foundnonce = -1;
}
bool futurerestore::init(){
@ -122,7 +123,7 @@ void futurerestore::setAutoboot(bool val){
}
}
bool futurerestore::nonceMatchesApTicket(){
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");
@ -130,22 +131,30 @@ bool futurerestore::nonceMatchesApTicket(){
int realNonceSize = 0;
recovery_get_ap_nonce(_client, &realnonce, &realNonceSize);
return memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4m,NULL), realNonceSize) == 0;
vector<const char*>nonces;
for (int i=0; i< _im4ms.size(); i++){
if (memcmp(realnonce, (unsigned const char*)getNonceFromIM4M(_im4ms[i],NULL), realNonceSize) == 0) return _aptickets[i];
}
return NULL;
}
void futurerestore::waitForNonce(const char *nonce, size_t nonceSize){
void futurerestore::waitForNonce(vector<const char *>nonces, size_t nonceSize){
if (!_didInit) reterror(-1, "did not init\n");
setAutoboot(false);
unsigned char* realnonce;
int realNonceSize = 0;
for (auto nonce : nonces){
info("waiting for nonce: ");
int i = 0;
for (i = 0; i < nonceSize; i++) {
info("%02x ", ((unsigned char *)nonce)[i]);
}
info("\n");
}
do {
if (realNonceSize){
@ -163,20 +172,30 @@ void futurerestore::waitForNonce(const char *nonce, size_t nonceSize){
info("%02x ", realnonce[i]);
}
info("\n");
} while (memcmp(realnonce, (unsigned const char*)nonce, realNonceSize) != 0);
for (int i=0; i<nonces.size(); i++){
if (memcmp(realnonce, (unsigned const char*)nonces[i], realNonceSize) == 0) _foundnonce = i;
}
} while (_foundnonce == -1);
info("Device has requested ApNonce now\n");
setAutoboot(true);
}
void futurerestore::waitForNonce(){
if (!_im4m) reterror(-1, "No IM4M loaded\n");
if (!_im4ms.size()) reterror(-1, "No IM4M loaded\n");
size_t nonceSize;
waitForNonce(getNonceFromIM4M(_im4m,&nonceSize),nonceSize);
vector<const char*>nonces;
for (auto im4m : _im4ms){
nonces.push_back(getNonceFromIM4M(im4m,&nonceSize));
}
waitForNonce(nonces,nonceSize);
}
void futurerestore::loadAPTicket(const char *apticketPath){
if (_apticket) plist_free(_apticket), _apticket = NULL;
void futurerestore::loadAPTickets(const vector<const char *> &apticketPaths){
for (auto apticketPath : apticketPaths){
FILE *f = fopen(apticketPath,"rb");
if (!f) reterror(-9, "failed to load apticket at %s\n",apticketPath);
fseek(f, 0, SEEK_END);
@ -184,23 +203,26 @@ void futurerestore::loadAPTicket(const char *apticketPath){
size_t fSize = ftell(f);
fseek(f, 0, SEEK_SET);
char *buf = (char*)malloc(fSize);
memset(buf, 0, fSize);
fread(buf, fSize, 1, f);
fclose(f);
plist_t apticket = NULL;
char *im4m = NULL;
if (memcmp(buf, "bplist00", 8) == 0)
plist_from_bin(buf, (uint32_t)fSize, &_apticket);
plist_from_bin(buf, (uint32_t)fSize, &apticket);
else
plist_from_xml(buf, (uint32_t)fSize, &_apticket);
plist_from_xml(buf, (uint32_t)fSize, &apticket);
safeFree(_im4m);
plist_t ticket = plist_dict_get_item(_apticket, "ApImg4Ticket");
plist_t ticket = plist_dict_get_item(apticket, "ApImg4Ticket");
uint64_t im4msize=0;
plist_get_data_val(ticket, &_im4m, &im4msize);
}
plist_get_data_val(ticket, &im4m, &im4msize);
void futurerestore::loadAPTicket(string apticketPath){
loadAPTicket(apticketPath.c_str());
_im4ms.push_back(im4m);
_aptickets.push_back(apticket);
}
}
int futurerestore::doRestore(const char *ipsw, bool noerase){
@ -231,7 +253,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){
}
info("Identified device as %s, %s\n", client->device->hardware_model, client->device->product_type);
if (!nonceMatchesApTicket()) reterror(-20, "Devicenonce does not match APTicket nonce\n");
if (!(client->tss = nonceMatchesApTickets())) reterror(-20, "Devicenonce does not match APTicket nonce\n");
// verify if ipsw file exists
@ -256,7 +278,6 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){
client->image4supported = is_image4_supported(client);
info("Device supports Image4: %s\n", (client->image4supported) ? "true" : "false");
client->tss = _apticket;
plist_dict_remove_item(client->tss, "BBTicket");
plist_dict_remove_item(client->tss, "BasebandFirmware");
@ -470,12 +491,16 @@ futurerestore::~futurerestore(){
normal_client_free(_client);
recovery_client_free(_client);
idevicerestore_client_free(_client);
safeFree(_im4m);
for (auto im4m : _im4ms){
safeFree(im4m);
}
safeFree(_firmwareJson);
safeFree(_firmwareTokens);
safeFree(__latestManifest);
safeFree(__latestFirmwareUrl);
safePlistFree(_apticket);
for (auto plist : _aptickets){
safePlistFree(plist);
}
}
void futurerestore::loadFirmwareTokens(){

View file

@ -12,6 +12,7 @@
#include "config.h"
#include <stdio.h>
#include <functional>
#include <vector>
#include "idevicerestore.h"
#include "jsmn.h"
@ -33,8 +34,9 @@ public:
class futurerestore {
struct idevicerestore_client_t* _client;
bool _didInit = false;
plist_t _apticket = NULL;
char *_im4m = NULL;
vector<plist_t> _aptickets;
vector<char *>_im4ms;
int _foundnonce = -1;
char *_firmwareJson = NULL;
jsmntok_t *_firmwareTokens = NULL;;
@ -55,11 +57,10 @@ public:
void putDeviceIntoRecovery();
void setAutoboot(bool val);
void waitForNonce();
void waitForNonce(const char *nonce, size_t nonceSize);
void loadAPTicket(const char *apticketPath);
void loadAPTicket(string apticketPath);
void waitForNonce(vector<const char *>nonces, size_t nonceSize);
void loadAPTickets(const vector<const char *> &apticketPaths);
bool nonceMatchesApTicket();
plist_t nonceMatchesApTickets();
void loadFirmwareTokens();
const char *getConnectedDeviceModel();

View file

@ -9,6 +9,7 @@
#include <iostream>
#include <getopt.h>
#include <string.h>
#include <vector>
#include "futurerestore.hpp"
#include "all_tsschecker.h"
#include "tsschecker.h"
@ -65,12 +66,13 @@ int main(int argc, const char * argv[]) {
int isBasebandSigned = 0;
const char *ipsw = NULL;
const char *apticketPath = NULL;
const char *basebandPath = NULL;
const char *basebandManifestPath = NULL;
const char *sepPath = NULL;
const char *sepManifestPath = NULL;
vector<const char*> apticketPaths;
t_devicevals devVals;
t_iosVersion versVals;
memset(&devVals, 0, sizeof(devVals));
@ -84,7 +86,7 @@ int main(int argc, const char * argv[]) {
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wud01", longopts, &optindex)) > 0) {
switch (opt) {
case 't': // long option: "apticket"; can be called as short option
apticketPath = optarg;
apticketPaths.push_back(optarg);
break;
case 'b': // long option: "baseband"; can be called as short option
basebandPath = optarg;
@ -128,9 +130,9 @@ int main(int argc, const char * argv[]) {
futurerestore client;
if (!client.init()) reterror(-3,"can't init, no device found\n");
if (apticketPath) client.loadAPTicket(apticketPath);
if (apticketPaths.size()) client.loadAPTickets(apticketPaths);
if (!((apticketPath && ipsw)
if (!((apticketPaths.size() && ipsw)
&& ((basebandPath && basebandManifestPath) || (flags & FLAG_LATEST_BASEBAND))
&& ((sepPath && sepManifestPath) || (flags & FLAG_LATEST_SEP)))) {
if (!(flags & FLAG_WAIT) || ipsw){