Add -c --custom-latest option

This commit is contained in:
Cryptiiiic 2022-03-15 14:01:36 -07:00
parent 2ca5c6c738
commit fb05ac3f98
No known key found for this signature in database
GPG key ID: 6027B509EFE3A76B
4 changed files with 36 additions and 4 deletions

View file

@ -68,6 +68,7 @@ Usage: `futurerestore [OPTIONS] iPSW`
| ` -w ` | ` --wait ` | Keep rebooting until ApNonce matches APTicket (ApNonce collision, unreliable) |
| ` -d ` | ` --debug ` | Show all code, use to save a log for debug testing |
| ` -e ` | ` --exit-recovery ` | Exit recovery mode and quit |
| ` -c ` | ` --custom-latest VERSION ` | Specify custom latest version to use for SEP, Baseband and other FirmwareUpdater components |
| | ` --use-pwndfu ` | Restoring devices with Odysseus method. Device needs to be in pwned DFU mode already |
| | ` --no-ibss ` | Restoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder. |
| | ` --rdsk PATH ` | Set custom restore ramdisk for entering restoremode(requires use-pwndfu) |

View file

@ -114,6 +114,8 @@ futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, b
nocache = 1; //tsschecker nocache
_foundnonce = -1;
_useCustomLatest = false;
_customLatest = std::string("");
}
bool futurerestore::init() {
@ -1421,6 +1423,22 @@ char *futurerestore::getLatestManifest() {
if (--versionCnt == 0)
reterror("[TSSC] automatic selection of firmware couldn't find for non-beta versions\n");
}
if(_useCustomLatest) {
i = 0;
while(i < versionCnt) {
versVals.version = strdup(versions[i++]);
std::string version(versVals.version);
if(!std::equal(_customLatest.begin(), _customLatest.end(), version.begin())) {
free((char *) versVals.version);
} else {
i = -1;
break;
}
}
if(i != -1) {
reterror("[TSSC] failed to find custom version for device!\n");
}
}
info("[TSSC] selecting latest firmware version: %s\n", versVals.version);
if (bpos) *bpos = '\0';
if (versions) free(versions[versionCnt - 1]), free(versions);

View file

@ -68,7 +68,9 @@ class futurerestore {
jssytok_t *_firmwareTokens = nullptr;;
char *_latestManifest = nullptr;
char *_latestFirmwareUrl = nullptr;
bool _useCustomLatest = false;
std::string _customLatest;
plist_t _sepbuildmanifest = nullptr;
plist_t _basebandbuildmanifest = nullptr;
@ -132,6 +134,7 @@ public:
void loadSep(std::string sepPath);
void loadBaseband(std::string basebandPath);
void setCustomLatest(std::string version){_customLatest = version; _useCustomLatest = true;}
void setSepPath(std::string sepPath) {_sepPath = sepPath;}
void setSepManifestPath(std::string sepManifestPath) {_sepManifestPath = sepManifestPath;}
void setRamdiskPath(std::string ramdiskPath) {_ramdiskPath = ramdiskPath;}

View file

@ -39,6 +39,7 @@ static struct option longopts[] = {
{ "update", no_argument, nullptr, 'u' },
{ "debug", no_argument, nullptr, 'd' },
{ "exit-recovery", no_argument, nullptr, 'e' },
{ "custom-latest", required_argument, nullptr, 'c' },
{ "latest-sep", no_argument, nullptr, '0' },
{ "no-restore", no_argument, nullptr, 'z' },
{ "latest-baseband", no_argument, nullptr, '1' },
@ -52,7 +53,7 @@ static struct option longopts[] = {
{ "serial", no_argument, nullptr, '8' },
{ "boot-args", required_argument, nullptr, '9' },
{ "no-cache", no_argument, nullptr, 'a' },
{ "skip-blob", no_argument, nullptr, 'c' },
{ "skip-blob", no_argument, nullptr, 'f' },
#endif
{ nullptr, 0, nullptr, 0 }
};
@ -83,6 +84,7 @@ void cmd_help(){
printf(" -d, --debug\t\t\tShow all code, use to save a log for debug testing\n");
printf(" -e, --exit-recovery\t\tExit recovery mode and quit\n");
printf(" -z, --no-restore\t\tDo not restore and end right before NOR data is sent\n");
printf(" -c, --custom-latest VERSION\tSpecify custom latest version to use for SEP, Baseband and other FirmwareUpdater components\n");
#ifdef HAVE_LIBIPATCHER
printf("\nOptions for downgrading with Odysseus:\n");
@ -142,6 +144,7 @@ int main_r(int argc, const char * argv[]) {
const char *sepPath = nullptr;
const char *sepManifestPath = nullptr;
const char *bootargs = nullptr;
std::string customLatest;
const char *ramdiskPath = nullptr;
const char *kernelPath = nullptr;
const char *custom_nonce = nullptr;
@ -156,7 +159,7 @@ int main_r(int argc, const char * argv[]) {
return -1;
}
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez0123456789ac", longopts, &optindex)) > 0) {
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:c:wude0z123456789af", longopts, &optindex)) > 0) {
switch (opt) {
case 't': // long option: "apticket"; can be called as short option
apticketPaths.push_back(optarg);
@ -179,6 +182,9 @@ int main_r(int argc, const char * argv[]) {
case 'u': // long option: "update"; can be called as short option
flags |= FLAG_UPDATE;
break;
case 'c': // long option: "custom-latest";
customLatest = (optarg) ? std::string(optarg) : std::string("");
break;
case '0': // long option: "latest-sep";
flags |= FLAG_LATEST_SEP;
break;
@ -223,7 +229,7 @@ int main_r(int argc, const char * argv[]) {
case 'a': // long option: "no-cache";
flags |= FLAG_NO_CACHE;
break;
case 'c': // long option: "skip-blob";
case 'f': // long option: "skip-blob";
flags |= FLAG_SKIP_BLOB;
break;
#endif
@ -298,6 +304,10 @@ int main_r(int argc, const char * argv[]) {
client.loadAPTickets(apticketPaths);
}
if(!customLatest.empty()) {
client.setCustomLatest(customLatest);
}
if (!(
((!apticketPaths.empty() && ipsw)
&& ((basebandPath && basebandManifestPath) || ((flags & FLAG_LATEST_BASEBAND) || (flags & FLAG_NO_BASEBAND)))