int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "RestoreKernelCache"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } irecv_usb_control_transfer(client->recovery->client, 0x21, 1, 0, 0, 0, 0, 5000); if (client->restore_boot_args) { char setba[256]; strcpy(setba, "setenv boot-args "); strcat(setba, client->restore_boot_args); recovery_error = irecv_send_command(client->recovery->client, setba); } if ((client->flags & FLAG_NOBOOTX) == 0) recovery_error = irecv_send_command(client->recovery->client, "bootx"); else info("Flag nobootx detected! Not executing \"bootx\", but device is ready\n"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } return 0; }
int recovery_send_applelogo(const char* ipsw, plist_t tss) { irecv_client_t recovery = NULL; const char* component = "applelogo"; irecv_error_t recovery_error = IRECV_E_SUCCESS; info("Sending %s...\n", component); if (recovery_open_with_timeout(&recovery) < 0) { return -1; } if (recovery_send_signed_component(recovery, ipsw, tss, "AppleLogo") < 0) { error("ERROR: Unable to send %s to device.\n", component); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "setpicture 1"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set %s\n", component); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "bgcolor 0 0 0"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to display %s\n", component); irecv_close(recovery); return -1; } irecv_close(recovery); recovery = NULL; return 0; }
int recovery_send_applelogo(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "AppleLogo"; irecv_error_t recovery_error = IRECV_E_SUCCESS; info("Sending %s...\n", component); if (client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } recovery_error = irecv_send_command(client->recovery->client, "setpicture 0"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set %s\n", component); return -1; } recovery_error = irecv_send_command(client->recovery->client, "bgcolor 0 0 0"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to display %s\n", component); return -1; } return 0; }
int recovery_send_ramdisk(struct idevicerestore_client_t* client, plist_t build_identity) { const char *component = "RestoreRamDisk"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if(client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } irecv_send_command(client->recovery->client, "getenv ramdisk-delay"); recovery_error = irecv_send_command(client->recovery->client, "ramdisk"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } sleep(2); return 0; }
int recovery_send_kernelcache(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "RestoreKernelCache"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } if (client->restore_boot_args) { char setba[256]; strcpy(setba, "setenv boot-args "); strcat(setba, client->restore_boot_args); recovery_error = irecv_send_command(client->recovery->client, setba); } recovery_error = irecv_send_command(client->recovery->client, "bootx"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } return 0; }
int normal_enter_recovery(struct idevicerestore_client_t* client) { idevice_t device = NULL; irecv_client_t recovery = NULL; lockdownd_client_t lockdown = NULL; irecv_error_t recovery_error = IRECV_E_SUCCESS; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdown_error = LOCKDOWN_E_SUCCESS; device_error = idevice_new(&device, client->uuid); if (device_error != IDEVICE_E_SUCCESS) { error("ERROR: Unable to find device\n"); return -1; } lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to connect to lockdownd service\n"); idevice_free(device); return -1; } lockdown_error = lockdownd_enter_recovery(lockdown); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to place device in recovery mode\n"); lockdownd_client_free(lockdown); idevice_free(device); return -1; } lockdownd_client_free(lockdown); idevice_free(device); lockdown = NULL; device = NULL; if (recovery_open_with_timeout(client) < 0) { error("ERROR: Unable to enter recovery mode\n"); return -1; } recovery_error = irecv_send_command(recovery, "setenv auto-boot true"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to reset auto-boot variable\n"); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "saveenv"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to save auto-boot variable\n"); irecv_close(recovery); return -1; } //client->mode = &idevicerestore_modes[MODE_RECOVERY]; irecv_close(recovery); recovery = NULL; return 0; }
int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity) { idevice_t device = NULL; restored_client_t restore = NULL; if (client->buildno >= 8) { client->restore_boot_args = strdup("rd=md0 nand-enable-reformat=1 -progress"); } /* upload data to make device boot restore mode */ if(client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if ((client->buildno > 8) && !(client->flags & FLAG_CUSTOM)) { /* send ApTicket */ if (recovery_send_ticket(client) < 0) { error("ERROR: Unable to send APTicket\n"); return -1; } } if (recovery_set_autoboot(client, 0) < 0) { return -1; } irecv_send_command(client->recovery->client, "getenv build-version"); irecv_send_command(client->recovery->client, "getenv build-style"); irecv_send_command(client->recovery->client, "getenv radio-error"); /* send logo and show it */ if (recovery_send_applelogo(client, build_identity) < 0) { error("ERROR: Unable to send AppleLogo\n"); return -1; } /* send ramdisk and run it */ if (recovery_send_ramdisk(client, build_identity) < 0) { error("ERROR: Unable to send Ramdisk\n"); return -1; } /* send devicetree and load it */ if (recovery_send_devicetree(client, build_identity) < 0) { error("ERROR: Unable to send DeviceTree\n"); return -1; } if (recovery_send_kernelcache(client, build_identity) < 0) { error("ERROR: Unable to send KernelCache\n"); return -1; } client->mode = &idevicerestore_modes[MODE_RESTORE]; return 0; }
int fsck_client(int _client_, const char* _order_operations, unsigned int argp) { argp = irecv_open_attempts(&client, 10); /* Open attempts and load client */ irecv_send_command(client, "fsck_hfs reset"); /* Send commmand {s_cmd[2]} */ irecv_send_command(client, _order_operations); /* Send specified order */ /* Initation payload[] */ if (argp != EOF) argp = irecv_send_command(client, ""); do { //_client_ = client->DfuPath; argp = EOF; } while (argp != EOF); return 0; }
int recovery_send_kernelcache(const char* ipsw, plist_t tss) { irecv_client_t recovery = NULL; const char* component = "kernelcache"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (recovery_open_with_timeout(&recovery) < 0) { return -1; } if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreKernelCache") < 0) { error("ERROR: Unable to send %s to device.\n", component); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "bootx"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); irecv_close(recovery); return -1; } irecv_close(recovery); recovery = NULL; return 0; }
irecv_error_t irecv_execute_script(irecv_client_t client, const char* filename) { irecv_error_t error = IRECV_E_SUCCESS; if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; char* file_data = NULL; unsigned int file_size = 0; if(irecv_read_file(filename, &file_data, &file_size) < 0) { return IRECV_E_FILE_NOT_FOUND; } char* line = strtok(file_data, "\n"); while(line != NULL) { if(line[0] != '#') { error = irecv_send_command(client, line); if(error != IRECV_E_SUCCESS) { return error; } error = irecv_receive(client); if(error != IRECV_E_SUCCESS) { return error; } } line = strtok(NULL, "\n"); } return IRECV_E_SUCCESS; }
int iboot_command_(const char* s_cmd) { int s_ret = 0; /*Value to be returned */ s_ret = irecv_open_attempts(&client, 10); /* Open attempts and load client */ irecv_send_command(client, s_cmd); /* Send commmand {s_cmd[2]} */ irecv_exit(); /* kill & clear client */ return s_ret; /* Return ret */ }
void init_shell(irecv_client_t client) { irecv_error_t error = 0; load_command_history(); irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL); irecv_event_subscribe(client, IRECV_RECEIVED, &received_cb, NULL); irecv_event_subscribe(client, IRECV_PRECOMMAND, &precommand_cb, NULL); irecv_event_subscribe(client, IRECV_POSTCOMMAND, &postcommand_cb, NULL); while (!quit) { error = irecv_receive(client); if (error != IRECV_E_SUCCESS) { debug("%s\n", irecv_strerror(error)); break; } char* cmd = readline("> "); if (cmd && *cmd) { error = irecv_send_command(client, cmd); if (error != IRECV_E_SUCCESS) { quit = 1; } append_command_to_history(cmd); free(cmd); } } }
int recovery_send_ticket(struct idevicerestore_client_t* client) { if (!client->tss) { error("ERROR: ApTicket requested but no TSS present\n"); return -1; } unsigned char* data = NULL; uint32_t size = 0; if (tss_get_ticket(client->tss, &data, &size) < 0) { error("ERROR: Unable to get ApTicket from TSS request\n"); return -1; } info("Sending APTicket (%d bytes)\n", size); irecv_error_t error = irecv_send_buffer(client->recovery->client, data, size, 0); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send APTicket: %s\n", irecv_strerror(error)); free(data); return -1; } free(data); error = irecv_send_command(client->recovery->client, "ticket"); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send ticket command\n"); return -1; } return 0; }
int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "iBEC"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if ((client->buildno > 9) && !(client->flags & FLAG_CUSTOM)) { /* send ApTicket */ if (recovery_send_ticket(client) < 0) { error("ERROR: Unable to send APTicket\n"); return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } if(client->buildno > 9) { if (recovery_set_autoboot(client, 0) < 0) { error("ERROR: Unable to send autoboot commands\n"); return -1; } } recovery_error = irecv_send_command(client->recovery->client, "go"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } return 0; }
static int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable) { irecv_error_t recovery_error = IRECV_E_SUCCESS; recovery_error = irecv_send_command(client->recovery->client, (enable) ? "setenv auto-boot true" : "setenv auto-boot false"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); return -1; } recovery_error = irecv_send_command(client->recovery->client, "saveenv"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to save environmental variable\n"); return -1; } return 0; }
int main(int argc, char* argv[]) { int result = 0; if (argc != 3) { usage(); } const char* ibssFile = argv[1]; const char* kernelcacheFile = argv[2]; pois0n_init(); pois0n_set_callback(&print_progress, NULL); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); return result; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); return result; } debug("Uploading %s to device\n", ibssFile); irecv_error_t error = irecv_send_file(client, ibssFile, 1); if(error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(error)); return -1; } client = irecv_reconnect(client, 10); debug("Uploading %s to device\n", kernelcacheFile); error = irecv_send_file(client, kernelcacheFile, 1); if(error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(error)); return -1; } error = irecv_send_command(client, "bootx"); if(error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); return -1; } pois0n_exit(); return 0; }
int recovery_send_ibec(const char* ipsw, plist_t tss) { irecv_client_t recovery = NULL; const char* component = "iBEC"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (recovery_open_with_timeout(&recovery) < 0) { return -1; } recovery_error = irecv_send_command(recovery, "setenv auto-boot true"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to set auto-boot environmental variable\n"); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "saveenv"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to save environmental variable\n"); irecv_close(recovery); return -1; } if (recovery_send_signed_component(recovery, ipsw, tss, "iBEC") < 0) { error("ERROR: Unable to send %s to device.\n", component); irecv_close(recovery); return -1; } recovery_error = irecv_send_command(recovery, "go"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); irecv_close(recovery); return -1; } irecv_close(recovery); recovery = NULL; return 0; }
int boot_ramdisk() { irecv_error_t error = IRECV_E_SUCCESS; // Add an exception for this since it's very different debug("Preparing to upload ramdisk\n"); if (upload_ramdisk() < 0) { error("Unable to upload ramdisk\n"); return -1; } debug("Executing ramdisk\n"); error = irecv_send_command(client, "ramdisk"); if (error != IRECV_E_SUCCESS) { error("Unable to execute ramdisk command\n"); return -1; } debug("Setting kernel bootargs\n"); error = irecv_send_command(client, "go kernel bootargs rd=md0 -v keepsyms=1"); if (error != IRECV_E_SUCCESS) { error("Unable to set kernel bootargs\n"); return -1; } debug("Preparing to upload kernelcache\n"); if (upload_kernelcache() < 0) { error("Unable to upload kernelcache\n"); return -1; } error = irecv_send_command(client, "bootx"); if (error != IRECV_E_SUCCESS) { error("Unable to move iBoot into memory\n"); return -1; } return 0; }
int execute_ibss_payload() { //int i = 0; char* bootargs = NULL; irecv_error_t error = IRECV_E_SUCCESS; debug("Initializing greenpois0n in iBSS\n"); irecv_send_command(client, "go"); // Code to detect whether to boot ramdisk or filesystem debug("Checking if device is already jailbroken\n"); error = irecv_getenv(client, "boot-args", &bootargs); if (error != IRECV_E_SUCCESS) { debug("%s\n", irecv_strerror(error)); error("Unable to read env var\n"); return -1; } // If boot-args hasn't been set then we've never been jailbroken if (!strcmp(bootargs, "") || !strcmp(bootargs, "0")) { debug("Booting jailbreak ramdisk\n"); if (boot_ramdisk() < 0) { error("Unable to boot device into tethered mode\n"); return -1; } } // If boot-args is 1 then boot device into tethered mode else if (!strcmp(bootargs, "1")) { debug("Booting tethered device\n"); if (boot_tethered() < 0) { error("Unable to boot device into tethered mode\n"); return -1; } } // If boot-args is 2, then don't boot kernel, just load iBSS payload else if (!strcmp(bootargs, "2")) { debug("Booting iBSS in payload mode\n"); return 0; } // If boot-args is 3, then don't boot kernel, just load iBoot payload else if (!strcmp(bootargs, "3")) { debug("Booting device in verbose mode\n"); if (boot_iboot() < 0) { error("Unable to boot device into verbose mode\n"); return -1; } } return 0; }
int send_command(char* command) { unsigned int ret = 0; irecv_error_t error = IRECV_E_SUCCESS; error = irecv_send_command(client, command); if (error != IRECV_E_SUCCESS) { printf("Unable to send command\n"); return -1; } error = irecv_getret(client, &ret); if (error != IRECV_E_SUCCESS) { printf("Unable to send command\n"); return -1; } return ret; }
int recovery_send_devicetree(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "RestoreDeviceTree"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if(client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } recovery_error = irecv_send_command(client->recovery->client, "devicetree"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } return 0; }
int recovery_send_ibec(struct idevicerestore_client_t* client, plist_t build_identity) { const char* component = "iBEC"; irecv_error_t recovery_error = IRECV_E_SUCCESS; if (client->recovery == NULL) { if (recovery_client_new(client) < 0) { return -1; } } if (recovery_send_component(client, build_identity, component) < 0) { error("ERROR: Unable to send %s to device.\n", component); return -1; } recovery_error = irecv_send_command(client->recovery->client, "go"); if (recovery_error != IRECV_E_SUCCESS) { error("ERROR: Unable to execute %s\n", component); return -1; } irecv_usb_control_transfer(client->recovery->client, 0x21, 1, 0, 0, 0, 0, 5000); return 0; }
int main(int argc, char* argv[]) { int i = 0; int opt = 0; int action = 0; char* argument = NULL; irecv_error_t error = 0; if (argc == 1) print_usage(); while ((opt = getopt(argc, argv, "vhrsc:f:e:k::")) > 0) { switch (opt) { case 'v': verbose += 1; break; case 'h': print_usage(); break; case 'r': action = kResetDevice; break; case 's': action = kStartShell; break; case 'f': action = kSendFile; argument = optarg; break; case 'c': action = kSendCommand; argument = optarg; break; case 'k': action = kSendExploit; argument = optarg; break; case 'e': action = kSendScript; argument = optarg; break; default: fprintf(stderr, "Unknown argument\n"); return -1; } } if (verbose) irecv_set_debug_level(verbose); irecv_init(); irecv_client_t client = NULL; for (i = 0; i <= 5; i++) { debug("Attempting to connect... \n"); if (irecv_open(&client) != IRECV_E_SUCCESS) sleep(1); else break; if (i == 5) { return -1; } } switch (action) { case kResetDevice: irecv_reset(client); break; case kSendFile: irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL); error = irecv_send_file(client, argument, 1); debug("%s\n", irecv_strerror(error)); break; case kSendCommand: error = irecv_send_command(client, argument); debug("%s\n", irecv_strerror(error)); break; case kSendExploit: if (argument != NULL) { irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL); error = irecv_send_file(client, argument, 0); if (error != IRECV_E_SUCCESS) { debug("%s\n", irecv_strerror(error)); break; } } error = irecv_send_exploit(client); debug("%s\n", irecv_strerror(error)); break; case kStartShell: init_shell(client); break; case kSendScript: error = irecv_execute_script(client, argument); if(error != IRECV_E_SUCCESS) { debug("%s\n", irecv_strerror(error)); } break; default: fprintf(stderr, "Unknown action\n"); break; } irecv_close(client); return 0; }
int boot_iboot() { irecv_error_t error = IRECV_E_SUCCESS; debug("Loading iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go image load 0x69626F74 0x9000000"); } else { error = irecv_send_command(client, "go image load 0x69626F74 0x41000000"); } if (error != IRECV_E_SUCCESS) { error("Unable load iBoot to memory\n"); return -1; } debug("Shifting iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go memory move 0x9000040 0x9000000 0x48000"); } else { error = irecv_send_command(client, "go memory move 0x41000040 0x41000000 0x48000"); } if (error != IRECV_E_SUCCESS) { error("Unable to move iBoot into memory\n"); return -1; } debug("Patching iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go patch 0x9000000 0x48000"); } else { error = irecv_send_command(client, "go patch 0x41000000 0x48000"); } if (error != IRECV_E_SUCCESS) { error("Unable to patch iBoot\n"); return -1; } irecv_setenv(client, "auto-boot", "false"); irecv_saveenv(client); debug("Jumping into iBoot\n"); if (device->chip_id == 8720) { error = irecv_send_command(client, "go jump 0x9000000"); } else { error = irecv_send_command(client, "go jump 0x41000000"); } if (error != IRECV_E_SUCCESS) { error("Unable to jump into iBoot\n"); return -1; } debug("Reconnecting to device\n"); client = irecv_reconnect(client, 10); if (client == NULL) { error("Unable to boot the device tethered\n"); return -1; } irecv_setenv(client, "auto-boot", "true"); irecv_saveenv(client); if (upload_firmware_payload("iBoot") < 0) { error("Unable to boot the device tethered\n"); return -1; } debug("Initializing greenpois0n in iBoot\n"); irecv_send_command(client, "go"); return 0; }
int boot_tethered() { irecv_error_t error = IRECV_E_SUCCESS; debug("Initializing greenpois0n in iBoot\n"); irecv_send_command(client, "go"); // Add an exception for this since it's very different if (device->index == DEVICE_APPLETV2) { debug("Preparing to upload kernelcache\n"); if (upload_kernelcache() < 0) { error("Unable to upload kernelcache\n"); return -1; } debug("Hooking jump_to command\n"); error = irecv_send_command(client, "go rdboot"); if (error != IRECV_E_SUCCESS) { error("Unable to hook jump_to\n"); return -1; } debug("Booting kernel\n"); error = irecv_send_command(client, "bootx"); if (error != IRECV_E_SUCCESS) { error("Unable to boot kernel\n"); return -1; } return 0; } debug("Preparing to boot iBoot\n"); if (boot_iboot() < 0) { error("Unable to boot iBoot\n"); return -1; } debug("Preparing to upload ramdisk\n"); if (upload_ramdisk() < 0) { error("Unable to upload ramdisk\n"); return -1; } debug("Executing ramdisk\n"); error = irecv_send_command(client, "go ramdisk 1 1"); if (error != IRECV_E_SUCCESS) { error("Unable to execute ramdisk command\n"); return -1; } debug("Setting kernel bootargs\n"); error = irecv_send_command(client, "go kernel bootargs rd=disk0s1 -v keepsyms=1"); if (error != IRECV_E_SUCCESS) { error("Unable to set kernel bootargs\n"); return -1; } irecv_setenv(client, "boot-args", "0"); irecv_setenv(client, "auto-boot", "true"); irecv_saveenv(client); error = irecv_send_command(client, "go fsboot"); if (error != IRECV_E_SUCCESS) { error("Unable to fsboot\n"); return -1; } return 0; }
int tethered_boot(const char *ibssFile, const char *ibecFile, const char *kernelcacheFile, const char *ramdiskFile, const char *devicetreeFile) { int result = 0; irecv_error_t ir_error = IRECV_E_SUCCESS; irecv_client_t client = g_syringe_client; libpois0n_debug = 1; pois0n_init(); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); goto cleanup; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); goto cleanup; } client = g_syringe_client; if (ibssFile != NULL) { debug("Uploading %s to device, mode: 0x%x\n", ibssFile, client->mode); ir_error = irecv_send_file(client, ibssFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(10); } else { error("ibss can't be null\n"); result = -1; goto cleanup; } if (ibecFile != NULL) { client = g_syringe_client = irecv_reconnect(client, 10); debug("Uploading iBEC %s to device, mode: 0x%x\n", ibecFile, client->mode); ir_error = irecv_send_file(client, ibecFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBEC\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(5); } client = g_syringe_client = irecv_reconnect(client, 10); if (ramdiskFile != NULL) { debug("Uploading ramdisk %s to device\n", ramdiskFile); ir_error = irecv_send_file(client, ramdiskFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload ramdisk\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } sleep(5); ir_error = irecv_send_command(client, "ramdisk"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the ramdisk command\n"); result = -1; goto cleanup; } } if (devicetreeFile != NULL) { debug("Uploading device tree %s to device\n", devicetreeFile); ir_error = irecv_send_file(client, devicetreeFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload device tree\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } ir_error = irecv_send_command(client, "devicetree"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to send the devicetree command\n"); result = -1; goto cleanup; } } if (kernelcacheFile != NULL) { debug("Uploading kernel %s to device, mode: 0x%x\n", kernelcacheFile, client->mode); ir_error = irecv_send_file(client, kernelcacheFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(ir_error)); result = -1; goto cleanup; } ir_error = irecv_send_command(client, "bootx"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); result = -1; goto cleanup; } } else { error("kernelcache can't be null\n"); result = -1; goto cleanup; } result = 0; cleanup: fflush(stderr); if (g_syringe_client) { irecv_close(&g_syringe_client); g_syringe_client = NULL; } //pois0n_exit(); return result; }
int boot_ramdisk() { irecv_error_t error = IRECV_E_SUCCESS; // Add an exception for this since it's very different if(device->index == DEVICE_APPLETV2) { debug("Preparing to upload ramdisk\n"); if(upload_ramdisk() < 0) { error("Unable to upload ramdisk\n"); return -1; } debug("Executing ramdisk\n"); error = irecv_send_command(client, "ramdisk"); if(error != IRECV_E_SUCCESS) { error("Unable to execute ramdisk command\n"); return -1; } debug("Setting kernel bootargs\n"); error = irecv_send_command(client, "go kernel bootargs rd=md0 -v keepsyms=1"); if(error != IRECV_E_SUCCESS) { error("Unable to set kernel bootargs\n"); return -1; } debug("Preparing to upload kernelcache\n"); if(upload_kernelcache() < 0) { error("Unable to upload kernelcache\n"); return -1; } error = irecv_send_command(client, "bootx"); if(error != IRECV_E_SUCCESS) { error("Unable to move iBoot into memory\n"); return -1; } return 0; } debug("Preparing to boot iBoot\n"); if(boot_iboot() < 0) { error("Unable to boot iBoot\n"); return -1; } debug("Preparing to upload ramdisk\n"); if(upload_ramdisk() < 0) { error("Unable to upload ramdisk\n"); return -1; } debug("Executing ramdisk\n"); error = irecv_send_command(client, "go ramdisk 1 1"); if(error != IRECV_E_SUCCESS) { error("Unable to execute ramdisk command\n"); return -1; } debug("Moving ramdisk\n"); if(device->chip_id == 8720) { error = irecv_send_command(client, "go memory move 0x9000040 0xC000000 0x100000"); } else { error = irecv_send_command(client, "go memory move 0x41000040 0x44000000 0x100000"); } if(error != IRECV_E_SUCCESS) { error("Unable to move ramdisk\n"); return -1; } debug("Setting kernel bootargs\n"); error = irecv_send_command(client, "go kernel bootargs rd=md0 -v keepsyms=1"); if(error != IRECV_E_SUCCESS) { error("Unable to set kernel bootargs\n"); return -1; } irecv_setenv(client, "boot-args", "0"); irecv_setenv(client, "auto-boot", "true"); irecv_saveenv(client); error = irecv_send_command(client, "go fsboot"); if (error != IRECV_E_SUCCESS) { error("Unable to fsboot\n"); return -1; } return 0; }
int main(int argc, char* argv[]) { int result = 0; irecv_error_t ir_error = IRECV_E_SUCCESS; //int index; const char *ibssFile = NULL, *ibecFile = NULL, *kernelcacheFile = NULL, *ramdiskFile = NULL, *bgcolor = NULL, *bootlogo = NULL; int c; opterr = 0; while ((c = getopt (argc, argv, "vhi:b:k:r:l:c:")) != -1) switch (c) { case 'v': g_verbose = true; break; case 'h': usage(); break; case 'i': if (!file_exists(optarg)) { error("Cannot open iBSS file '%s'\n", optarg); return -1; } ibssFile = optarg; break; case 'b': if (!file_exists(optarg)) { error("Cannot open iBEC file '%s'\n", optarg); return -1; } ibecFile = optarg; break; case 'k': if (!file_exists(optarg)) { error("Cannot open kernelcache file '%s'\n", optarg); return -1; } kernelcacheFile = optarg; break; case 'r': if (!file_exists(optarg)) { error("Cannot open ramdisk file '%s'\n", optarg); return -1; } ramdiskFile = optarg; break; case 'l': if (!file_exists(optarg)) { error("Cannot open bootlogo file '%s'\n", optarg); return -1; } bootlogo = optarg; break; case 'c': bgcolor = optarg; break; default: usage(); } pois0n_init(); pois0n_set_callback(&print_progress, NULL); info("Waiting for device to enter DFU mode\n"); while(pois0n_is_ready()) { sleep(1); } info("Found device in DFU mode\n"); result = pois0n_is_compatible(); if (result < 0) { error("Your device in incompatible with this exploit!\n"); return result; } result = pois0n_injectonly(); if (result < 0) { error("Exploit injection failed!\n"); return result; } if (ibssFile != NULL) { debug("Uploading %s to device\n", ibssFile); ir_error = irecv_send_file(g_syringe_client, ibssFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBSS\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(10); } else { return 0; } if (ibecFile != NULL) { g_syringe_client = irecv_reconnect(g_syringe_client, 10); debug("Uploading iBEC %s to device\n", ibecFile); ir_error = irecv_send_file(g_syringe_client, ibecFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload iBEC\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(5); } g_syringe_client = irecv_reconnect(g_syringe_client, 10); if (ramdiskFile != NULL) { debug("Uploading ramdisk %s to device\n", ramdiskFile); ir_error = irecv_send_file(g_syringe_client, ramdiskFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload ramdisk\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } sleep(5); ir_error = irecv_send_command(g_syringe_client, "ramdisk"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the ramdisk command\n"); return -1; } } if (bootlogo != NULL) { debug("Uploading boot logo %s to device\n", bootlogo); ir_error = irecv_send_file(g_syringe_client, bootlogo, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload bootlogo\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } ir_error = irecv_send_command(g_syringe_client, "setpicture 1"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to set picture\n"); return -1; } ir_error = irecv_send_command(g_syringe_client, "bgcolor 0 0 0"); if(ir_error != IRECV_E_SUCCESS) { error("Unable to set picture\n"); return -1; } } if (bgcolor != NULL) { char finalbgcolor[255]; sprintf(finalbgcolor, "bgcolor %s", bgcolor); ir_error = irecv_send_command(g_syringe_client, finalbgcolor); if(ir_error != IRECV_E_SUCCESS) { error("Unable set bgcolor\n"); return -1; } } if (kernelcacheFile != NULL) { debug("Uploading %s to device\n", kernelcacheFile); ir_error = irecv_send_file(g_syringe_client, kernelcacheFile, 1); if(ir_error != IRECV_E_SUCCESS) { error("Unable to upload kernelcache\n"); debug("%s\n", irecv_strerror(ir_error)); return -1; } ir_error = irecv_send_command(g_syringe_client, "bootx"); if(ir_error != IRECV_E_SUCCESS) { error("Unable send the bootx command\n"); return -1; } } pois0n_exit(); return 0; }
int recovery_send_reset(struct idevicerestore_client_t* client) { irecv_error_t recovery_error = irecv_send_command(client->recovery->client, "reset"); return 0; }
void resetRecovery(void) { irecv_open_attempts(&client, 10); irecv_send_command(client, "reset"); irecv_exit(); }