summaryrefslogtreecommitdiffstats
path: root/src/recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/recovery.c')
-rw-r--r--src/recovery.c121
1 files changed, 73 insertions, 48 deletions
diff --git a/src/recovery.c b/src/recovery.c
index 233224a..6a38343 100644
--- a/src/recovery.c
+++ b/src/recovery.c
@@ -45,6 +45,7 @@ int recovery_client_new(struct idevicerestore_client_t* client) {
error("ERROR: Out of memory\n");
return -1;
}
+
client->recovery = recovery;
if (recovery_open_with_timeout(client) < 0) {
@@ -122,28 +123,28 @@ int recovery_check_mode() {
return 0;
}
-int recovery_enter_restore(struct idevicerestore_client_t* client) {
+int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build_identity) {
idevice_t device = NULL;
restored_client_t restore = NULL;
// upload data to make device boot restore mode
- if (recovery_send_ibec(client) < 0) {
+ if (recovery_send_ibec(client, build_identity) < 0) {
error("ERROR: Unable to send iBEC\n");
return -1;
}
- sleep(1);
+ sleep(2);
- if (recovery_send_applelogo(client) < 0) {
+ if (recovery_send_applelogo(client, build_identity) < 0) {
error("ERROR: Unable to send AppleLogo\n");
return -1;
}
- if (recovery_send_devicetree(client) < 0) {
+ if (recovery_send_devicetree(client, build_identity) < 0) {
error("ERROR: Unable to send DeviceTree\n");
return -1;
}
- if (recovery_send_ramdisk(client) < 0) {
+ if (recovery_send_ramdisk(client, build_identity) < 0) {
error("ERROR: Unable to send Ramdisk\n");
return -1;
}
@@ -154,7 +155,10 @@ int recovery_enter_restore(struct idevicerestore_client_t* client) {
printf("Hit any key to continue...");
getchar();
- if (recovery_send_kernelcache(client) < 0) {
+ info("Resetting recovery mode connection...\n");
+ irecv_reset(client->recovery->client);
+
+ if (recovery_send_kernelcache(client, build_identity) < 0) {
error("ERROR: Unable to send KernelCache\n");
return -1;
}
@@ -170,29 +174,42 @@ int recovery_enter_restore(struct idevicerestore_client_t* client) {
return 0;
}
-int recovery_send_signed_component(struct idevicerestore_client_t* client, const char* component) {
- int size = 0;
+int recovery_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component) {
+ uint32_t size = 0;
char* data = NULL;
char* path = NULL;
char* blob = NULL;
irecv_error_t error = 0;
- if (tss_get_entry_path(client->tss, component, &path) < 0) {
- error("ERROR: Unable to get component path\n");
- return -1;
+ if (client->tss) {
+ if (tss_get_entry_path(client->tss, component, &path) < 0) {
+ error("ERROR: Unable to get component path\n");
+ return -1;
+ }
+ } else {
+ if (build_identity_get_component_path(build_identity, component, &path) < 0) {
+ error("ERROR: Unable to get component: %s\n", component);
+ if (path)
+ free(path);
+ return -1;
+ }
}
- if (get_signed_component(client, client->ipsw, client->tss, path, &data, &size) < 0) {
- error("ERROR: Unable to get signed component: %s\n", component);
+ info("Resetting recovery mode connection...\n");
+ irecv_reset(client->recovery->client);
+
+ if (ipsw_get_component_by_path(client->ipsw, client->tss, path, &data, &size) < 0) {
+ error("ERROR: Unable to get component: %s\n", component);
free(path);
return -1;
}
- free(path);
- info("Sending %s...\n", component);
+ info("Sending %s (%d bytes)...\n", component, size);
+
error = irecv_send_buffer(client->recovery->client, data, size);
+ free(path);
if (error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send component: %s\n", component);
+ error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(error));
free(data);
return -1;
}
@@ -201,10 +218,8 @@ int recovery_send_signed_component(struct idevicerestore_client_t* client, const
return 0;
}
-int recovery_send_ibec(struct idevicerestore_client_t* client) {
- const char* component = "iBEC";
+static int recovery_enable_autoboot(struct idevicerestore_client_t* client) {
irecv_error_t recovery_error = IRECV_E_SUCCESS;
-
//recovery_error = irecv_send_command(client->recovery->client, "setenv auto-boot true");
recovery_error = irecv_setenv(client->recovery->client, "auto-boot", "true");
if (recovery_error != IRECV_E_SUCCESS) {
@@ -218,7 +233,18 @@ int recovery_send_ibec(struct idevicerestore_client_t* client) {
return -1;
}
- if (recovery_send_signed_component(client, "iBEC") < 0) {
+ 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 (recovery_enable_autoboot(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;
}
@@ -232,9 +258,8 @@ int recovery_send_ibec(struct idevicerestore_client_t* client) {
return 0;
}
-int recovery_send_applelogo(struct idevicerestore_client_t* client) {
- irecv_client_t recovery = NULL;
- const char* component = "applelogo";
+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);
@@ -242,40 +267,37 @@ int recovery_send_applelogo(struct idevicerestore_client_t* client) {
return -1;
}
- if (recovery_send_signed_component(client, "AppleLogo") < 0) {
+ if (recovery_send_component(client, build_identity, component) < 0) {
error("ERROR: Unable to send %s to device.\n", component);
- irecv_close(recovery);
return -1;
}
- recovery_error = irecv_send_command(recovery, "setpicture 1");
+ recovery_error = irecv_send_command(client->recovery->client, "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");
+ 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);
- irecv_close(recovery);
return -1;
}
- irecv_close(recovery);
- recovery = NULL;
return 0;
}
-int recovery_send_devicetree(struct idevicerestore_client_t* client) {
- const char* component = "devicetree";
+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 (recovery_open_with_timeout(client) < 0) {
- return -1;
+ if(client->recovery == NULL) {
+ if (recovery_open_with_timeout(client) < 0) {
+ return -1;
+ }
}
- if (recovery_send_signed_component(client, "RestoreDeviceTree") < 0) {
+ if (recovery_send_component(client, build_identity, component) < 0) {
error("ERROR: Unable to send %s to device.\n", component);
return -1;
}
@@ -289,16 +311,17 @@ int recovery_send_devicetree(struct idevicerestore_client_t* client) {
return 0;
}
-int recovery_send_ramdisk(struct idevicerestore_client_t* client) {
+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;
- const char *component = "ramdisk";
- recovery_error = recovery_open_with_timeout(client);
- if (recovery_error != IRECV_E_SUCCESS) {
- return -1;
+ if(client->recovery == NULL) {
+ if (recovery_open_with_timeout(client) < 0) {
+ return -1;
+ }
}
- if (recovery_send_signed_component(client, "RestoreRamDisk") < 0) {
+ if (recovery_send_component(client, build_identity, component) < 0) {
error("ERROR: Unable to send %s to device.\n", component);
return -1;
}
@@ -312,15 +335,15 @@ int recovery_send_ramdisk(struct idevicerestore_client_t* client) {
return 0;
}
-int recovery_send_kernelcache(struct idevicerestore_client_t* client) {
- const char* component = "kernelcache";
+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 (recovery_open_with_timeout(client) < 0) {
return -1;
}
- if (recovery_send_signed_component(client, "RestoreKernelCache") < 0) {
+ if (recovery_send_component(client, build_identity, component) < 0) {
error("ERROR: Unable to send %s to device.\n", component);
return -1;
}
@@ -337,8 +360,10 @@ int recovery_send_kernelcache(struct idevicerestore_client_t* client) {
int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {
irecv_error_t recovery_error = IRECV_E_SUCCESS;
- if (recovery_open_with_timeout(client) < 0) {
- return -1;
+ if(client->recovery == NULL) {
+ if (recovery_open_with_timeout(client) < 0) {
+ return -1;
+ }
}
recovery_error = irecv_get_ecid(client->recovery->client, ecid);