-
-
Save nikias/8a9f4d7937d71bd2d375944d096cd781 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/restore.c b/src/restore.c | |
index 807047c..70f0d8e 100644 | |
--- a/src/restore.c | |
+++ b/src/restore.c | |
@@ -911,6 +911,8 @@ int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* | |
unsigned int nor_size = 0; | |
unsigned char* nor_data = NULL; | |
plist_t norimage_array = NULL; | |
+ plist_t firmware_files = NULL; | |
+ uint32_t i; | |
info("About to send NORData...\n"); | |
@@ -939,11 +941,53 @@ int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* | |
memset(manifest_file, '\0', sizeof(manifest_file)); | |
snprintf(manifest_file, sizeof(manifest_file), "%s/manifest", firmware_path); | |
- info("Getting firmware manifest %s\n", manifest_file); | |
- if (ipsw_extract_to_memory(client->ipsw, manifest_file, &manifest_data, &manifest_size) < 0) { | |
- error("ERROR: Unable to extract firmware manifest from ipsw\n"); | |
- free(llb_path); | |
+ firmware_files = plist_new_array(); | |
+ ipsw_extract_to_memory(client->ipsw, manifest_file, &manifest_data, &manifest_size); | |
+ if (manifest_data && manifest_size > 0) { | |
+ info("Getting firmware manifest from %s\n", manifest_file); | |
+ char *manifest_p = (char*)manifest_data; | |
+ while ((filename = strsep(&manifest_p, "\r\n")) != NULL) { | |
+ if (*filename == '\0') continue; | |
+ memset(firmware_filename, '\0', sizeof(firmware_filename)); | |
+ snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); | |
+ plist_array_append_item(firmware_files, plist_new_string(firmware_filename)); | |
+ } | |
+ free(manifest_data); | |
+ } else { | |
+ info("Getting firmware manifest from build identity\n"); | |
+ plist_dict_iter iter = NULL; | |
+ plist_t build_id_manifest = plist_dict_get_item(build_identity, "Manifest"); | |
+ if (build_id_manifest) { | |
+ plist_dict_new_iter(build_id_manifest, &iter); | |
+ } | |
+ if (iter) { | |
+ char *component; | |
+ plist_t manifest_entry; | |
+ do { | |
+ component = NULL; | |
+ manifest_entry = NULL; | |
+ plist_dict_next_item(build_id_manifest, iter, &component, &manifest_entry); | |
+ if (component && manifest_entry && plist_get_node_type(manifest_entry) == PLIST_DICT) { | |
+ uint8_t is_fw = 0; | |
+ plist_t is_fw_node = plist_access_path(manifest_entry, 2, "Info", "IsFirmwarePayload"); | |
+ if (is_fw_node && plist_get_node_type(is_fw_node) == PLIST_BOOLEAN) { | |
+ plist_get_bool_val(is_fw_node, &is_fw); | |
+ } | |
+ if (is_fw) { | |
+ plist_t comp_path = plist_access_path(manifest_entry, 2, "Info", "Path"); | |
+ if (comp_path) { | |
+ plist_array_append_item(firmware_files, plist_copy(comp_path)); | |
+ } | |
+ } | |
+ } | |
+ } while (manifest_entry); | |
+ free(iter); | |
+ } | |
+ } | |
+ | |
+ if (plist_array_get_size(firmware_files) == 0) { | |
+ error("ERROR: Unable to get list of firmware files.\n"); | |
return -1; | |
} | |
@@ -972,28 +1016,43 @@ int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* | |
norimage_array = plist_new_array(); | |
- filename = strtok((char*)manifest_data, "\r\n"); | |
- while (filename != NULL) { | |
- if ((!strncmp("LLB", filename, 3)) || (!strncmp("sep", filename, 3))) { | |
- // skip LLB, it's already passed in LlbImageData | |
- filename = strtok(NULL, "\r\n"); | |
+ for (i = 0; i < plist_array_get_size(firmware_files); i++) { | |
+ plist_t pcomp = plist_array_get_item(firmware_files, i); | |
+ char *comppath = NULL; | |
+ | |
+ plist_get_string_val(pcomp, &comppath); | |
+ if (!comppath) continue; | |
+ | |
+ filename = strrchr(comppath, '/'); | |
+ if (!filename) { | |
+ free(comppath); | |
continue; | |
} | |
- memset(firmware_filename, '\0', sizeof(firmware_filename)); | |
- snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); | |
+ filename++; | |
component = get_component_name(filename); | |
+ if (!strcmp(component, "LLB") || !strcmp(component, "RestoreSEP")) { | |
+ // skip LLB, it's already passed in LlbImageData | |
+ // skip RestoreSEP, it's passed in RestoreSEPImageData | |
+ free(comppath); | |
+ continue; | |
+ } | |
+ | |
component_data = NULL; | |
unsigned int component_size = 0; | |
- if (extract_component(client->ipsw, firmware_filename, &component_data, &component_size) < 0) { | |
+ if (extract_component(client->ipsw, comppath, &component_data, &component_size) < 0) { | |
+ free(comppath); | |
+ plist_free(firmware_files); | |
error("ERROR: Unable to extract component: %s\n", component); | |
return -1; | |
} | |
+ free(comppath); | |
if (personalize_component(component, component_data, component_size, client->tss, &nor_data, &nor_size) < 0) { | |
- error("ERROR: Unable to get personalized component: %s\n", component); | |
free(component_data); | |
+ plist_free(firmware_files); | |
+ error("ERROR: Unable to get personalized component: %s\n", component); | |
return -1; | |
} | |
free(component_data); | |
@@ -1010,8 +1069,8 @@ int restore_send_nor(restored_client_t restore, struct idevicerestore_client_t* | |
free(nor_data); | |
nor_data = NULL; | |
nor_size = 0; | |
- filename = strtok(NULL, "\r\n"); | |
} | |
+ plist_free(firmware_files); | |
plist_dict_set_item(dict, "NorImageData", norimage_array); | |
unsigned char* personalized_data = NULL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment