Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}