diff options
| author | 2010-05-22 14:48:13 -0400 | |
|---|---|---|
| committer | 2010-05-22 14:48:13 -0400 | |
| commit | a184cda744006d4a597ff5a23b67b635dd28c222 (patch) | |
| tree | ae250bf08d06cc95db3729dcd8d36734926f903c /src/idevicerestore.c | |
| parent | 58a0ad3e30bd61cb0c2e6bb62dec600305ea2368 (diff) | |
| download | idevicerestore-a184cda744006d4a597ff5a23b67b635dd28c222.tar.gz idevicerestore-a184cda744006d4a597ff5a23b67b635dd28c222.tar.bz2 | |
Started implementation of img3 file and tss_stitcher
Diffstat (limited to 'src/idevicerestore.c')
| -rw-r--r-- | src/idevicerestore.c | 107 | 
1 files changed, 106 insertions, 1 deletions
| diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 121ce22..0719508 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -29,6 +29,7 @@  #include <libimobiledevice/libimobiledevice.h>  #include "tss.h" +#include "img3.h"  #include "ipsw.h"  #include "idevicerestore.h" @@ -130,6 +131,8 @@ int main(int argc, char* argv[]) {  		plist_get_uint_val(unique_chip_node, &ecid);  		lockdownd_client_free(lockdown);  		idevice_free(device); +		lockdown = NULL; +		device = NULL;  	}  	else if(mode == RECOVERY_MODE) {  		recovery_error = irecv_get_ecid(recovery, &ecid); @@ -139,6 +142,7 @@ int main(int argc, char* argv[]) {  			return -1;  		}  		irecv_close(recovery); +		recovery = NULL;  	}  	if(ecid != 0) { @@ -184,8 +188,109 @@ int main(int argc, char* argv[]) {  		return -1;  	}  	plist_free(tss_request); -  	info("Got TSS response\n"); + +	if(mode == NORMAL_MODE) { +		// Place the device in recovery mode +		info("Entering recovery mode...\n"); +		device_error = idevice_new(&device, uuid); +		if(device_error != IDEVICE_E_SUCCESS) { +			error("ERROR: Unable to find device\n"); +			plist_free(tss_response); +			return -1; +		} + +		lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); +		if(lockdown_error != LOCKDOWN_E_SUCCESS) { +			error("ERROR: Unable to connect to lockdownd service\n"); +			plist_free(tss_response); +			idevice_free(device); +			return -1; +		} + +		lockdown_error = lockdownd_enter_recovery(lockdown); +		if(lockdown_error != LOCKDOWN_E_SUCCESS) { +			error("ERROR: Unable to place device in recovery mode\n"); +			lockdownd_client_free(lockdown); +			plist_free(tss_response); +			idevice_free(device); +			return -1; +		} + +		lockdownd_client_free(lockdown); +		idevice_free(device); +		lockdown = NULL; +		device = NULL; +	} + +	recovery_error = irecv_open(&recovery, uuid); +	while(recovery_error != IRECV_E_SUCCESS) { +		sleep(1); +		info("Retrying connection...\n"); +		recovery_error = irecv_open(&recovery, uuid); +		if(recovery_error == IRECV_E_SUCCESS) { +			mode = RECOVERY_MODE; +			break; +		} +	} + +	info("Extracting iBEC from IPSW\n"); +	archive = ipsw_open(ipsw); +	if(archive == NULL) { +		error("ERROR: Unable to open IPSW\n"); +		plist_free(tss_response); +		irecv_close(recovery); +		return -1; +	} + +	plist_t ibec_entry = plist_dict_get_item(tss_response, "iBEC"); +	if(!ibec_entry || plist_get_node_type(ibec_entry) != PLIST_DICT) { +		error("ERROR: Unable to find iBEC entry in TSS response\n"); +		plist_free(tss_response); +		irecv_close(recovery); +		ipsw_close(archive); +		return -1; +	} + +	char* ibec_path = NULL; +	plist_t ibec_path_node = plist_dict_get_item(ibec_entry, "Path"); +	if(!ibec_path_node || plist_get_node_type(ibec_path_node) != PLIST_STRING) { +		error("ERROR: Unable to find iBEC path in entry\n"); +		plist_free(tss_response); +		plist_free(ibec_entry); +		irecv_close(recovery); +		ipsw_close(archive); +	} +	plist_get_string_val(ibec_path_node, &ibec_path); +	plist_free(ibec_entry); + +	ipsw_file* ibec = ipsw_extract_file(archive, ibec_path); +	if(ibec == NULL) { +		error("ERROR: Unable to extract %s from IPSW\n", ibec_path); +		irecv_close(recovery); +		ipsw_close(archive); +		return -1; +	} +	ipsw_close(archive); + +	img3_file* ibec_img3 = img3_parse_file(ibec->data, ibec->size); +	if(ibec_img3 == NULL) { +		error("ERROR: Unable to parse IMG3: %s\n", ibec_path); +		irecv_close(recovery); +		ipsw_free_file(ibec); +		return -1; +	} +	ipsw_free_file(ibec); + +	tss_stitch_img3(tss_response, &ibec_img3); +	recovery_error = irecv_send_file(recovery, ibec_img3->data); +	if(recovery_error != IRECV_E_SUCCESS) { +		error("ERROR: Unable to send IMG3: %s\n", ibec_path); +		irecv_close(recovery); +		image3_free(ibec_img3); +	} + +	irecv_close(recovery);  	plist_free(tss_response);  	return 0;  } | 
