fully supporting 32bit devices now

-autodetecting 32bit devices (removing --is-32bit parameter)
This commit is contained in:
tihmstar 2017-04-02 13:42:27 +02:00
parent 12066c924e
commit d8b69365ec
3 changed files with 37 additions and 35 deletions

View file

@ -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(){
vector<const char*>nonces;
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(){
vector<const char*>nonces;
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;
vector<const char*>nonces;
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<const char *> &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);

View file

@ -35,7 +35,6 @@ public:
class futurerestore {
struct idevicerestore_client_t* _client;
bool _didInit = false;
bool _is32bit = false;
vector<plist_t> _aptickets;
vector<char *>_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();

View file

@ -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");
}
}