mirror of
https://github.com/tihmstar/futurerestore.git
synced 2025-04-20 14:31:41 +00:00
Improve pwned restores, add set-nonce for pwned
This commit is contained in:
parent
db1dff1b1b
commit
b37542c91c
2
external/idevicerestore
vendored
2
external/idevicerestore
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 59ca01ebf4a9ed2e019cf5b28cc01707adc283fb
|
||||
Subproject commit 988bd03b5acd8692b23969a7e24b290abed75b5a
|
|
@ -106,7 +106,7 @@ extern "C"{
|
|||
}
|
||||
|
||||
#pragma mark futurerestore
|
||||
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, bool noRestore) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS), _noRestore(noRestore){
|
||||
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, bool cfwRamdisk, bool cfwKernel, bool setNonce, bool noRestore) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS), _cfwRamdisk(cfwRamdisk), _cfwKernel(cfwKernel), _setNonce(setNonce), _noRestore(noRestore){
|
||||
_client = idevicerestore_client_new();
|
||||
if (_client == NULL) throw std::string("could not create idevicerestore client\n");
|
||||
|
||||
|
@ -582,7 +582,8 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
|
||||
info("ApNonce pre-hax:\n");
|
||||
get_ap_nonce(_client, &_client->nonce, &_client->nonce_size);
|
||||
std::string generator = getGeneratorFromSHSH2(_client->tss);
|
||||
|
||||
std::string generator = (_setNonce && _custom_nonce != NULL) ? _custom_nonce : getGeneratorFromSHSH2(_client->tss);
|
||||
|
||||
if(memcmp(_client->nonce, nonceelem.payload(), _client->nonce_size) != 0) {
|
||||
info("ApNonce from device doesn't match IM4M nonce, applying hax...\n");
|
||||
|
@ -616,7 +617,7 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
printf("APnonce post-hax:\n");
|
||||
get_ap_nonce(_client, &_client->nonce, &_client->nonce_size);
|
||||
assure(!irecv_send_command(_client->recovery->client, "bgcolor 255 255 0"));
|
||||
retassure(memcmp(_client->nonce, nonceelem.payload(), _client->nonce_size) == 0, "ApNonce from device doesn't match IM4M nonce after applying ApNonce hax. Aborting!");
|
||||
retassure(_setNonce || memcmp(_client->nonce, nonceelem.payload(), _client->nonce_size) == 0, "ApNonce from device doesn't match IM4M nonce after applying ApNonce hax. Aborting!");
|
||||
} else {
|
||||
getDeviceMode(true);
|
||||
retassure(((dfu_client_new(_client) == IRECV_E_SUCCESS) || (mutex_unlock(&_client->device_event_mutex),0)), "Failed to connect to device in Recovery Mode!");
|
||||
|
@ -643,6 +644,12 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
retassure(!irecv_setenv(_client->recovery->client, "com.apple.System.boot-nonce", generator.c_str()), "failed to write generator to nvram");
|
||||
retassure(!irecv_saveenv(_client->recovery->client), "failed to save nvram");
|
||||
|
||||
if(_setNonce) {
|
||||
info("Successfully set nonce generator: %s, exiting recovery mode...\n", generator.c_str());
|
||||
exitRecovery();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
}
|
||||
#endif //HAVE_LIBIPATCHER
|
||||
|
@ -1947,6 +1954,40 @@ void futurerestore::loadVeridian(const char *veridianDGMPath, const char *veridi
|
|||
fclose(fveridianfwm);
|
||||
}
|
||||
|
||||
void futurerestore::loadRamdisk(const char *ramdiskPath){
|
||||
FILE *framdisk = NULL;
|
||||
retassure(framdisk = fopen(ramdiskPath, "rb"), "failed to read Ramdisk\n");
|
||||
|
||||
fseek(framdisk, 0, SEEK_END);
|
||||
_client->ramdiskdatasize = ftell(framdisk);
|
||||
fseek(framdisk, 0, SEEK_SET);
|
||||
|
||||
retassure(_client->ramdiskdata = (char*)malloc(_client->ramdiskdatasize), "failed to malloc memory for Ramdisk\n");
|
||||
|
||||
size_t freadRet=0;
|
||||
retassure((freadRet = fread(_client->ramdiskdata, 1, _client->ramdiskdatasize, framdisk)) == _client->ramdiskdatasize,
|
||||
"failed to load Ramdisk. size=%zu but fread returned %zu\n",_client->ramdiskdatasize,freadRet);
|
||||
|
||||
fclose(framdisk);
|
||||
}
|
||||
|
||||
void futurerestore::loadKernel(const char *loadKernel){
|
||||
FILE *fkernel = NULL;
|
||||
retassure(fkernel = fopen(loadKernel, "rb"), "failed to read Kernel\n");
|
||||
|
||||
fseek(fkernel, 0, SEEK_END);
|
||||
_client->kerneldatasize = ftell(fkernel);
|
||||
fseek(fkernel, 0, SEEK_SET);
|
||||
|
||||
retassure(_client->kerneldata = (char*)malloc(_client->kerneldatasize), "failed to malloc memory for Kernel\n");
|
||||
|
||||
size_t freadRet=0;
|
||||
retassure((freadRet = fread(_client->kerneldata, 1, _client->kerneldatasize, fkernel)) == _client->kerneldatasize,
|
||||
"failed to load Kernel. size=%zu but fread returned %zu\n",_client->kerneldatasize,freadRet);
|
||||
|
||||
fclose(fkernel);
|
||||
}
|
||||
|
||||
void futurerestore::loadSep(const char *sepPath){
|
||||
FILE *fsep = NULL;
|
||||
retassure(fsep = fopen(sepPath, "rb"), "failed to read SEP\n");
|
||||
|
@ -1972,6 +2013,21 @@ void futurerestore::setBasebandPath(const char *basebandPath){
|
|||
fclose(fbb);
|
||||
}
|
||||
|
||||
void futurerestore::setRamdiskPath(const char *ramdiskPath) {
|
||||
FILE *fbb = NULL;
|
||||
|
||||
retassure(fbb = fopen(ramdiskPath, "rb"), "failed to read ramdisk");
|
||||
_ramdiskPath = ramdiskPath;
|
||||
fclose(fbb);
|
||||
}
|
||||
void futurerestore::setKernelPath(const char *kernelPath) {
|
||||
FILE *fbb = NULL;
|
||||
|
||||
retassure(fbb = fopen(kernelPath, "rb"), "failed to read kernel");
|
||||
_kernelPath = kernelPath;
|
||||
fclose(fbb);
|
||||
}
|
||||
|
||||
#pragma mark static methods
|
||||
inline void futurerestore::saveStringToFile(const char *str, const char *path){
|
||||
FILE *f = NULL;
|
||||
|
|
|
@ -58,6 +58,9 @@ class futurerestore {
|
|||
bool _isUpdateInstall = false;
|
||||
bool _isPwnDfu = false;
|
||||
bool _noIBSS = false;
|
||||
bool _cfwRamdisk = false;
|
||||
bool _cfwKernel = false;
|
||||
bool _setNonce = false;
|
||||
bool _noRestore = false;
|
||||
|
||||
char *_firmwareJson = NULL;
|
||||
|
@ -77,6 +80,10 @@ class futurerestore {
|
|||
const char *_basebandPath = NULL;
|
||||
const char *_sepbuildmanifestPath = NULL;
|
||||
const char *_basebandbuildmanifestPath = NULL;
|
||||
const char *_ramdiskPath = NULL;
|
||||
const char *_kernelPath = NULL;
|
||||
|
||||
const char *_custom_nonce = NULL;
|
||||
|
||||
bool _enterPwnRecoveryRequested = false;
|
||||
bool _rerestoreiOS9 = false;
|
||||
|
@ -85,7 +92,7 @@ class futurerestore {
|
|||
void enterPwnRecovery2(plist_t build_identity, std::string bootargs = "");
|
||||
|
||||
public:
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool noRestore = false);
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool cfwRamdisk = false, bool cfwKernel = false, bool setNonce = false, bool noRestore = false);
|
||||
bool init();
|
||||
int getDeviceMode(bool reRequest);
|
||||
uint64_t getDeviceEcid();
|
||||
|
@ -119,8 +126,13 @@ public:
|
|||
void loadSE(const char *sePath);
|
||||
void loadSavage(const char *savagePath[6]);
|
||||
void loadVeridian(const char *veridianDGMPath, const char *veridianFWMPath);
|
||||
void loadRamdisk(const char *ramdiskPath);
|
||||
void loadKernel(const char *kernelPath);
|
||||
void loadSep(const char *sepPath);
|
||||
void setBasebandPath(const char *basebandPath);
|
||||
void setRamdiskPath(const char *ramdiskPath);
|
||||
void setKernelPath(const char *kernelPath);
|
||||
void setNonce(const char *custom_nonce){_custom_nonce = custom_nonce;};
|
||||
bool isUpdateInstall(){return _isUpdateInstall;};
|
||||
|
||||
plist_t sepManifest(){return _sepbuildmanifest;};
|
||||
|
|
|
@ -49,8 +49,10 @@ static struct option longopts[] = {
|
|||
{ "no-baseband", no_argument, NULL, '2' },
|
||||
#ifdef HAVE_LIBIPATCHER
|
||||
{ "use-pwndfu", no_argument, NULL, '3' },
|
||||
{ "just-boot", optional_argument, NULL, '4' },
|
||||
{ "no-ibss", no_argument, NULL, '5' },
|
||||
{ "no-ibss", no_argument, NULL, '4' },
|
||||
{ "rdsk", required_argument, NULL, '5' },
|
||||
{ "rkrn", required_argument, NULL, '6' },
|
||||
{ "set-nonce", optional_argument, NULL, '7' },
|
||||
#endif
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
@ -62,8 +64,10 @@ static struct option longopts[] = {
|
|||
#define FLAG_NO_BASEBAND 1 << 4
|
||||
#define FLAG_IS_PWN_DFU 1 << 5
|
||||
#define FLAG_NO_IBSS 1 << 6
|
||||
#define FLAG_NO_RESTORE_FR 1 << 7
|
||||
|
||||
#define FLAG_RESTORE_RAMDISK 1 << 7
|
||||
#define FLAG_RESTORE_KERNEL 1 << 8
|
||||
#define FLAG_SET_NONCE 1 << 9
|
||||
#define FLAG_NO_RESTORE_FR 1 << 10
|
||||
void cmd_help(){
|
||||
printf("Usage: futurerestore [OPTIONS] iPSW\n");
|
||||
printf("Allows restoring to non-matching firmware with custom SEP+baseband\n");
|
||||
|
@ -79,8 +83,10 @@ void cmd_help(){
|
|||
#ifdef HAVE_LIBIPATCHER
|
||||
printf("\nOptions for downgrading with Odysseus:\n");
|
||||
printf(" --use-pwndfu\t\tRestoring devices with Odysseus method. Device needs to be in pwned DFU mode already\n");
|
||||
printf(" --just-boot=\"-v\"\t\tTethered booting the device from pwned DFU mode. You can optionally set boot-args\n");
|
||||
printf(" --no-ibss\t\t\tRestoring devices with Odysseus method. For checkm8/iPwnder32 specifically, bootrom needs to be patched already with unless iPwnder.\n");
|
||||
printf(" --rdsk PATH\t\tSet custom restore ramdisk for entering restoremode(requires use-pwndfu)\n");
|
||||
printf(" --rkrn PATH\t\tSet custom restore kernelcache for entering restoremode(requires use-pwndfu)\n");
|
||||
printf(" --set-nonce NONCE\t\tSet custom nonce then exit recovery(requires use-pwndfu)\n");
|
||||
#endif
|
||||
|
||||
printf("\nOptions for SEP:\n");
|
||||
|
@ -131,7 +137,10 @@ int main_r(int argc, const char * argv[]) {
|
|||
const char *sepPath = NULL;
|
||||
const char *sepManifestPath = NULL;
|
||||
const char *bootargs = NULL;
|
||||
|
||||
const char *ramdiskPath = NULL;
|
||||
const char *kernelPath = NULL;
|
||||
const char *custom_nonce = NULL;
|
||||
|
||||
vector<const char*> apticketPaths;
|
||||
|
||||
t_devicevals devVals = {0};
|
||||
|
@ -142,7 +151,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez0123", longopts, &optindex)) > 0) {
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez01234567", longopts, &optindex)) > 0) {
|
||||
switch (opt) {
|
||||
case 't': // long option: "apticket"; can be called as short option
|
||||
apticketPaths.push_back(optarg);
|
||||
|
@ -178,13 +187,27 @@ int main_r(int argc, const char * argv[]) {
|
|||
case '3': // long option: "use-pwndfu";
|
||||
flags |= FLAG_IS_PWN_DFU;
|
||||
break;
|
||||
case '4': // long option: "just-boot";
|
||||
bootargs = (optarg) ? optarg : "";
|
||||
break;
|
||||
case '5': // long option: "no-ibss";
|
||||
case '4': // long option: "no-ibss";
|
||||
flags |= FLAG_NO_IBSS;
|
||||
break;
|
||||
break;
|
||||
case '5': // long option: "rdsk";
|
||||
flags |= FLAG_RESTORE_RAMDISK;
|
||||
ramdiskPath = optarg;
|
||||
break;
|
||||
case '6': // long option: "rkrn";
|
||||
flags |= FLAG_RESTORE_KERNEL;
|
||||
kernelPath = optarg;
|
||||
break;
|
||||
case '7': // long option: "set-nonce";
|
||||
flags |= FLAG_SET_NONCE;
|
||||
custom_nonce = (optarg) ? optarg : NULL;
|
||||
if(custom_nonce != NULL) {
|
||||
uint64_t gen;
|
||||
retassure(strlen(custom_nonce) == 16 || strlen(custom_nonce) == 18,"Incorrect nonce length!\n");
|
||||
sscanf(custom_nonce, "0x%16llx",&gen);
|
||||
retassure(gen, "failed to parse generator. Make sure it is in format 0x%16llx");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'e': // long option: "exit-recovery"; can be called as short option
|
||||
exitRecovery = true;
|
||||
|
@ -220,14 +243,22 @@ int main_r(int argc, const char * argv[]) {
|
|||
return -5;
|
||||
}
|
||||
|
||||
futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_NO_RESTORE_FR);
|
||||
futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_RESTORE_RAMDISK, flags & FLAG_RESTORE_KERNEL, flags & FLAG_SET_NONCE, flags & FLAG_NO_RESTORE_FR);
|
||||
retassure(client.init(),"can't init, no device found\n");
|
||||
|
||||
printf("futurerestore init done\n");
|
||||
retassure(!bootargs || (flags & FLAG_IS_PWN_DFU),"--just-boot requires --use-pwndfu\n");
|
||||
if(flags & FLAG_NO_IBSS)
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--no-ibss requires --use-pwndfu\n");
|
||||
|
||||
if(flags & FLAG_RESTORE_RAMDISK)
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--rdsk requires --use-pwndfu\n");
|
||||
if(flags & FLAG_RESTORE_KERNEL)
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--rkrn requires --use-pwndfu\n");
|
||||
if(flags & FLAG_SET_NONCE)
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--set-nonce requires --use-pwndfu\n");
|
||||
if(flags & FLAG_RESTORE_RAMDISK)
|
||||
retassure((flags & FLAG_RESTORE_KERNEL),"--rdsk requires --rkrn\n");
|
||||
|
||||
if (exitRecovery) {
|
||||
client.exitRecovery();
|
||||
info("Done\n");
|
||||
|
@ -260,7 +291,21 @@ int main_r(int argc, const char * argv[]) {
|
|||
}else{
|
||||
devVals.deviceModel = (char*)client.getDeviceModelNoCopy();
|
||||
devVals.deviceBoard = (char*)client.getDeviceBoardNoCopy();
|
||||
|
||||
|
||||
if(flags & FLAG_SET_NONCE) {
|
||||
client.setNonce(custom_nonce);
|
||||
}
|
||||
|
||||
if(flags & FLAG_RESTORE_RAMDISK) {
|
||||
client.setRamdiskPath(ramdiskPath);
|
||||
client.loadRamdisk(ramdiskPath);
|
||||
}
|
||||
|
||||
if(flags & FLAG_RESTORE_KERNEL) {
|
||||
client.setKernelPath(kernelPath);
|
||||
client.loadKernel(kernelPath);
|
||||
}
|
||||
|
||||
if (flags & FLAG_LATEST_SEP){
|
||||
info("user specified to use latest signed SEP\n");
|
||||
client.loadLatestSep();
|
||||
|
@ -316,10 +361,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
}
|
||||
|
||||
try {
|
||||
if (bootargs)
|
||||
client.doJustBoot(ipsw,bootargs);
|
||||
else
|
||||
client.doRestore(ipsw);
|
||||
client.doRestore(ipsw);
|
||||
printf("Done: restoring succeeded!\n");
|
||||
} catch (tihmstar::exception &e) {
|
||||
e.dump();
|
||||
|
|
Loading…
Reference in a new issue