summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/idevicerestore.c567
1 files changed, 107 insertions, 460 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 5f3e95e..1422c8c 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -46,11 +46,11 @@ static int idevicerestore_mode = 0;
void usage(int argc, char* argv[]);
int write_file(const char* filename, char* data, int size);
-int send_ibec(char* ipsw, plist_t tss);
-int send_applelogo(char* ipsw, plist_t tss);
-int send_devicetree(char* ipsw, plist_t tss);
-int send_ramdisk(char* ipsw, plist_t tss);
-int send_kernelcache(char* ipsw, plist_t tss);
+int irecv_send_ibec(char* ipsw, plist_t tss);
+int irecv_send_applelogo(char* ipsw, plist_t tss);
+int irecv_send_devicetree(char* ipsw, plist_t tss);
+int irecv_send_ramdisk(char* ipsw, plist_t tss);
+int irecv_send_kernelcache(char* ipsw, plist_t tss);
int get_tss_data(plist_t tss, const char* entry, char** path, char** blob);
void device_callback(const idevice_event_t* event, void *user_data);
@@ -101,6 +101,7 @@ int main(int argc, char* argv[]) {
idevice_error_t device_error = IDEVICE_E_SUCCESS;
lockdownd_error_t lockdown_error = LOCKDOWN_E_SUCCESS;
+ /* determine recovery or normal mode */
info("Checking for device in normal mode...\n");
device_error = 1;//idevice_new(&device, uuid);
if (device_error != IDEVICE_E_SUCCESS) {
@@ -118,6 +119,7 @@ int main(int argc, char* argv[]) {
idevicerestore_mode = NORMAL_MODE;
}
+ /* retrieve ECID */
if (idevicerestore_mode == NORMAL_MODE) {
lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
if (lockdown_error != LOCKDOWN_E_SUCCESS) {
@@ -166,6 +168,7 @@ int main(int argc, char* argv[]) {
return -1;
}
+ /* parse buildmanifest */
int buildmanifest_size = 0;
char* buildmanifest_data = NULL;
info("Extracting BuildManifest.plist from IPSW\n");
@@ -226,8 +229,8 @@ int main(int argc, char* argv[]) {
return -1;
}
+ /* place device into recovery mode if required */
if (idevicerestore_mode == NORMAL_MODE) {
- // Place the device in recovery mode
info("Entering recovery mode...\n");
device_error = idevice_new(&device, uuid);
if (device_error != IDEVICE_E_SUCCESS) {
@@ -259,26 +262,27 @@ int main(int argc, char* argv[]) {
device = NULL;
}
- if (send_ibec(ipsw, tss_response) < 0) {
+ /* upload data to make device boot restore mode */
+ if (irecv_send_ibec(ipsw, tss_response) < 0) {
error("ERROR: Unable to send iBEC\n");
plist_free(tss_response);
return -1;
}
sleep(1);
- if (send_applelogo(ipsw, tss_response) < 0) {
+ if (irecv_send_applelogo(ipsw, tss_response) < 0) {
error("ERROR: Unable to send AppleLogo\n");
plist_free(tss_response);
return -1;
}
- if (send_devicetree(ipsw, tss_response) < 0) {
+ if (irecv_send_devicetree(ipsw, tss_response) < 0) {
error("ERROR: Unable to send DeviceTree\n");
plist_free(tss_response);
return -1;
}
- if (send_ramdisk(ipsw, tss_response) < 0) {
+ if (irecv_send_ramdisk(ipsw, tss_response) < 0) {
error("ERROR: Unable to send Ramdisk\n");
plist_free(tss_response);
return -1;
@@ -288,7 +292,7 @@ int main(int argc, char* argv[]) {
printf("Hit any key to continue...");
getchar();
- if (send_kernelcache(ipsw, tss_response) < 0) {
+ if (irecv_send_kernelcache(ipsw, tss_response) < 0) {
error("ERROR: Unable to send KernelCache\n");
plist_free(tss_response);
return -1;
@@ -309,6 +313,7 @@ int main(int argc, char* argv[]) {
//return -1;
}
idevice_set_debug_level(5);
+
restored_client_t restore = NULL;
restored_error_t restore_error = restored_client_new(device, &restore, "idevicerestore");
if (restore_error != RESTORE_E_SUCCESS) {
@@ -329,7 +334,7 @@ int main(int argc, char* argv[]) {
}
info("Device has successfully entered restore mode\n");
- /* start restored service and retrieve port */
+ /* start restore process */
int quit_flag = 0;
char* kernelcache = NULL;
printf("Restore protocol version is %llu.\n", version);
@@ -343,18 +348,18 @@ int main(int argc, char* argv[]) {
char *msgtype = NULL;
plist_get_string_val(msgtype_node, &msgtype);
if (!strcmp(msgtype, "ProgressMsg")) {
- restore_error = progress_msg(restore, message);
+ restore_error = restored_handle_progress_msg(restore, message);
} else if (!strcmp(msgtype, "DataRequestMsg")) {
- //restore_error = data_request_msg(device, restore, message, filesystem);
+ //restore_error = restored_handle_data_request_msg(device, restore, message, filesystem);
plist_t datatype_node = plist_dict_get_item(message, "DataType");
if (datatype_node && PLIST_STRING == plist_get_node_type(datatype_node)) {
char *datatype = NULL;
plist_get_string_val(datatype_node, &datatype);
if (!strcmp(datatype, "SystemImageData")) {
- send_system_data(device, restore, filesystem);
+ asr_send_system_image_data_from_file(device, restore, filesystem);
} else if (!strcmp(datatype, "KernelCache")) {
- send_kernel_data(device, restore, kernelcache);
+ restored_send_kernel_cache_from_file(restore, kernelcache);
} else if (!strcmp(datatype, "NORData")) {
send_nor_data(device, restore);
} else {
@@ -365,7 +370,7 @@ int main(int argc, char* argv[]) {
}
} else if (!strcmp(msgtype, "StatusMsg")) {
- restore_error = status_msg(restore, message);
+ restore_error = restored_handle_status_msg(restore, message);
} else {
printf("Received unknown message type: %s\n", msgtype);
@@ -406,20 +411,20 @@ void usage(int argc, char* argv[]) {
exit(1);
}
-int progress_msg(restored_client_t client, plist_t msg) {
+int restored_handle_progress_msg(restored_client_t client, plist_t msg) {
info("Got progress message\n");
return 0;
}
-int data_request_msg(idevice_t device, restored_client_t client, plist_t msg, const char *filesystem, const char *kernel) {
+int restored_handle_data_request_msg(idevice_t device, restored_client_t client, plist_t msg, const char *filesystem, const char *kernel) {
plist_t datatype_node = plist_dict_get_item(msg, "DataType");
if (datatype_node && PLIST_STRING == plist_get_node_type(datatype_node)) {
char *datatype = NULL;
plist_get_string_val(datatype_node, &datatype);
if (!strcmp(datatype, "SystemImageData")) {
- send_system_data(device, client, filesystem);
+ asr_send_system_image_data_from_file(device, client, filesystem);
} else if (!strcmp(datatype, "KernelCache")) {
- send_kernel_data(device, client, kernel);
+ restored_send_kernel_cache_from_file(client, kernel);
} else if (!strcmp(datatype, "NORData")) {
send_nor_data(device, client);
} else {
@@ -431,12 +436,12 @@ int data_request_msg(idevice_t device, restored_client_t client, plist_t msg, co
return 0;
}
-int status_msg(restored_client_t client, plist_t msg) {
+int restored_handle_status_msg(restored_client_t client, plist_t msg) {
info("Got status message\n");
return 0;
}
-int send_system_data(idevice_t device, restored_client_t client, const char *filesystem) {
+int asr_send_system_image_data_from_file(idevice_t device, restored_client_t client, const char *filesystem) {
int i = 0;
char buffer[0x1000];
uint32_t recv_bytes = 0;
@@ -600,7 +605,7 @@ int send_system_data(idevice_t device, restored_client_t client, const char *fil
return ret;
}
-int send_kernel_data(idevice_t device, restored_client_t client, const char *kernel) {
+int restored_send_kernel_cache_from_file(restored_client_t client, const char *kernel) {
printf("Sending kernelcache\n");
FILE* fd = fopen(kernel, "rb");
if (fd == NULL) {
@@ -703,69 +708,42 @@ int get_tss_data(plist_t tss, const char* entry, char** ppath, char** pblob) {
return 0;
}
-int send_ibec(char* ipsw, plist_t tss) {
- int i = 0;
- irecv_error_t error = 0;
- irecv_client_t client = NULL;
- info("Sending iBEC...\n");
- for (i = 10; i > 0; i--) {
- error = irecv_open(&client);
- if (error == IRECV_E_SUCCESS) {
- irecv_send_command(client, "setenv auto-boot true");
- irecv_send_command(client, "saveenv");
- break;
- }
-
- if (i == 0) {
- error("Unable to connect to iBoot\n");
- return -1;
- }
-
- sleep(2);
- info("Retrying connection...\n");
- }
-
+static int irecv_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) {
char* path = NULL;
char* blob = NULL;
- info("Extracting data from TSS response\n");
- if (get_tss_data(tss, "iBEC", &path, &blob) < 0) {
- error("ERROR: Unable to get data for TSS entry\n");
- irecv_close(client);
- client = NULL;
+ irecv_error_t error = 0;
+
+ info("Extracting %s from TSS response\n", component);
+ if (get_tss_data(tss, component, &path, &blob) < 0) {
+ error("ERROR: Unable to get data for TSS %s entry\n", component);
return -1;
}
- int ibec_size = 0;
- char* ibec_data = NULL;
+ int component_size = 0;
+ char* component_data = NULL;
info("Extracting %s from %s\n", path, ipsw);
- if (ipsw_extract_to_memory(ipsw, path, &ibec_data, &ibec_size)) {
+ if (ipsw_extract_to_memory(ipsw, path, &component_data, &component_size) < 0) {
error("ERROR: Unable to extract %s from %s\n", path, ipsw);
- irecv_close(client);
- client = NULL;
free(path);
free(blob);
return -1;
}
- img3_file* img3 = img3_parse_file(ibec_data, ibec_size);
+ img3_file* img3 = img3_parse_file(component_data, component_size);
if (img3 == NULL) {
error("ERROR: Unable to parse IMG3: %s\n", path);
- irecv_close(client);
- client = NULL;
- free(ibec_data);
+ free(component_data);
free(path);
free(blob);
return -1;
}
- if (ibec_data) {
- free(ibec_data);
- ibec_data = NULL;
+ if (component_data) {
+ free(component_data);
+ component_data = NULL;
}
if (img3_replace_signature(img3, blob) < 0) {
error("ERROR: Unable to replace IMG3 signature\n");
- irecv_close(client);
- client = NULL;
free(path);
free(blob);
return -1;
@@ -779,9 +757,7 @@ int send_ibec(char* ipsw, plist_t tss) {
char* data = NULL;
if (img3_get_data(img3, &data, &size) < 0) {
error("ERROR: Unable to reconstruct IMG3\n");
- irecv_close(client);
img3_free(img3);
- client = NULL;
free(path);
return -1;
}
@@ -799,13 +775,13 @@ int send_ibec(char* ipsw, plist_t tss) {
error = irecv_send_buffer(client, data, size);
if (error != IRECV_E_SUCCESS) {
error("ERROR: Unable to send IMG3: %s\n", path);
- irecv_close(client);
img3_free(img3);
- client = NULL;
free(data);
free(path);
return -1;
}
+
+leave:
if (img3) {
img3_free(img3);
img3 = NULL;
@@ -819,35 +795,21 @@ int send_ibec(char* ipsw, plist_t tss) {
path = NULL;
}
- error = irecv_send_command(client, "go");
- if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute iBEC\n");
- irecv_close(client);
- client = NULL;
- free(data);
- return -1;
- }
-
- if (client) {
- irecv_close(client);
- client = NULL;
- }
return 0;
}
-int send_applelogo(char* ipsw, plist_t tss) {
- int i = 0;
+static irecv_error_t irecv_open_with_timeout(irecv_client_t *client) {
irecv_error_t error = 0;
- irecv_client_t client = NULL;
- info("Sending AppleLogo...\n");
+ int i = 0;
+
for (i = 10; i > 0; i--) {
- error = irecv_open(&client);
+ error = irecv_open(client);
if (error == IRECV_E_SUCCESS) {
break;
}
if (i == 0) {
- error("Unable to connect to iBEC\n");
+ error("Unable to connect to recovery device.\n");
return -1;
}
@@ -855,107 +817,37 @@ int send_applelogo(char* ipsw, plist_t tss) {
info("Retrying connection...\n");
}
- char* path = NULL;
- char* blob = NULL;
- info("Extracting data from TSS response\n");
- if (get_tss_data(tss, "RestoreLogo", &path, &blob) < 0) {
- error("ERROR: Unable to get data for TSS entry\n");
- irecv_close(client);
- client = NULL;
- return -1;
- }
-
- int applelogo_size = 0;
- char* applelogo_data = NULL;
- info("Extracting %s from %s\n", path, ipsw);
- if (ipsw_extract_to_memory(ipsw, path, &applelogo_data, &applelogo_size) < 0) {
- error("ERROR: Unable to extract %s from %s\n", path, ipsw);
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
-
- img3_file* img3 = img3_parse_file(applelogo_data, applelogo_size);
- if (img3 == NULL) {
- error("ERROR: Unable to parse IMG3: %s\n", path);
- irecv_close(client);
- client = NULL;
- free(applelogo_data);
- free(path);
- free(blob);
- return -1;
- }
- if (applelogo_data) {
- free(applelogo_data);
- applelogo_data = NULL;
- }
+ return error;
+}
- if (img3_replace_signature(img3, blob) < 0) {
- error("ERROR: Unable to replace IMG3 signature\n");
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
- if (blob) {
- free(blob);
- blob = NULL;
- }
+int irecv_send_ibec(char* ipsw, plist_t tss) {
+ irecv_error_t error = 0;
+ irecv_client_t client = NULL;
+ char *component = "iBEC";
+ info("Sending %s...\n", component);
- int size = 0;
- char* data = NULL;
- if (img3_get_data(img3, &data, &size) < 0) {
- error("ERROR: Unable to reconstruct IMG3\n");
+ error = irecv_open_with_timeout(&client);
+ if (error != IRECV_E_SUCCESS) {
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(path);
return -1;
}
- if (idevicerestore_debug) {
- char* out = strrchr(path, '/');
- if (out != NULL) {
- out++;
- } else {
- out = path;
- }
- write_file(out, data, size);
- }
+ irecv_send_command(client, "setenv auto-boot true");
+ irecv_send_command(client, "saveenv");
- error = irecv_send_buffer(client, data, size);
- if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send IMG3: %s\n", path);
+ if (irecv_send_signed_component(client, ipsw, tss, component) < 0) {
+ error("ERROR: Unable to send %s to device.\n", component);
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(data);
- free(path);
return -1;
}
- if (img3) {
- img3_free(img3);
- img3 = NULL;
- }
- if (data) {
- free(data);
- data = NULL;
- }
- if (path) {
- free(path);
- path = NULL;
- }
- error = irecv_send_command(client, "setpicture 1");
- error = irecv_send_command(client, "bgcolor 0 0 0");
+ error = irecv_send_command(client, "go");
if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to set AppleLogo\n");
+ error("ERROR: Unable to execute %s\n", component);
irecv_close(client);
client = NULL;
- free(data);
return -1;
}
@@ -966,126 +858,69 @@ int send_applelogo(char* ipsw, plist_t tss) {
return 0;
}
-int send_devicetree(char* ipsw, plist_t tss) {
- int i = 0;
+int irecv_send_applelogo(char* ipsw, plist_t tss) {
irecv_error_t error = 0;
irecv_client_t client = NULL;
- info("Sending DeviceTree...\n");
- for (i = 10; i > 0; i--) {
- error = irecv_open(&client);
- if (error == IRECV_E_SUCCESS) {
- break;
- }
+ char *component = "AppleLogo";
- if (i == 0) {
- error("Unable to connect to iBEC\n");
- return -1;
- }
-
- sleep(3);
- info("Retrying connection...\n");
- }
+ info("Sending %s...\n", component);
- char* path = NULL;
- char* blob = NULL;
- info("Extracting data from TSS response\n");
- if (get_tss_data(tss, "RestoreDeviceTree", &path, &blob) < 0) {
- error("ERROR: Unable to get data for TSS entry\n");
+ error = irecv_open_with_timeout(&client);
+ if (error != IRECV_E_SUCCESS) {
irecv_close(client);
client = NULL;
return -1;
}
- int devicetree_size = 0;
- char* devicetree_data = NULL;
- info("Extracting %s from %s\n", path, ipsw);
- if (ipsw_extract_to_memory(ipsw, path, &devicetree_data, &devicetree_size) < 0) {
- error("ERROR: Unable to extract %s from %s\n", path, ipsw);
+ if (irecv_send_signed_component(client, ipsw, tss, component) < 0) {
+ error("ERROR: Unable to send %s to device.\n", component);
irecv_close(client);
client = NULL;
- free(path);
- free(blob);
return -1;
}
- img3_file* img3 = img3_parse_file(devicetree_data, devicetree_size);
- if (img3 == NULL) {
- error("ERROR: Unable to parse IMG3: %s\n", path);
- free(devicetree_data);
+ error = irecv_send_command(client, "setpicture 1");
+ error = irecv_send_command(client, "bgcolor 0 0 0");
+ if (error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to set %s\n", component);
irecv_close(client);
client = NULL;
- free(path);
- free(blob);
return -1;
}
- if (devicetree_data) {
- free(devicetree_data);
- devicetree_data = NULL;
- }
- if (img3_replace_signature(img3, blob) < 0) {
- error("ERROR: Unable to replace IMG3 signature\n");
+ if (client) {
irecv_close(client);
client = NULL;
- free(path);
- free(blob);
- return -1;
- }
- if (blob) {
- free(blob);
- blob = NULL;
}
+ return 0;
+}
- int size = 0;
- char* data = NULL;
- if (img3_get_data(img3, &data, &size) < 0) {
- error("ERROR: Unable to reconstruct IMG3\n");
+int irecv_send_devicetree(char* ipsw, plist_t tss) {
+ irecv_error_t error = 0;
+ irecv_client_t client = NULL;
+ char *component = "RestoreDeviceTree";
+
+ info("Sending %s...\n", component);
+
+ error = irecv_open_with_timeout(&client);
+ if (error != IRECV_E_SUCCESS) {
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(path);
return -1;
}
- if (idevicerestore_debug) {
- char* out = strrchr(path, '/');
- if (out != NULL) {
- out++;
- } else {
- out = path;
- }
- write_file(out, data, size);
- }
-
- error = irecv_send_buffer(client, data, size);
- if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send IMG3: %s\n", path);
+ if (irecv_send_signed_component(client, ipsw, tss, component) < 0) {
+ error("ERROR: Unable to send %s to device.\n", component);
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(data);
- free(path);
return -1;
}
- if (img3) {
- img3_free(img3);
- img3 = NULL;
- }
- if (data) {
- free(data);
- data = NULL;
- }
- if (path) {
- free(path);
- path = NULL;
- }
error = irecv_send_command(client, "devicetree");
if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute DeviceTree\n");
+ error("ERROR: Unable to execute %s\n", component);
irecv_close(client);
client = NULL;
- free(data);
return -1;
}
@@ -1096,126 +931,32 @@ int send_devicetree(char* ipsw, plist_t tss) {
return 0;
}
-int send_ramdisk(char* ipsw, plist_t tss) {
- int i = 0;
+int irecv_send_ramdisk(char* ipsw, plist_t tss) {
irecv_error_t error = 0;
irecv_client_t client = NULL;
- info("Sending Ramdisk...\n");
- for (i = 10; i > 0; i--) {
- error = irecv_open(&client);
- if (error == IRECV_E_SUCCESS) {
- break;
- }
-
- if (i == 0) {
- error("Unable to connect to iBEC\n");
- return -1;
- }
+ char *component = "RestoreRamDisk";
- sleep(3);
- info("Retrying connection...\n");
- }
-
- char* path = NULL;
- char* blob = NULL;
- info("Extracting data from TSS response\n");
- if (get_tss_data(tss, "RestoreRamDisk", &path, &blob) < 0) {
- error("ERROR: Unable to get data for TSS entry\n");
- irecv_close(client);
- client = NULL;
- return -1;
- }
-
- int ramdisk_size = 0;
- char* ramdisk_data = NULL;
- info("Extracting %s from %s\n", path, ipsw);
- if (ipsw_extract_to_memory(ipsw, path, &ramdisk_data, &ramdisk_size) < 0) {
- error("ERROR: Unable to extract %s from %s\n", path, ipsw);
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
+ info("Sending %s...\n", component);
- img3_file* img3 = img3_parse_file(ramdisk_data, ramdisk_size);
- if (img3 == NULL) {
- error("ERROR: Unable to parse IMG3: %s\n", path);
- free(ramdisk_data);
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
- if (ramdisk_data) {
- free(ramdisk_data);
- ramdisk_data = NULL;
- }
-
- if (img3_replace_signature(img3, blob) < 0) {
- error("ERROR: Unable to replace IMG3 signature\n");
+ error = irecv_open_with_timeout(&client);
+ if (error != IRECV_E_SUCCESS) {
irecv_close(client);
client = NULL;
- free(path);
- free(blob);
return -1;
}
- if (blob) {
- free(blob);
- blob = NULL;
- }
- int size = 0;
- char* data = NULL;
- if (img3_get_data(img3, &data, &size) < 0) {
- error("ERROR: Unable to reconstruct IMG3\n");
+ if (irecv_send_signed_component(client, ipsw, tss, component) < 0) {
+ error("ERROR: Unable to send %s to device.\n", component);
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(path);
return -1;
}
- if (idevicerestore_debug) {
- char* out = strrchr(path, '/');
- if (out != NULL) {
- out++;
- } else {
- out = path;
- }
- write_file(out, data, size);
- }
-
- error = irecv_send_buffer(client, data, size);
- if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send IMG3: %s\n", path);
- irecv_close(client);
- img3_free(img3);
- client = NULL;
- free(data);
- free(path);
- return -1;
- }
- if (img3) {
- img3_free(img3);
- img3 = NULL;
- }
- if (data) {
- free(data);
- data = NULL;
- }
- if (path) {
- free(path);
- path = NULL;
- }
-
error = irecv_send_command(client, "ramdisk");
if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute Ramdisk\n");
+ error("ERROR: Unable to execute %s\n", component);
irecv_close(client);
client = NULL;
- free(data);
return -1;
}
@@ -1226,126 +967,32 @@ int send_ramdisk(char* ipsw, plist_t tss) {
return 0;
}
-int send_kernelcache(char* ipsw, plist_t tss) {
- int i = 0;
+int irecv_send_kernelcache(char* ipsw, plist_t tss) {
irecv_error_t error = 0;
irecv_client_t client = NULL;
- info("Sending KernelCache...\n");
- for (i = 10; i > 0; i--) {
- error = irecv_open(&client);
- if (error == IRECV_E_SUCCESS) {
- break;
- }
+ char *component = "RestoreKernelCache";
- if (i == 0) {
- error("Unable to connect to iBEC\n");
- return -1;
- }
-
- sleep(3);
- info("Retrying connection...\n");
- }
-
- char* path = NULL;
- char* blob = NULL;
- info("Extracting data from TSS response\n");
- if (get_tss_data(tss, "RestoreKernelCache", &path, &blob) < 0) {
- error("ERROR: Unable to get data for TSS entry\n");
- irecv_close(client);
- client = NULL;
- return -1;
- }
-
- int kernelcache_size = 0;
- char* kernelcache_data = NULL;
- info("Extracting %s from %s\n", path, ipsw);
- if (ipsw_extract_to_memory(ipsw, path, &kernelcache_data, &kernelcache_size) < 0) {
- error("ERROR: Unable to extract %s from %s\n", path, ipsw);
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
-
- img3_file* img3 = img3_parse_file(kernelcache_data, kernelcache_size);
- if (img3 == NULL) {
- error("ERROR: Unable to parse IMG3: %s\n", path);
- free(kernelcache_data);
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
- if (kernelcache_data) {
- free(kernelcache_data);
- kernelcache_data = NULL;
- }
-
- if (img3_replace_signature(img3, blob) < 0) {
- error("ERROR: Unable to replace IMG3 signature\n");
- irecv_close(client);
- client = NULL;
- free(path);
- free(blob);
- return -1;
- }
- if (blob) {
- free(blob);
- blob = NULL;
- }
+ info("Sending %s...\n", component);
- int size = 0;
- char* data = NULL;
- if (img3_get_data(img3, &data, &size) < 0) {
- error("ERROR: Unable to reconstruct IMG3\n");
+ error = irecv_open_with_timeout(&client);
+ if (error != IRECV_E_SUCCESS) {
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(path);
return -1;
}
- if (idevicerestore_debug) {
- char* out = strrchr(path, '/');
- if (out != NULL) {
- out++;
- } else {
- out = path;
- }
- write_file(out, data, size);
- }
-
- error = irecv_send_buffer(client, data, size);
- if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send IMG3: %s\n", path);
+ if (irecv_send_signed_component(client, ipsw, tss, component) < 0) {
+ error("ERROR: Unable to send %s to device.\n", component);
irecv_close(client);
- img3_free(img3);
client = NULL;
- free(data);
- free(path);
return -1;
}
- if (img3) {
- img3_free(img3);
- img3 = NULL;
- }
- if (data) {
- free(data);
- data = NULL;
- }
- if (path) {
- free(path);
- path = NULL;
- }
error = irecv_send_command(client, "bootx");
if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute iBEC\n");
+ error("ERROR: Unable to execute %s\n", component);
irecv_close(client);
client = NULL;
- free(data);
return -1;
}