Enable no-ibss, fix 32 restores

* disable set-nonce on 32bit
This commit is contained in:
Cryptic 2021-10-13 09:04:32 -07:00
parent 3e915baf1c
commit 96c0a02229
No known key found for this signature in database
GPG key ID: 6027B509EFE3A76B
4 changed files with 222 additions and 138 deletions

View file

@ -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 |

View file

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

View file

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

View file

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