int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plist_t tss, char* component) { int size = 0; char* data = NULL; char* path = NULL; char* blob = NULL; irecv_error_t error = 0; if (tss_get_entry_path(tss, component, &path) < 0) { error("ERROR: Unable to get component path\n"); return -1; } if (get_signed_component(ipsw, tss, path, &data, &size) < 0) { error("ERROR: Unable to get signed component: %s\n", component); free(path); return -1; } free(path); info("Sending %s...\n", component); error = irecv_send_buffer(client, data, size); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send component: %s\n", component); free(data); return -1; } free(data); return 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 (client->tss) { if (tss_get_entry_path(client->tss, component, &path) < 0) { debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component); } } if (!path) { if (build_identity_get_component_path(build_identity, component, &path) < 0) { error("ERROR: Unable to get path for component '%s'\n", component); if (path) free(path); return -1; } } if (client->tss) info("%s will be signed\n", component); if (ipsw_get_component_by_path(client->ipsw, client->tss, component, path, &data, &size) < 0) { error("ERROR: Unable to get component: %s\n", component); free(path); return -1; } info("Sending %s (%d bytes)...\n", component, size); // FIXME: Did I do this right???? error = irecv_send_buffer(client->recovery->client, data, size, 0); free(path); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(error)); free(data); return -1; } free(data); return 0; }
int restore_handle_data_request_msg(idevice_t device, restored_client_t restore, plist_t message, plist_t tss, const char* ipsw, const char* filesystem) { char* type = NULL; plist_t node = NULL; // checks and see what kind of data restored is requests and pass // the request to its own handler node = plist_dict_get_item(message, "DataType"); if (node && PLIST_STRING == plist_get_node_type(node)) { plist_get_string_val(node, &type); // this request is sent when restored is ready to receive the filesystem if (!strcmp(type, "SystemImageData")) { restore_send_filesystem(device, filesystem); } else if (!strcmp(type, "KernelCache")) { int kernelcache_size = 0; char* kernelcache_data = NULL; char* kernelcache_path = NULL; if (tss_get_entry_path(tss, "KernelCache", &kernelcache_path) < 0) { error("ERROR: Unable to find kernelcache path\n"); return -1; } if (get_signed_component(ipsw, tss, kernelcache_path, &kernelcache_data, &kernelcache_size) < 0) { error("ERROR: Unable to get kernelcache file\n"); return -1; } restore_send_kernelcache(restore, kernelcache_data, kernelcache_size); free(kernelcache_data); } else if (!strcmp(type, "NORData")) { restore_send_nor(restore, ipsw, tss); } else { // Unknown DataType!! debug("Unknown data request received\n"); } } return 0; }
int dfu_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 (client->tss) { if (tss_get_entry_path(client->tss, component, &path) < 0) { debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component); } } if (!path) { if (build_identity_get_component_path(build_identity, component, &path) < 0) { error("ERROR: Unable to get path for component '%s'\n", component); if (path) free(path); return -1; } } if (client->tss) info("%s will be signed\n", component); if (ipsw_get_component_by_path(client->ipsw, client->tss, component, path, &data, &size) < 0) { error("ERROR: Unable to get component: %s\n", component); free(path); return -1; } if (!(client->flags & FLAG_CUSTOM) && (strcmp(component, "iBEC") == 0)) { char* ticket = NULL; uint32_t tsize = 0; if (tss_get_ticket(client->tss, &ticket, &tsize) < 0) { error("ERROR: Unable to get ApTicket from TSS request\n"); return -1; } uint32_t fillsize = 0; if ((tsize % 0x100) != 0) { fillsize = ((tsize / 0x100) + 1) * 0x100; } debug("ticket size = %d\nfillsize = %d\n", tsize, fillsize); char* newdata = (char*)malloc(size + fillsize); memcpy(newdata, ticket, tsize); memset(newdata+tsize, '\xFF', fillsize - tsize); memcpy(newdata+fillsize, data, size); free(data); data = newdata; size += fillsize; } info("Sending %s (%d bytes)...\n", component, size); // FIXME: Did I do this right???? error = irecv_send_buffer(client->dfu->client, data, size, 1); free(path); if (error != IRECV_E_SUCCESS) { error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(error)); free(data); return -1; } free(data); return 0; }
int restore_send_nor(restored_client_t client, const char* ipsw, plist_t tss) { char* llb_path = NULL; if (tss_get_entry_path(tss, "LLB", &llb_path) < 0) { error("ERROR: Unable to get LLB info from TSS response\n"); return -1; } char* llb_filename = strstr(llb_path, "LLB"); if (llb_filename == NULL) { error("ERROR: Unable to extract firmware path from LLB filename\n"); free(llb_path); return -1; } char firmware_path[256]; memset(firmware_path, '\0', sizeof(firmware_path)); memcpy(firmware_path, llb_path, (llb_filename - 1) - llb_path); info("Found firmware path %s\n", firmware_path); char manifest_file[256]; 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); int manifest_size = 0; char* manifest_data = NULL; if (ipsw_extract_to_memory(ipsw, manifest_file, &manifest_data, &manifest_size) < 0) { error("ERROR: Unable to extract firmware manifest from ipsw\n"); free(llb_path); return -1; } char firmware_filename[256]; memset(firmware_filename, '\0', sizeof(firmware_filename)); int llb_size = 0; char* llb_data = NULL; plist_t dict = plist_new_dict(); char* filename = strtok(manifest_data, "\n"); if (filename != NULL) { memset(firmware_filename, '\0', sizeof(firmware_filename)); snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); if (get_signed_component(ipsw, tss, firmware_filename, &llb_data, &llb_size) < 0) { error("ERROR: Unable to get signed LLB\n"); return -1; } plist_dict_insert_item(dict, "LlbImageData", plist_new_data(llb_data, (uint64_t) llb_size)); } int nor_size = 0; char* nor_data = NULL; filename = strtok(NULL, "\n"); plist_t norimage_array = plist_new_array(); while (filename != NULL) { memset(firmware_filename, '\0', sizeof(firmware_filename)); snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); if (get_signed_component(ipsw, tss, firmware_filename, &nor_data, &nor_size) < 0) { error("ERROR: Unable to get signed firmware %s\n", firmware_filename); break; } plist_array_append_item(norimage_array, plist_new_data(nor_data, (uint64_t) nor_size)); free(nor_data); nor_data = NULL; nor_size = 0; filename = strtok(NULL, "\n"); } plist_dict_insert_item(dict, "NorImageData", norimage_array); debug_plist(dict); restored_error_t ret = restored_send(client, dict); if (ret != RESTORE_E_SUCCESS) { error("ERROR: Unable to send kernelcache data\n"); plist_free(dict); return -1; } plist_free(dict); return 0; }