diff options
| author | 2010-07-14 12:48:51 -0400 | |
|---|---|---|
| committer | 2010-07-14 12:48:51 -0400 | |
| commit | fde808212e85de310cb404ac2e577da17f8382c2 (patch) | |
| tree | d69d929dd1fc78b19dbe0ba71908cad89f3039b4 /src | |
| parent | 021a49be23280ddf9289284e8efff2f239d96d15 (diff) | |
| parent | db6dc7b5310138eb6eb3eb099f22ccde65e3e765 (diff) | |
| download | idevicerestore-fde808212e85de310cb404ac2e577da17f8382c2.tar.gz idevicerestore-fde808212e85de310cb404ac2e577da17f8382c2.tar.bz2 | |
Merge branch 'martin'
Diffstat (limited to 'src')
| -rw-r--r-- | src/idevicerestore.c | 57 | ||||
| -rw-r--r-- | src/ipsw.c | 5 | ||||
| -rw-r--r-- | src/ipsw.h | 2 | ||||
| -rw-r--r-- | src/recovery.c | 64 | ||||
| -rw-r--r-- | src/restore.c | 14 | 
5 files changed, 76 insertions, 66 deletions
| diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 00c35c1..f3fdbdc 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -64,7 +64,7 @@ int main(int argc, char* argv[]) {  	int optindex = 0;  	char* ipsw = NULL;  	char* uuid = NULL; -	uint64_t ecid = 0; +	int tss_enabled = 0;  	// create an instance of our context  	struct idevicerestore_client_t* client = (struct idevicerestore_client_t*) malloc(sizeof(struct idevicerestore_client_t)); @@ -149,7 +149,7 @@ int main(int argc, char* argv[]) {  	// extract buildmanifest  	plist_t buildmanifest = NULL;  	info("Extracting BuildManifest from IPSW\n"); -	if (ipsw_extract_build_manifest(ipsw, &buildmanifest) < 0) { +	if (ipsw_extract_build_manifest(ipsw, &buildmanifest, &tss_enabled) < 0) {  		error("ERROR: Unable to extract BuildManifest from %s\n", ipsw);  		return -1;  	} @@ -157,16 +157,10 @@ int main(int argc, char* argv[]) {  	/* print iOS information from the manifest */  	build_manifest_print_information(buildmanifest); -	// devices are listed in order from oldest to newest -	// so we'll need their ECID -	if (client->device->index > DEVICE_IPOD2G) { -		debug("Getting device's ECID for TSS request\n"); -		// fetch the device's ECID for the TSS request -		if (get_ecid(client, &client->ecid) < 0) { -			error("ERROR: Unable to find device ECID\n"); -			return -1; -		} -		debug("Found ECID %llu\n", client->ecid); +	if (client->flags & FLAG_CUSTOM) { +		/* prevent signing custom firmware */ +		tss_enabled = 0; +		info("Custom firmware requested. Disabled TSS request.\n");  	}  	// choose whether this is an upgrade or a restore (default to upgrade) @@ -194,22 +188,29 @@ int main(int argc, char* argv[]) {  	/* print information about current build identity */  	build_identity_print_information(build_identity); -	if (client->flags & FLAG_CUSTOM > 0) { -		if (client->device->index > DEVICE_IPOD2G) { -			if (get_shsh_blobs(client, ecid, build_identity, &client->tss) < 0) { -				error("ERROR: Unable to get SHSH blobs for this device\n"); -				return -1; -			} +	/* retrieve shsh blobs if required */ +	if (tss_enabled) { +		debug("Getting device's ECID for TSS request\n"); +		/* fetch the device's ECID for the TSS request */ +		if (get_ecid(client, &client->ecid) < 0) { +			error("ERROR: Unable to find device ECID\n"); +			return -1;  		} +		info("Found ECID %llu\n", client->ecid); -		/* verify if we have tss records if required */ -		if ((client->device->index > DEVICE_IPOD2G) && (client->tss == NULL)) { -			error("ERROR: Unable to proceed without a tss record.\n"); -			plist_free(buildmanifest); +		if (get_shsh_blobs(client, client->ecid, build_identity, &client->tss) < 0) { +			error("ERROR: Unable to get SHSH blobs for this device\n");  			return -1;  		}  	} +	/* verify if we have tss records if required */ +	if ((tss_enabled) && (client->tss == NULL)) { +		error("ERROR: Unable to proceed without a TSS record.\n"); +		plist_free(buildmanifest); +		return -1; +	} +  	// Extract filesystem from IPSW and return its name  	char* filesystem = NULL;  	if (ipsw_extract_filesystem(client->ipsw, build_identity, &filesystem) < 0) { @@ -432,11 +433,6 @@ int get_cpid(struct idevicerestore_client_t* client, uint32_t* cpid) {  }  int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { -	if(client->device->index <= DEVICE_IPOD2G) { -		*ecid = 0; -		return 0; -	} -  	switch (client->mode->index) {  	case MODE_NORMAL:  		if (normal_get_ecid(client->uuid, ecid) < 0) { @@ -494,13 +490,16 @@ int get_shsh_blobs(struct idevicerestore_client_t* client, uint64_t ecid, plist_  		return -1;  	} -	info("Sending TSS request\n"); +	info("Sending TSS request... ");  	response = tss_send_request(request);  	if (response == NULL) { +		info("ERROR: Unable to send TSS request\n");  		plist_free(request);  		return -1;  	} +	info("received SHSH blobs\n"); +  	plist_free(request);  	*tss = response;  	return 0; @@ -556,7 +555,6 @@ int ipsw_get_component_by_path(const char* ipsw, plist_t tss, const char* path,  	}  	if (tss) { -		info("Signing img3...\n");  		img3 = img3_parse_file(component_data, component_size);  		if (img3 == NULL) {  			error("ERROR: Unable to parse IMG3: %s\n", component_name); @@ -572,6 +570,7 @@ int ipsw_get_component_by_path(const char* ipsw, plist_t tss, const char* path,  			return -1;  		} +		info("Signing %s\n", component_name);  		if (img3_replace_signature(img3, component_blob) < 0) {  			error("ERROR: Unable to replace IMG3 signature\n");  			free(component_blob); @@ -173,10 +173,12 @@ int ipsw_extract_to_memory(const char* ipsw, const char* infile, char** pbuffer,  	return 0;  } -int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest) { +int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *tss_enabled) {  	int size = 0;  	char* data = NULL; +	*tss_enabled = 0; +  	/* older devices don't require personalized firmwares and use a BuildManifesto.plist */  	if (ipsw_extract_to_memory(ipsw, "BuildManifesto.plist", &data, &size) == 0) {  		plist_from_xml(data, size, buildmanifest); @@ -188,6 +190,7 @@ int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest) {  	/* whereas newer devices do not require personalized firmwares and use a BuildManifest.plist */  	if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", &data, &size) == 0) { +		*tss_enabled = 1;  		plist_from_xml(data, size, buildmanifest);  		return 0;  	} @@ -38,7 +38,7 @@ typedef struct {  } ipsw_file;  int ipsw_extract_to_memory(const char* ipsw, const char* infile, char** pbuffer, uint32_t* psize); -int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest); +int ipsw_extract_build_manifest(const char* ipsw, plist_t* buildmanifest, int *tss_enabled);  void ipsw_free_file(ipsw_file* file);  #ifdef __cplusplus diff --git a/src/recovery.c b/src/recovery.c index 6a38343..40b207e 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -95,7 +95,7 @@ int recovery_open_with_timeout(struct idevicerestore_client_t* client) {  			return -1;  		} -		sleep(2); +		sleep(4);  		debug("Retrying connection...\n");  	} @@ -123,27 +123,57 @@ int recovery_check_mode() {  	return 0;  } +static int recovery_enable_autoboot(struct idevicerestore_client_t* client) { +	irecv_error_t recovery_error = IRECV_E_SUCCESS; + +	recovery_error = irecv_setenv(client->recovery->client, "auto-boot", "true"); +	if (recovery_error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to set auto-boot environmental variable\n"); +		return -1; +	} + +	recovery_error = irecv_send_command(client->recovery->client, "saveenv"); +	if (recovery_error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to save environmental variable\n"); +		return -1; +	} + +	return 0; +} +  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 +	/* upload data to make device boot restore mode */ + +	if (recovery_enable_autoboot(client) < 0) { +		return -1; +	} + +	/* send iBEC and run it */  	if (recovery_send_ibec(client, build_identity) < 0) {  		error("ERROR: Unable to send iBEC\n");  		return -1;  	} -	sleep(2); +	/* this must be long enough to allow the device to run the iBEC */ +	/* FIXME: Probably better to detect if the device is back then */ +	sleep(4); + +	/* send logo and show it */  	if (recovery_send_applelogo(client, build_identity) < 0) {  		error("ERROR: Unable to send AppleLogo\n");  		return -1;  	} +	/* send devicetree and load it */  	if (recovery_send_devicetree(client, build_identity) < 0) {  		error("ERROR: Unable to send DeviceTree\n");  		return -1;  	} +	/* send ramdisk and run it */  	if (recovery_send_ramdisk(client, build_identity) < 0) {  		error("ERROR: Unable to send Ramdisk\n");  		return -1; @@ -155,9 +185,6 @@ int recovery_enter_restore(struct idevicerestore_client_t* client, plist_t build  	printf("Hit any key to continue...");  	getchar(); -	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; @@ -198,6 +225,9 @@ int recovery_send_component(struct idevicerestore_client_t* client, plist_t buil  	info("Resetting recovery mode connection...\n");  	irecv_reset(client->recovery->client); +	if (client->tss) +		info("%s will be signed\n", component); +  	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); @@ -218,32 +248,10 @@ int recovery_send_component(struct idevicerestore_client_t* client, plist_t buil  	return 0;  } -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) { -		error("ERROR: Unable to set auto-boot environmental variable\n"); -		return -1; -	} - -	recovery_error = irecv_send_command(client->recovery->client, "saveenv"); -	if (recovery_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to save environmental variable\n"); -		return -1; -	} - -	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; diff --git a/src/restore.c b/src/restore.c index bb3ed96..5e42b97 100644 --- a/src/restore.c +++ b/src/restore.c @@ -275,7 +275,7 @@ int restore_open_with_timeout(struct idevicerestore_client_t* client) {  const char* restore_progress_string(unsigned int operation) {  	switch (operation) {  	case WAIT_FOR_STORAGE: -		return "Waiting for Storage Device..."; +		return "Waiting for storage device";  	case CREATE_PARTITION_MAP:  		return "Creating partition map"; @@ -314,13 +314,13 @@ const char* restore_progress_string(unsigned int operation) {  		return "Partition NAND device";  	case WAIT_FOR_NAND: -		return "Waiting for NAND..."; +		return "Waiting for NAND";  	case WAIT_FOR_DEVICE: -		return "Waiting for Device..."; +		return "Waiting for device";  	case LOAD_KERNEL_CACHE: -		return "Loading kernelcache..."; +		return "Loading kernelcache";  	case LOAD_NOR:  		return "Loading NOR data to flash"; @@ -406,7 +406,7 @@ int restore_send_filesystem(idevice_t device, const char* filesystem) {  	// this step sends requested chunks of data from various offsets to asr so  	// it can validate the filesystem before installing it -	debug("Preparing to validate the filesystem\n"); +	info("Validating the filesystem\n");  	if (asr_perform_validation(asr, filesystem) < 0) {  		error("ERROR: ASR was unable to validate the filesystem\n");  		asr_close(asr); @@ -416,13 +416,13 @@ int restore_send_filesystem(idevice_t device, const char* filesystem) {  	// once the target filesystem has been validated, ASR then requests the  	// entire filesystem to be sent. -	debug("Preparing to send filesystem\n"); +	info("Sending filesystem now...\n");  	if (asr_send_payload(asr, filesystem) < 0) {  		error("ERROR: Unable to send payload to ASR\n");  		asr_close(asr);  		return -1;  	} -	info("Filesystem finished\n"); +	info("Filesystem sent\n");  	asr_close(asr);  	return 0; | 
