adding support for gzip compressed shsh files

This commit is contained in:
tihmstar 2017-04-03 12:45:47 +02:00
parent eeefc9ef41
commit ace8ae144f
3 changed files with 64 additions and 32 deletions

View file

@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include <zlib.h>
#include "futurerestore.hpp" #include "futurerestore.hpp"
#include "common.h" #include "common.h"
#include "all_tsschecker.h" #include "all_tsschecker.h"
@ -59,6 +60,10 @@
#define safePlistFree(buf) if (buf) plist_free(buf), buf = NULL #define safePlistFree(buf) if (buf) plist_free(buf), buf = NULL
futurerestore::futurerestore(){ futurerestore::futurerestore(){
futurerestore(false);
}
futurerestore::futurerestore(bool isUpdateInstall) : _isUpdateInstall(isUpdateInstall){
_client = idevicerestore_client_new(); _client = idevicerestore_client_new();
if (_client == NULL) throw std::string("could not create idevicerestore client\n"); if (_client == NULL) throw std::string("could not create idevicerestore client\n");
@ -243,34 +248,58 @@ void futurerestore::waitForNonce(){
waitForNonce(nonces,nonceSize); waitForNonce(nonces,nonceSize);
} }
void futurerestore::loadAPTickets(const vector<const char *> &apticketPaths){ void futurerestore::loadAPTickets(const vector<const char *> &apticketPaths){
for (auto apticketPath : 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);
size_t fSize = ftell(f);
fseek(f, 0, SEEK_SET);
char *buf = (char*)malloc(fSize+1);
memset(buf, 0, fSize+1);
size_t freadRet = 0;
if ((freadRet = fread(buf, 1, fSize, f)) != fSize){
reterror(-15,"fread=%zu but fSize=%zu",freadRet,fSize);
}
fclose(f);
plist_t apticket = NULL; plist_t apticket = NULL;
char *im4m = NULL; char *im4m = NULL;
if (memcmp(buf, "bplist00", 8) == 0) struct stat fst;
plist_from_bin(buf, (uint32_t)fSize, &apticket); if (stat(apticketPath, &fst))
else reterror(-9, "failed to load apticket at %s\n",apticketPath);
plist_from_xml(buf, (uint32_t)fSize, &apticket);
gzFile zf = gzopen(apticketPath, "rb");
if (zf) {
int blen = 0;
int readsize = 16384; //0x4000
int bufsize = readsize;
char* bin = (char*)malloc(bufsize);
char* p = bin;
do {
int bytes_read = gzread(zf, p, readsize);
if (bytes_read < 0)
reterror(-39, "Error reading gz compressed data\n");
blen += bytes_read;
if (bytes_read < readsize) {
if (gzeof(zf)) {
bufsize += bytes_read;
break;
}
}
bufsize += readsize;
bin = (char*)realloc(bin, bufsize);
p = bin + blen;
} while (!gzeof(zf));
gzclose(zf);
if (blen > 0) {
if (memcmp(bin, "bplist00", 8) == 0)
plist_from_bin(bin, blen, &apticket);
else
plist_from_xml(bin, blen, &apticket);
}
free(bin);
}
if (_isUpdateInstall) {
if(plist_t update = plist_dict_get_item(apticket, "updateInstall")){
plist_t cpy = plist_copy(update);
plist_free(apticket);
apticket = cpy;
}
}else if (plist_t noNonce = plist_dict_get_item(apticket, "noNonce")){
plist_t cpy = plist_copy(noNonce);
plist_free(apticket);
apticket = cpy;
}
plist_t ticket = plist_dict_get_item(apticket, (_client->image4supported) ? "ApImg4Ticket" : "APTicket"); plist_t ticket = plist_dict_get_item(apticket, (_client->image4supported) ? "ApImg4Ticket" : "APTicket");
uint64_t im4msize=0; uint64_t im4msize=0;
@ -303,7 +332,7 @@ uint64_t futurerestore::getBasebandGoldCertIDFromDevice(){
return val; return val;
} }
int futurerestore::doRestore(const char *ipsw, bool noerase){ int futurerestore::doRestore(const char *ipsw){
int err = 0; int err = 0;
//some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway. //some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway.
@ -317,7 +346,7 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){
plist_t sep_build_identity = NULL; plist_t sep_build_identity = NULL;
client->ipsw = strdup(ipsw); client->ipsw = strdup(ipsw);
if (!noerase) client->flags |= FLAG_ERASE; if (!_isUpdateInstall) client->flags |= FLAG_ERASE;
getDeviceMode(true); getDeviceMode(true);
info("Found device in %s mode\n", client->mode->string); info("Found device in %s mode\n", client->mode->string);
@ -357,10 +386,10 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){
plist_dict_remove_item(client->tss, "BBTicket"); plist_dict_remove_item(client->tss, "BBTicket");
plist_dict_remove_item(client->tss, "BasebandFirmware"); plist_dict_remove_item(client->tss, "BasebandFirmware");
if (!(build_identity = getBuildidentityWithBoardconfig(buildmanifest, client->device->hardware_model, noerase))) if (!(build_identity = getBuildidentityWithBoardconfig(buildmanifest, client->device->hardware_model, _isUpdateInstall)))
reterror(-5,"ERROR: Unable to find any build identities for IPSW\n"); reterror(-5,"ERROR: Unable to find any build identities for IPSW\n");
if (_client->image4supported && !(sep_build_identity = getBuildidentityWithBoardconfig(_sepbuildmanifest, client->device->hardware_model, noerase))) if (_client->image4supported && !(sep_build_identity = getBuildidentityWithBoardconfig(_sepbuildmanifest, client->device->hardware_model, _isUpdateInstall)))
reterror(-5,"ERROR: Unable to find any build identities for SEP\n"); reterror(-5,"ERROR: Unable to find any build identities for SEP\n");
//this is the buildidentity used for restore //this is the buildidentity used for restore
@ -444,11 +473,11 @@ int futurerestore::doRestore(const char *ipsw, bool noerase){
if (_basebandbuildmanifest){ if (_basebandbuildmanifest){
if (!(client->basebandBuildIdentity = getBuildidentityWithBoardconfig(_basebandbuildmanifest, client->device->hardware_model, noerase))){ if (!(client->basebandBuildIdentity = getBuildidentityWithBoardconfig(_basebandbuildmanifest, client->device->hardware_model, _isUpdateInstall))){
if (!(client->basebandBuildIdentity = getBuildidentityWithBoardconfig(_basebandbuildmanifest, client->device->hardware_model, !noerase))) if (!(client->basebandBuildIdentity = getBuildidentityWithBoardconfig(_basebandbuildmanifest, client->device->hardware_model, !_isUpdateInstall)))
reterror(-5,"ERROR: Unable to find any build identities for Baseband\n"); reterror(-5,"ERROR: Unable to find any build identities for Baseband\n");
else else
info("[WARNING] Unable to find Baseband buildidentities for restore type %s, using fallback %s\n", (noerase) ? "Update" : "Erase",(!noerase) ? "Update" : "Erase"); info("[WARNING] Unable to find Baseband buildidentities for restore type %s, using fallback %s\n", (_isUpdateInstall) ? "Update" : "Erase",(!_isUpdateInstall) ? "Update" : "Erase");
} }
client->bbfwtmp = (char*)_basebandPath; client->bbfwtmp = (char*)_basebandPath;

View file

@ -38,6 +38,7 @@ class futurerestore {
vector<plist_t> _aptickets; vector<plist_t> _aptickets;
vector<char *>_im4ms; vector<char *>_im4ms;
int _foundnonce = -1; int _foundnonce = -1;
bool _isUpdateInstall = false;
char *_firmwareJson = NULL; char *_firmwareJson = NULL;
jsmntok_t *_firmwareTokens = NULL;; jsmntok_t *_firmwareTokens = NULL;;
@ -54,6 +55,7 @@ class futurerestore {
public: public:
futurerestore(); futurerestore();
futurerestore(bool isUpdateInstall);
bool init(); bool init();
int getDeviceMode(bool reRequest); int getDeviceMode(bool reRequest);
uint64_t getDeviceEcid(); uint64_t getDeviceEcid();
@ -78,6 +80,7 @@ public:
void setBasebandManifestPath(const char *basebandManifestPath); void setBasebandManifestPath(const char *basebandManifestPath);
void loadSep(const char *sepPath); void loadSep(const char *sepPath);
void setBasebandPath(const char *basebandPath); void setBasebandPath(const char *basebandPath);
bool isUpdateInstall(){return _isUpdateInstall;};
plist_t sepManifest(){return _sepbuildmanifest;}; plist_t sepManifest(){return _sepbuildmanifest;};
@ -89,7 +92,7 @@ public:
uint64_t getBasebandGoldCertIDFromDevice(); uint64_t getBasebandGoldCertIDFromDevice();
int doRestore(const char *ipsw, bool noerase); int doRestore(const char *ipsw);
~futurerestore(); ~futurerestore();

View file

@ -146,7 +146,7 @@ int main(int argc, const char * argv[]) {
return -5; return -5;
} }
futurerestore client; futurerestore client(flags & FLAG_UPDATE);
if (!client.init()) reterror(-3,"can't init, no device found\n"); if (!client.init()) reterror(-3,"can't init, no device found\n");
printf("futurerestore init done\n"); printf("futurerestore init done\n");
@ -226,7 +226,7 @@ int main(int argc, const char * argv[]) {
} }
try { try {
res = client.doRestore(ipsw, flags & FLAG_UPDATE); res = client.doRestore(ipsw);
} catch (int error) { } catch (int error) {
if (error == -20) error("maybe you forgot -w ?\n"); if (error == -20) error("maybe you forgot -w ?\n");
err = error; err = error;