mirror of
https://github.com/tihmstar/futurerestore.git
synced 2025-04-20 14:31:41 +00:00
Enable no-ibss, fix 32 restores
* disable set-nonce on 32bit
This commit is contained in:
parent
3e915baf1c
commit
96c0a02229
|
@ -74,6 +74,8 @@ Usage: `futurerestore [OPTIONS] iPSW`
|
|||
| | ` --rkrn PATH ` | Set custom restore kernelcache for entering restoremode(requires use-pwndfu) |
|
||||
| | ` --set-nonce ` | Set custom nonce from your blob then exit recovery(requires use-pwndfu) |
|
||||
| | ` --set-nonce=0xNONCE ` | Set custom nonce then exit recovery(requires use-pwndfu) |
|
||||
| | ` --serial ` | Enable serial during boot(requires serial cable and use-pwndfu) |
|
||||
| | ` --boot-args "BOOTARGS" ` | Set custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu) |
|
||||
| | ` --latest-sep ` | Use latest signed SEP instead of manually specifying one |
|
||||
| ` -s ` | ` --sep PATH ` | Manually specify SEP to be flashed |
|
||||
| ` -m ` | ` --sep-manifest PATH ` | BuildManifest for requesting SEP ticket |
|
||||
|
|
|
@ -106,7 +106,7 @@ extern "C"{
|
|||
}
|
||||
|
||||
#pragma mark futurerestore
|
||||
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){
|
||||
futurerestore::futurerestore(bool isUpdateInstall, bool isPwnDfu, bool noIBSS, bool setNonce, bool serial, bool noRestore) : _isUpdateInstall(isUpdateInstall), _isPwnDfu(isPwnDfu), _noIBSS(noIBSS), _setNonce(setNonce), _serial(serial), _noRestore(noRestore){
|
||||
_client = idevicerestore_client_new();
|
||||
if (_client == NULL) throw std::string("could not create idevicerestore client\n");
|
||||
|
||||
|
@ -462,14 +462,24 @@ pair<ptr_smart<char*>, size_t> getIPSWComponent(struct idevicerestore_client_t*
|
|||
return {(char*)component_data,component_size};
|
||||
}
|
||||
|
||||
void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
||||
void futurerestore::enterPwnRecovery(plist_t build_identity, std::string bootargs){
|
||||
#ifndef HAVE_LIBIPATCHER
|
||||
reterror("compiled without libipatcher");
|
||||
#else
|
||||
bootargs = "rd=md0 -restore -progress nand-enable-reformat=0x1 -v serial=0x3 debug=0x14e keepsyms=0x1 amfi=0xff amfi_unrestrict_task_for_pid=0x0 amfi_allow_any_signature=0x1 amfi_get_out_of_my_way=0x1 cs_enforcement_disable=0x1";
|
||||
idevicerestore_mode_t *mode = 0;
|
||||
libipatcher::fw_key iBSSKeys;
|
||||
libipatcher::fw_key iBECKeys;
|
||||
pair<ptr_smart<char*>, size_t> iBSS;
|
||||
pair<ptr_smart<char*>, size_t> iBEC;
|
||||
FILE *ibss = NULL;
|
||||
FILE *ibec = NULL;
|
||||
int rv;
|
||||
bool cache1 = false;
|
||||
bool cache2 = false;
|
||||
std::string img3_end = ".patched.img3";
|
||||
std::string img4_end = ".patched.img4";
|
||||
std::string ibss_name = FUTURERESTORE_TMP_PATH"/ibss.";
|
||||
std::string ibec_name = FUTURERESTORE_TMP_PATH"/ibec.";
|
||||
|
||||
/* Assure device is in dfu */
|
||||
irecv_device_event_subscribe(&_client->irecv_e_ctx, irecv_event_cb, _client);
|
||||
|
@ -483,6 +493,43 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
mutex_unlock(&_client->device_event_mutex);
|
||||
info("Device found in DFU Mode.\n");
|
||||
|
||||
ibss_name.append(getDeviceBoardNoCopy());
|
||||
ibec_name.append(getDeviceBoardNoCopy());
|
||||
ibss_name.append(".");
|
||||
ibec_name.append(".");
|
||||
ibss_name.append(_client->build);
|
||||
ibec_name.append(_client->build);
|
||||
if(_client->image4supported) {
|
||||
ibss_name.append(img4_end);
|
||||
ibec_name.append(img4_end);
|
||||
} else {
|
||||
ibss_name.append(img3_end);
|
||||
ibec_name.append(img3_end);
|
||||
}
|
||||
|
||||
ibss = fopen(ibss_name.c_str(), "rb");
|
||||
if(ibss) {
|
||||
fseek(ibss, 0, SEEK_END);
|
||||
iBSS.second = ftell(ibss);
|
||||
fseek(ibss, 0, SEEK_SET);
|
||||
retassure(iBSS.first = (char*)malloc(iBSS.second), "failed to malloc memory for Rose\n");
|
||||
size_t freadRet=0;
|
||||
retassure((freadRet = fread((char*)iBSS.first, 1, iBSS.second, ibss)) == iBSS.second, "failed to load iBSS. size=%zu but fread returned %zu\n",iBSS.second,freadRet);
|
||||
fclose(ibss);
|
||||
cache1 = true;
|
||||
}
|
||||
ibec = fopen(ibec_name.c_str(), "rb");
|
||||
if(ibec) {
|
||||
fseek(ibec, 0, SEEK_END);
|
||||
iBEC.second = ftell(ibec);
|
||||
fseek(ibec, 0, SEEK_SET);
|
||||
retassure(iBEC.first = (char*)malloc(iBEC.second), "failed to malloc memory for Rose\n");
|
||||
size_t freadRet=0;
|
||||
retassure((freadRet = fread((char*)iBEC.first, 1, iBEC.second, ibec)) == iBEC.second, "failed to load iBEC. size=%zu but fread returned %zu\n",iBEC.second,freadRet);
|
||||
fclose(ibec);
|
||||
cache2 = true;
|
||||
}
|
||||
|
||||
/* Patch bootloaders */
|
||||
try {
|
||||
std::string board = getDeviceBoardNoCopy();
|
||||
|
@ -498,48 +545,52 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
reterror("getting keys failed with error: %d (%s). Are keys publicly available?",e.code(),e.what());
|
||||
}
|
||||
|
||||
info("Patching iBSS\n");
|
||||
auto iBSS = getIPSWComponent(_client, build_identity, "iBSS");
|
||||
iBSS = move(libipatcher::patchiBSS((char*)iBSS.first, iBSS.second, iBSSKeys));
|
||||
|
||||
info("Patching iBEC\n");
|
||||
auto iBEC = getIPSWComponent(_client, build_identity, "iBEC");
|
||||
iBEC = move(libipatcher::patchiBEC((char*)iBEC.first, iBEC.second, iBECKeys, bootargs));
|
||||
if(!iBSS.first){
|
||||
info("Patching iBSS\n");
|
||||
iBSS = getIPSWComponent(_client, build_identity, "iBSS");
|
||||
iBSS = move(libipatcher::patchiBSS((char*)iBSS.first, iBSS.second, iBSSKeys));
|
||||
}
|
||||
if(!iBEC.first) {
|
||||
info("Patching iBEC\n");
|
||||
iBEC = getIPSWComponent(_client, build_identity, "iBEC");
|
||||
iBEC = move(libipatcher::patchiBEC((char*)iBEC.first, iBEC.second, iBECKeys, bootargs));
|
||||
}
|
||||
|
||||
if (_client->image4supported) {
|
||||
/* if this is 64-bit, we need to back IM4P to IMG4
|
||||
also due to the nature of iBoot64Patchers sigpatches we need to stich a valid signed im4m to it (but nonce is ignored) */
|
||||
info("Repacking patched bootloaders as IMG4\n");
|
||||
iBSS = move(libipatcher::packIM4PToIMG4(iBSS.first, iBSS.second, _im4ms[0].first, _im4ms[0].second));
|
||||
iBEC = move(libipatcher::packIM4PToIMG4(iBEC.first, iBEC.second, _im4ms[0].first, _im4ms[0].second));
|
||||
if(!cache1)
|
||||
iBSS = move(libipatcher::packIM4PToIMG4(iBSS.first, iBSS.second, _im4ms[0].first, _im4ms[0].second));
|
||||
if(!cache2)
|
||||
iBEC = move(libipatcher::packIM4PToIMG4(iBEC.first, iBEC.second, _im4ms[0].first, _im4ms[0].second));
|
||||
}
|
||||
|
||||
FILE *ibss = NULL;
|
||||
FILE *ibec = NULL;
|
||||
int rv;
|
||||
retassure(ibss = fopen(FUTURERESTORE_TMP_PATH"/ibss.patched.img4", "wb"), "can't save patched ibss at %s\n", FUTURERESTORE_TMP_PATH"/ibss.patched.img4");
|
||||
retassure(rv = fwrite(iBSS.first, iBSS.second, 1, ibss), "can't save patched ibss at %s\n", FUTURERESTORE_TMP_PATH"/ibss.patched.img4");
|
||||
retassure(ibec = fopen(FUTURERESTORE_TMP_PATH"/ibec.patched.img4", "wb"), "can't save patched ibec at %s\n", FUTURERESTORE_TMP_PATH"/ibec.patched.img4");
|
||||
retassure(rv = fwrite(iBEC.first, iBEC.second, 1, ibec), "can't save patched ibec at %s\n", FUTURERESTORE_TMP_PATH"/ibec.patched.img4");
|
||||
retassure(ibss = fopen(ibss_name.c_str(), "wb"), "can't save patched ibss at %s\n", ibss_name.c_str());
|
||||
retassure(rv = fwrite(iBSS.first, iBSS.second, 1, ibss), "can't save patched ibss at %s\n", ibss_name.c_str());
|
||||
retassure(ibec = fopen(ibec_name.c_str(), "wb"), "can't save patched ibec at %s\n", ibec_name.c_str());
|
||||
retassure(rv = fwrite(iBEC.first, iBEC.second, 1, ibec), "can't save patched ibec at %s\n", ibec_name.c_str());
|
||||
fflush(ibss);
|
||||
fclose(ibss);
|
||||
fflush(ibec);
|
||||
fclose(ibec);
|
||||
|
||||
/* Send and boot bootloaders */
|
||||
irecv_error_t err = IRECV_E_UNKNOWN_ERROR;
|
||||
if(!_noIBSS) {
|
||||
/* send iBSS */
|
||||
info("Sending %s (%lu bytes)...\n", "iBSS", iBSS.second);
|
||||
mutex_lock(&_client->device_event_mutex);
|
||||
err = irecv_send_buffer(_client->dfu->client, (unsigned char *) (char *) iBSS.first,
|
||||
(unsigned long) iBSS.second, 1);
|
||||
retassure(err == IRECV_E_SUCCESS, "ERROR: Unable to send %s component: %s\n", "iBSS", irecv_strerror(err));
|
||||
|
||||
// if(_noIBSS) goto label;
|
||||
|
||||
/* send iBSS */
|
||||
info("Sending %s (%lu bytes)...\n", "iBSS", iBSS.second);
|
||||
mutex_lock(&_client->device_event_mutex);
|
||||
irecv_error_t err = irecv_send_buffer(_client->dfu->client, (unsigned char*)(char*)iBSS.first, (unsigned long)iBSS.second, 1);
|
||||
retassure(err == IRECV_E_SUCCESS,"ERROR: Unable to send %s component: %s\n", "iBSS", irecv_strerror(err));
|
||||
|
||||
info("Booting iBSS, waiting for device to disconnect...\n");
|
||||
cond_wait_timeout(&_client->device_event_cond, &_client->device_event_mutex, 10000);
|
||||
info("Booting iBSS, waiting for device to disconnect...\n");
|
||||
cond_wait_timeout(&_client->device_event_cond, &_client->device_event_mutex, 10000);
|
||||
|
||||
retassure(((_client->mode == MODE_UNKNOWN) || (mutex_unlock(&_client->device_event_mutex),0)), "Device did not disconnect. Possibly invalid iBSS. Reset device and try again");
|
||||
info("Booting iBSS, waiting for device to reconnect...\n");
|
||||
}
|
||||
bool dfu = false;
|
||||
if((_client->device->chip_id >= 0x7000 && _client->device->chip_id <= 0x8004) || (_client->device->chip_id >= 0x8900 && _client->device->chip_id <= 0x8965)) {
|
||||
cond_wait_timeout(&_client->device_event_cond, &_client->device_event_mutex, 10000);
|
||||
|
@ -564,7 +615,6 @@ void futurerestore::enterPwnRecovery(plist_t build_identity, string bootargs){
|
|||
mutex_unlock(&_client->device_event_mutex);
|
||||
getDeviceMode(true);
|
||||
retassure(((recovery_client_new(_client) == IRECV_E_SUCCESS) || (mutex_unlock(&_client->device_event_mutex),0)), "Failed to connect to device in Recovery Mode!");
|
||||
mutex_lock(&_client->device_event_mutex);
|
||||
}
|
||||
} else if((_client->device->chip_id >= 0x8006 && _client->device->chip_id <= 0x8030) || (_client->device->chip_id >= 0x8101 && _client->device->chip_id <= 0x8301)) {
|
||||
dfu = true;
|
||||
|
@ -1347,7 +1397,16 @@ void futurerestore::doRestore(const char *ipsw){
|
|||
retassure((getDeviceMode(true) == _MODE_DFU) || (getDeviceMode(false) == _MODE_RECOVERY && _noIBSS), "unexpected device mode\n");
|
||||
irecv_device_event_unsubscribe(client->irecv_e_ctx);
|
||||
client->idevice_e_ctx = NULL;
|
||||
enterPwnRecovery(build_identity);
|
||||
std::string bootargs = "";
|
||||
if(_boot_args != NULL) {
|
||||
bootargs = _boot_args;
|
||||
} else {
|
||||
if (_serial) {
|
||||
bootargs.append("serial=0x3 ");
|
||||
}
|
||||
bootargs.append("rd=md0 -restore -progress nand-enable-reformat=0x1 -v debug=0x14e keepsyms=0x1 amfi=0xff amfi_unrestrict_task_for_pid=0x0 amfi_allow_any_signature=0x1 amfi_get_out_of_my_way=0x1 cs_enforcement_disable=0x1");
|
||||
}
|
||||
enterPwnRecovery(build_identity, bootargs);
|
||||
irecv_device_event_unsubscribe(_client->irecv_e_ctx);
|
||||
_client->idevice_e_ctx = NULL;
|
||||
irecv_device_event_subscribe(&client->irecv_e_ctx, irecv_event_cb, _client);
|
||||
|
|
|
@ -58,9 +58,8 @@ class futurerestore {
|
|||
bool _isUpdateInstall = false;
|
||||
bool _isPwnDfu = false;
|
||||
bool _noIBSS = false;
|
||||
bool _cfwRamdisk = false;
|
||||
bool _cfwKernel = false;
|
||||
bool _setNonce = false;
|
||||
bool _serial = false;
|
||||
bool _noRestore = false;
|
||||
|
||||
char *_firmwareJson = NULL;
|
||||
|
@ -84,15 +83,16 @@ class futurerestore {
|
|||
const char *_kernelPath = NULL;
|
||||
|
||||
const char *_custom_nonce = NULL;
|
||||
const char *_boot_args = NULL;
|
||||
|
||||
bool _enterPwnRecoveryRequested = false;
|
||||
bool _rerestoreiOS9 = false;
|
||||
//methods
|
||||
void enterPwnRecovery(plist_t build_identity, std::string bootargs = "");
|
||||
void enterPwnRecovery(plist_t build_identity, std::string bootargs);
|
||||
void enterPwnRecovery2(plist_t build_identity, std::string bootargs = "");
|
||||
|
||||
public:
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool cfwRamdisk = false, bool cfwKernel = false, bool setNonce = false, bool noRestore = false);
|
||||
futurerestore(bool isUpdateInstall = false, bool isPwnDfu = false, bool noIBSS = false, bool setNonce = false, bool serial = false, bool noRestore = false);
|
||||
bool init();
|
||||
int getDeviceMode(bool reRequest);
|
||||
uint64_t getDeviceEcid();
|
||||
|
@ -133,6 +133,7 @@ public:
|
|||
void setRamdiskPath(const char *ramdiskPath);
|
||||
void setKernelPath(const char *kernelPath);
|
||||
void setNonce(const char *custom_nonce){_custom_nonce = custom_nonce;};
|
||||
void setBootArgs(const char *boot_args){_boot_args = boot_args;};
|
||||
bool isUpdateInstall(){return _isUpdateInstall;};
|
||||
|
||||
plist_t sepManifest(){return _sepbuildmanifest;};
|
||||
|
|
|
@ -34,27 +34,29 @@ extern "C"{
|
|||
#endif
|
||||
|
||||
static struct option longopts[] = {
|
||||
{ "apticket", required_argument, NULL, 't' },
|
||||
{ "baseband", required_argument, NULL, 'b' },
|
||||
{ "baseband-manifest", required_argument, NULL, 'p' },
|
||||
{ "sep", required_argument, NULL, 's' },
|
||||
{ "sep-manifest", required_argument, NULL, 'm' },
|
||||
{ "wait", no_argument, NULL, 'w' },
|
||||
{ "update", no_argument, NULL, 'u' },
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "exit-recovery", no_argument, NULL, 'e' },
|
||||
{ "latest-sep", no_argument, NULL, '0' },
|
||||
{ "no-restore", no_argument, NULL, 'z' },
|
||||
{ "latest-baseband", no_argument, NULL, '1' },
|
||||
{ "no-baseband", no_argument, NULL, '2' },
|
||||
{ "apticket", required_argument, NULL, 't' },
|
||||
{ "baseband", required_argument, NULL, 'b' },
|
||||
{ "baseband-manifest", required_argument, NULL, 'p' },
|
||||
{ "sep", required_argument, NULL, 's' },
|
||||
{ "sep-manifest", required_argument, NULL, 'm' },
|
||||
{ "wait", no_argument, NULL, 'w' },
|
||||
{ "update", no_argument, NULL, 'u' },
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "exit-recovery", no_argument, NULL, 'e' },
|
||||
{ "latest-sep", no_argument, NULL, '0' },
|
||||
{ "no-restore", no_argument, NULL, 'z' },
|
||||
{ "latest-baseband", no_argument, NULL, '1' },
|
||||
{ "no-baseband", no_argument, NULL, '2' },
|
||||
#ifdef HAVE_LIBIPATCHER
|
||||
{ "use-pwndfu", no_argument, NULL, '3' },
|
||||
{ "no-ibss", no_argument, NULL, '4' },
|
||||
{ "rdsk", required_argument, NULL, '5' },
|
||||
{ "rkrn", required_argument, NULL, '6' },
|
||||
{ "set-nonce", optional_argument, NULL, '7' },
|
||||
{ "use-pwndfu", no_argument, NULL, '3' },
|
||||
{ "no-ibss", no_argument, NULL, '4' },
|
||||
{ "rdsk", required_argument, NULL, '5' },
|
||||
{ "rkrn", required_argument, NULL, '6' },
|
||||
{ "set-nonce", optional_argument, NULL, '7' },
|
||||
{ "serial", no_argument, NULL, '8' },
|
||||
{ "boot-args", required_argument, NULL, '9' },
|
||||
#endif
|
||||
{ NULL, 0, NULL, 0 }
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
#define FLAG_WAIT 1 << 0
|
||||
|
@ -67,7 +69,9 @@ static struct option longopts[] = {
|
|||
#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
|
||||
#define FLAG_SERIAL 1 << 10
|
||||
#define FLAG_BOOT_ARGS 1 << 11
|
||||
#define FLAG_NO_RESTORE_FR 1 << 12
|
||||
void cmd_help(){
|
||||
printf("Usage: futurerestore [OPTIONS] iPSW\n");
|
||||
printf("Allows restoring to non-matching firmware with custom SEP+baseband\n");
|
||||
|
@ -79,7 +83,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");
|
||||
|
||||
|
||||
#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");
|
||||
|
@ -88,13 +92,15 @@ void cmd_help(){
|
|||
printf(" --rkrn PATH\t\tSet custom restore kernelcache for entering restoremode(requires use-pwndfu)\n");
|
||||
printf(" --set-nonce\t\tSet custom nonce from your blob then exit recovery(requires use-pwndfu)\n");
|
||||
printf(" --set-nonce=0xNONCE\tSet custom nonce then exit recovery(requires use-pwndfu)\n");
|
||||
printf(" --serial\t\t\tEnable serial during boot(requires serial cable and use-pwndfu)\n");
|
||||
printf(" --boot-args\t\tSet custom restore boot-args(PROCEED WITH CAUTION)(requires use-pwndfu)\n");
|
||||
#endif
|
||||
|
||||
|
||||
printf("\nOptions for SEP:\n");
|
||||
printf(" --latest-sep\t\tUse latest signed SEP instead of manually specifying one\n");
|
||||
printf(" -s, --sep PATH\t\tSEP to be flashed\n");
|
||||
printf(" -m, --sep-manifest PATH\tBuildManifest for requesting SEP ticket\n");
|
||||
|
||||
|
||||
printf("\nOptions for baseband:\n");
|
||||
printf(" --latest-baseband\t\tUse latest signed baseband instead of manually specifying one\n");
|
||||
printf(" -b, --baseband PATH\t\tBaseband to be flashed\n");
|
||||
|
@ -128,10 +134,10 @@ int main_r(int argc, const char * argv[]) {
|
|||
long flags = 0;
|
||||
bool exitRecovery = false;
|
||||
bool noRestore = false;
|
||||
|
||||
|
||||
int isSepManifestSigned = 0;
|
||||
int isBasebandSigned = 0;
|
||||
|
||||
|
||||
const char *ipsw = NULL;
|
||||
const char *basebandPath = NULL;
|
||||
const char *basebandManifestPath = NULL;
|
||||
|
@ -143,16 +149,16 @@ int main_r(int argc, const char * argv[]) {
|
|||
const char *custom_nonce = NULL;
|
||||
|
||||
vector<const char*> apticketPaths;
|
||||
|
||||
|
||||
t_devicevals devVals = {0};
|
||||
t_iosVersion versVals = {0};
|
||||
|
||||
|
||||
if (argc == 1){
|
||||
cmd_help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez01234567", longopts, &optindex)) > 0) {
|
||||
while ((opt = getopt_long(argc, (char* const *)argv, "ht:b:p:s:m:wudez0123456789", longopts, &optindex)) > 0) {
|
||||
switch (opt) {
|
||||
case 't': // long option: "apticket"; can be called as short option
|
||||
apticketPaths.push_back(optarg);
|
||||
|
@ -209,6 +215,13 @@ int main_r(int argc, const char * argv[]) {
|
|||
retassure(gen, "failed to parse generator. Make sure it is in format 0x%16llx");
|
||||
}
|
||||
break;
|
||||
case '8': // long option: "serial";
|
||||
flags |= FLAG_SERIAL;
|
||||
break;
|
||||
case '9': // long option: "boot-args";
|
||||
flags |= FLAG_BOOT_ARGS;
|
||||
bootargs = (optarg) ? optarg : NULL;
|
||||
break;
|
||||
#endif
|
||||
case 'e': // long option: "exit-recovery"; can be called as short option
|
||||
exitRecovery = true;
|
||||
|
@ -224,11 +237,11 @@ int main_r(int argc, const char * argv[]) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (argc-optind == 1) {
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
|
||||
ipsw = argv[0];
|
||||
}else if (argc == optind && flags & FLAG_WAIT) {
|
||||
info("User requested to only wait for ApNonce to match, but not for actually restoring\n");
|
||||
|
@ -243,12 +256,11 @@ 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_RESTORE_RAMDISK, flags & FLAG_RESTORE_KERNEL, flags & FLAG_SET_NONCE, flags & FLAG_NO_RESTORE_FR);
|
||||
|
||||
futurerestore client(flags & FLAG_UPDATE, flags & FLAG_IS_PWN_DFU, flags & FLAG_NO_IBSS, flags & FLAG_SET_NONCE, flags & FLAG_SERIAL, 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)
|
||||
|
@ -257,25 +269,33 @@ int main_r(int argc, const char * argv[]) {
|
|||
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_SET_NONCE && client.is32bit())
|
||||
error("--set-nonce not supported on 32bit devices.\n");
|
||||
if(flags & FLAG_RESTORE_RAMDISK)
|
||||
retassure((flags & FLAG_RESTORE_KERNEL),"--rdsk requires --rkrn\n");
|
||||
if(flags & FLAG_SERIAL) {
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--serial requires --use-pwndfu\n");
|
||||
retassure(!(flags & FLAG_BOOT_ARGS),"--serial conflicts with --boot-args\n");
|
||||
}
|
||||
if(flags & FLAG_BOOT_ARGS)
|
||||
retassure((flags & FLAG_IS_PWN_DFU),"--boot-args requires --use-pwndfu\n");
|
||||
|
||||
if (exitRecovery) {
|
||||
client.exitRecovery();
|
||||
info("Done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if (apticketPaths.size()) client.loadAPTickets(apticketPaths);
|
||||
|
||||
|
||||
if (!(
|
||||
((apticketPaths.size() && ipsw)
|
||||
&& ((basebandPath && basebandManifestPath) || ((flags & FLAG_LATEST_BASEBAND) || (flags & FLAG_NO_BASEBAND)))
|
||||
&& ((sepPath && sepManifestPath) || (flags & FLAG_LATEST_SEP) || client.is32bit())
|
||||
) || (ipsw && bootargs && (flags & FLAG_IS_PWN_DFU))
|
||||
)) {
|
||||
|
||||
((apticketPaths.size() && ipsw)
|
||||
&& ((basebandPath && basebandManifestPath) || ((flags & FLAG_LATEST_BASEBAND) || (flags & FLAG_NO_BASEBAND)))
|
||||
&& ((sepPath && sepManifestPath) || (flags & FLAG_LATEST_SEP) || client.is32bit())
|
||||
) || (ipsw && (flags & FLAG_IS_PWN_DFU))
|
||||
)) {
|
||||
|
||||
if (!(flags & FLAG_WAIT) || ipsw){
|
||||
error("missing argument\n");
|
||||
cmd_help();
|
||||
|
@ -287,68 +307,70 @@ int main_r(int argc, const char * argv[]) {
|
|||
}
|
||||
goto error;
|
||||
}
|
||||
if (bootargs){
|
||||
|
||||
|
||||
devVals.deviceModel = (char*)client.getDeviceModelNoCopy();
|
||||
devVals.deviceBoard = (char*)client.getDeviceBoardNoCopy();
|
||||
|
||||
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_SET_NONCE) {
|
||||
client.setNonce(custom_nonce);
|
||||
}
|
||||
|
||||
if(flags & FLAG_BOOT_ARGS) {
|
||||
client.setBootArgs(bootargs);
|
||||
}
|
||||
|
||||
if (flags & FLAG_LATEST_SEP){
|
||||
info("user specified to use latest signed SEP\n");
|
||||
client.loadLatestSep();
|
||||
}else if (!client.is32bit()){
|
||||
client.loadSep(sepPath);
|
||||
client.setSepManifestPath(sepManifestPath);
|
||||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeWithoutBaseband;
|
||||
if (!client.is32bit() && !(isSepManifestSigned = isManifestSignedForDevice(client.sepManifestPath(), &devVals, &versVals, NULL))){
|
||||
reterror("SEP firmware is NOT being signed!\n");
|
||||
}
|
||||
if (flags & FLAG_NO_BASEBAND){
|
||||
printf("\nWARNING: user specified is not to flash a baseband. This can make the restore fail if the device needs a baseband!\n");
|
||||
printf("if you added this flag by mistake, you can press CTRL-C now to cancel\n");
|
||||
int c = 10;
|
||||
printf("continuing restore in ");
|
||||
while (c) {
|
||||
printf("%d ",c--);
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
printf("\n");
|
||||
}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();
|
||||
}else if (!client.is32bit()){
|
||||
client.loadSep(sepPath);
|
||||
client.setSepManifestPath(sepManifestPath);
|
||||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeWithoutBaseband;
|
||||
if (!client.is32bit() && !(isSepManifestSigned = isManifestSignedForDevice(client.sepManifestPath(), &devVals, &versVals, NULL))){
|
||||
reterror("SEP firmware is NOT being signed!\n");
|
||||
}
|
||||
if (flags & FLAG_NO_BASEBAND){
|
||||
printf("\nWARNING: user specified is not to flash a baseband. This can make the restore fail if the device needs a baseband!\n");
|
||||
printf("if you added this flag by mistake, you can press CTRL-C now to cancel\n");
|
||||
int c = 10;
|
||||
printf("continuing restore in ");
|
||||
while (c) {
|
||||
printf("%d ",c--);
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
}
|
||||
printf("\n");
|
||||
if (flags & FLAG_LATEST_BASEBAND){
|
||||
info("user specified to use latest signed baseband\n");
|
||||
client.loadLatestBaseband();
|
||||
}else{
|
||||
if (flags & FLAG_LATEST_BASEBAND){
|
||||
info("user specified to use latest signed baseband\n");
|
||||
client.loadLatestBaseband();
|
||||
}else{
|
||||
client.setBasebandPath(basebandPath);
|
||||
client.setBasebandManifestPath(basebandManifestPath);
|
||||
printf("Did set SEP+baseband path and firmware\n");
|
||||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeOnlyBaseband;
|
||||
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(client.basebandManifestPath(), &devVals, &versVals, NULL))) {
|
||||
reterror("baseband firmware is NOT being signed!\n");
|
||||
}
|
||||
client.setBasebandPath(basebandPath);
|
||||
client.setBasebandManifestPath(basebandManifestPath);
|
||||
printf("Did set SEP+baseband path and firmware\n");
|
||||
}
|
||||
|
||||
versVals.basebandMode = kBasebandModeOnlyBaseband;
|
||||
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(client.basebandManifestPath(), &devVals, &versVals, NULL))) {
|
||||
reterror("baseband firmware is NOT being signed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(!client.is32bit())
|
||||
client.downloadLatestFirmwareComponents();
|
||||
client.putDeviceIntoRecovery();
|
||||
|
@ -360,7 +382,7 @@ int main_r(int argc, const char * argv[]) {
|
|||
printf("[Error] Fail code=%d\n",err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
client.doRestore(ipsw);
|
||||
printf("Done: restoring succeeded!\n");
|
||||
|
@ -368,8 +390,8 @@ int main_r(int argc, const char * argv[]) {
|
|||
e.dump();
|
||||
printf("Done: restoring failed!\n");
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
error:
|
||||
if (err){
|
||||
printf("Failed with error code=%d\n",err);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue