diff options
| author | 2010-06-02 04:13:25 +0800 | |
|---|---|---|
| committer | 2010-06-09 17:17:06 +0800 | |
| commit | bab56cf4083c2d0695215ba785019532ffae5749 (patch) | |
| tree | bcc8ff80fc9152823c5881de9d0163a124d369f1 /src | |
| parent | 4de6d38c54d9f641006539a06083e423a5d0c9c9 (diff) | |
| download | idevicerestore-bab56cf4083c2d0695215ba785019532ffae5749.tar.gz idevicerestore-bab56cf4083c2d0695215ba785019532ffae5749.tar.bz2 | |
Began major refactoring, not quite finished yet, this branch is probably broke
Diffstat (limited to 'src')
| -rw-r--r-- | src/dfu.c | 28 | ||||
| -rw-r--r-- | src/dfu.h | 7 | ||||
| -rw-r--r-- | src/idevicerestore.c | 339 | ||||
| -rw-r--r-- | src/idevicerestore.h | 55 | ||||
| -rw-r--r-- | src/img3.h | 4 | ||||
| -rw-r--r-- | src/ipsw.h | 4 | ||||
| -rw-r--r-- | src/normal.c | 169 | ||||
| -rw-r--r-- | src/normal.h | 11 | ||||
| -rw-r--r-- | src/recovery.c | 78 | ||||
| -rw-r--r-- | src/recovery.h | 19 | ||||
| -rw-r--r-- | src/restore.c | 43 | ||||
| -rw-r--r-- | src/restore.h | 9 | ||||
| -rw-r--r-- | src/tss.h | 4 | 
13 files changed, 609 insertions, 161 deletions
| @@ -20,9 +20,37 @@   */  #include <stdint.h> +#include <libirecovery.h>  #include "dfu.h" +int dfu_check_mode() { +	irecv_client_t dfu = NULL; +	irecv_error_t dfu_error = IRECV_E_SUCCESS; + +	dfu_error = irecv_open(&dfu); +	if (dfu_error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if(dfu->mode != kDfuMode) { +		irecv_close(dfu); +		return -1; +	} + +	irecv_close(dfu); +	dfu = NULL; +	return 0; +} + +int dfu_get_cpid(uint32_t* cpid) { +	return 0; +} + +int dfu_get_bdid(uint32_t* bdid) { +	return 0; +} +  int dfu_get_ecid(uint64_t* ecid) {  	return 0;  } @@ -19,11 +19,14 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef DFU_H -#define DFU_H +#ifndef IDEVICERESTORE_DFU_H +#define IDEVICERESTORE_DFU_H  #include <stdint.h> +int dfu_check_mode(); +int dfu_get_cpid(uint32_t* cpid); +int dfu_get_bdid(uint32_t* bdid);  int dfu_get_ecid(uint64_t* ecid);  #endif diff --git a/src/idevicerestore.c b/src/idevicerestore.c index aaff4d6..f03e30e 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -38,25 +38,203 @@  #include "recovery.h"  #include "idevicerestore.h" -#define UNKNOWN_MODE   0 -#define DFU_MODE       1 -#define NORMAL_MODE    2 -#define RECOVERY_MODE  3 -#define RESTORE_MODE   4 - +int idevicerestore_quit = 0;  int idevicerestore_debug = 0; -static int idevicerestore_mode = 0; -static int idevicerestore_quit = 0; -static int idevicerestore_custom = 0; +int idevicerestore_custom = 0; +int idevicerestore_verbose = 0; +idevicerestore_mode_t idevicerestore_mode = UNKNOWN_MODE; +idevicerestore_device_t idevicerestore_device = UNKNOWN_DEVICE;  void usage(int argc, char* argv[]); +int get_device(const char* uuid); +idevicerestore_mode_t check_mode(const char* uuid); +int get_ecid(const char* uuid, uint64_t* ecid); +int get_bdid(const char* uuid, uint32_t* bdid); +int get_cpid(const char* uuid, uint32_t* cpid);  int write_file(const char* filename, char* data, int size); +int extract_buildmanifest(const char* ipsw, plist_t* buildmanifest);  int get_tss_data_by_name(plist_t tss, const char* entry, char** path, char** blob);  int get_tss_data_by_path(plist_t tss, const char* path, char** name, char** blob);  void device_callback(const idevice_event_t* event, void *user_data);  int get_signed_component_by_name(char* ipsw, plist_t tss, char* component, char** pdata, int* psize);  int get_signed_component_by_path(char* ipsw, plist_t tss, char* path, char** pdata, int* psize); +idevicerestore_mode_t check_mode(const char* uuid) { +	if(normal_check_mode(uuid) == 0) { +		info("Found device in normal mode\n"); +		idevicerestore_mode = NORMAL_MODE; +	} + +	else if(recovery_check_mode() == 0) { +		info("Found device in recovery mode\n"); +		idevicerestore_mode = RECOVERY_MODE; +	} + +	else if(dfu_check_mode() == 0) { +		info("Found device in DFU mode\n"); +		idevicerestore_mode = DFU_MODE; +	} + +	else if(restore_check_mode(uuid) == 0) { +		info("Found device in restore mode\n"); +		idevicerestore_mode = RESTORE_MODE; +	} + +	return idevicerestore_mode; +} + +int get_device(const char* uuid) { +	uint32_t bdid = 0; +	uint32_t cpid = 0; + +	if(get_cpid(uuid, &cpid) < 0) { +		error("ERROR: Unable to get device CPID\n"); +		return -1; +	} + +	switch(cpid) { +	case IPHONE2G_CPID: +		// iPhone1,1 iPhone1,2 and iPod1,1 all share the same ChipID +		//   so we need to check the BoardID +		if(get_bdid(uuid, &bdid) < 0) { +			error("ERROR: Unable to get device BDID\n"); +			return -1; +		} + +		switch(bdid) { +		case IPHONE2G_BDID: +			idevicerestore_device = IPHONE2G_DEVICE; +			break; + +		case IPHONE3G_BDID: +			idevicerestore_device = IPHONE3G_DEVICE; +			break; + +		case IPOD1G_BDID: +			idevicerestore_device = IPOD1G_DEVICE; +			break; + +		default: +			idevicerestore_device = UNKNOWN_DEVICE; +			break; +		} +		break; + +	case IPHONE3GS_CPID: +		idevicerestore_device = IPHONE3GS_DEVICE; +		break; + +	case IPOD2G_CPID: +		idevicerestore_device = IPOD2G_DEVICE; +		break; + +	case IPOD3G_CPID: +		idevicerestore_device = IPOD3G_DEVICE; +		break; + +	case IPAD1G_CPID: +		idevicerestore_device = IPAD1G_DEVICE; +		break; + +	default: +		idevicerestore_device = UNKNOWN_DEVICE; +		break; +	} + +	return idevicerestore_device; +} + +int get_bdid(const char* uuid, uint32_t* bdid) { +	switch(idevicerestore_mode) { +	case NORMAL_MODE: +		if(normal_get_bdid(uuid, bdid) < 0) { +			*bdid = -1; +			return -1; +		} +		break; + +	case RECOVERY_MODE: +		if(recovery_get_bdid(bdid) < 0) { +			*bdid = -1; +			return -1; +		} +		break; + +	case DFU_MODE: +		if(dfu_get_bdid(bdid) < 0) { +			*bdid = -1; +			return -1; +		} +		break; + +	default: +		error("ERROR: Device is in an invalid state\n"); +		return -1; +	} + +	return 0; +} + +int get_cpid(const char* uuid, uint32_t* cpid) { +	switch(idevicerestore_mode) { +	case NORMAL_MODE: +		if(normal_get_cpid(uuid, cpid) < 0) { +			*cpid = -1; +			return -1; +		} +		break; + +	case RECOVERY_MODE: +		if(recovery_get_cpid(cpid) < 0) { +			*cpid = -1; +			return -1; +		} +		break; + +	case DFU_MODE: +		if(dfu_get_cpid(cpid) < 0) { +			*cpid = -1; +			return -1; +		} +		break; + +	default: +		error("ERROR: Device is in an invalid state\n"); +		return -1; +	} + +	return 0; +} + +int get_ecid(const char* uuid, uint64_t* ecid) { +	if(normal_get_ecid(uuid, ecid) == 0) { +		info("Found device in normal mode\n"); +		idevicerestore_mode = NORMAL_MODE; +	} + +	else if(recovery_get_ecid(ecid) == 0) { +		info("Found device in recovery mode\n"); +		idevicerestore_mode = RECOVERY_MODE; +	} + +	else if(dfu_get_ecid(ecid) == 0) { +		info("Found device in DFU mode\n"); +		idevicerestore_mode = DFU_MODE; +	} + +	return idevicerestore_mode; +} + +int extract_buildmanifest(const char* ipsw, plist_t* buildmanifest) { +	int size = 0; +	char* data = NULL; +	if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", &data, &size) < 0) { +		return -1; +	} +	plist_from_xml(data, size, buildmanifest); +	return 0; +} +  int main(int argc, char* argv[]) {  	int opt = 0;  	char* ipsw = NULL; @@ -68,16 +246,16 @@ int main(int argc, char* argv[]) {  			usage(argc, argv);  			break; -		case 'v': -			idevicerestore_debug += 1; +		case 'd': +			idevicerestore_debug = 1;  			break;  		case 'c':  			idevicerestore_custom = 1;  			break; -		case 'd': -			idevicerestore_debug = 3; +		case 'v': +			idevicerestore_verbose = 1;  			break;  		case 'u': @@ -86,7 +264,7 @@ int main(int argc, char* argv[]) {  		default:  			usage(argc, argv); -			break; +			return -1;  		}  	} @@ -97,105 +275,40 @@ int main(int argc, char* argv[]) {  		ipsw = argv[0];  	if (ipsw == NULL) { +		usage(argc, argv);  		error("ERROR: Please supply an IPSW\n");  		return -1;  	} -	idevice_t device = NULL; -	irecv_client_t recovery = NULL; -	lockdownd_client_t lockdown = NULL; -	irecv_error_t recovery_error = IRECV_E_SUCCESS; -	idevice_error_t device_error = IDEVICE_E_SUCCESS; -	lockdownd_error_t lockdown_error = LOCKDOWN_E_SUCCESS; - -	/* determine recovery or normal mode */ -	info("Checking for device in normal mode...\n"); -	device_error = idevice_new(&device, uuid); -	if (device_error != IDEVICE_E_SUCCESS) { -		info("Checking for the device in recovery mode...\n"); -		recovery_error = irecv_open(&recovery); -		if (recovery_error != IRECV_E_SUCCESS) { -			error("ERROR: Unable to find device, is it plugged in?\n"); -			return -1; -		} -		info("Found device in recovery mode\n"); -		idevicerestore_mode = RECOVERY_MODE; - -	} else { -		info("Found device in normal mode\n"); -		idevicerestore_mode = NORMAL_MODE; -	} - -	/* retrieve ECID */ -	if (idevicerestore_mode == NORMAL_MODE) { -		lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); -		if (lockdown_error != LOCKDOWN_E_SUCCESS) { -			error("ERROR: Unable to connect to lockdownd\n"); -			idevice_free(device); -			return -1; -		} - -		plist_t unique_chip_node = NULL; -		lockdown_error = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &unique_chip_node); -		if (lockdown_error != LOCKDOWN_E_SUCCESS) { -			error("ERROR: Unable to get UniqueChipID from lockdownd\n"); -			lockdownd_client_free(lockdown); -			idevice_free(device); -			return -1; -		} - -		if (!unique_chip_node || plist_get_node_type(unique_chip_node) != PLIST_UINT) { -			error("ERROR: Unable to get ECID\n"); -			lockdownd_client_free(lockdown); -			idevice_free(device); -			return -1; -		} - -		plist_get_uint_val(unique_chip_node, &ecid); -		lockdownd_client_free(lockdown); -		plist_free(unique_chip_node); -		idevice_free(device); -		lockdown = NULL; -		device = NULL; - -	} else if (idevicerestore_mode == RECOVERY_MODE) { -		recovery_error = irecv_get_ecid(recovery, &ecid); -		if (recovery_error != IRECV_E_SUCCESS) { -			error("ERROR: Unable to get device ECID\n"); -			irecv_close(recovery); -			return -1; -		} -		irecv_close(recovery); -		recovery = NULL; +	/* discover the device type */ +	if(get_device(uuid) < 0) { +		error("ERROR: Unable to find device type\n"); +		return -1;  	} -	if (ecid != 0) { -		info("Found ECID %llu\n", ecid); -	} else { -		error("Unable to find device ECID\n"); +	/* get the device ECID and determine mode */ +	if(get_ecid(uuid, &ecid) < 0 || ecid == 0) { +		error("ERROR: Unable to find device ECID\n");  		return -1;  	} +	info("Found ECID %llu\n", ecid); -	/* parse buildmanifest */ -	int buildmanifest_size = 0; -	char* buildmanifest_data = NULL; +	/* extract buildmanifest */ +	plist_t buildmanifest = NULL;  	info("Extracting BuildManifest.plist from IPSW\n"); -	if (ipsw_extract_to_memory(ipsw, "BuildManifest.plist", &buildmanifest_data, &buildmanifest_size) < 0) { -		error("ERROR: Unable to extract BuildManifest.plist IPSW\n"); +	if(extract_buildmanifest(ipsw, &buildmanifest) < 0) { +		error("ERROR: Unable to extract BuildManifest from %s\n", ipsw);  		return -1;  	} -	plist_t manifest = NULL; -	plist_from_xml(buildmanifest_data, buildmanifest_size, &manifest); -  	info("Creating TSS request\n"); -	plist_t tss_request = tss_create_request(manifest, ecid); +	plist_t tss_request = tss_create_request(buildmanifest, ecid);  	if (tss_request == NULL) {  		error("ERROR: Unable to create TSS request\n"); -		plist_free(manifest); +		plist_free(buildmanifest);  		return -1;  	} -	plist_free(manifest); +	plist_free(buildmanifest);  	info("Sending TSS request\n");  	plist_t tss_response = tss_send_request(tss_request); @@ -240,34 +353,12 @@ int main(int argc, char* argv[]) {  	/* place device into recovery mode if required */  	if (idevicerestore_mode == NORMAL_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); +		if(normal_enter_recovery(uuid) < 0) { +			error("ERROR: Unable to place device into recovery mode\n");  			plist_free(tss_response); -			idevice_free(device);  			return -1;  		} -		lockdownd_client_free(lockdown); -		idevice_free(device); -		lockdown = NULL; -		device = NULL;  	}  	/* upload data to make device boot restore mode */ @@ -315,7 +406,8 @@ int main(int argc, char* argv[]) {  		sleep(1);  	} -	device_error = idevice_new(&device, uuid); +	idevice_t device = NULL; +	idevice_error_t device_error = idevice_new(&device, uuid);  	if (device_error != IDEVICE_E_SUCCESS) {  		error("ERROR: Unable to open device\n");  		plist_free(tss_response); @@ -364,7 +456,7 @@ int main(int argc, char* argv[]) {  						char *datatype = NULL;  						plist_get_string_val(datatype_node, &datatype);  						if (!strcmp(datatype, "SystemImageData")) { -							asr_send_system_image_data_from_file(device, restore, filesystem); +							restore_send_filesystem(device, restore, filesystem);  						} else if (!strcmp(datatype, "KernelCache")) {  							int kernelcache_size = 0; @@ -377,7 +469,7 @@ int main(int argc, char* argv[]) {  							free(kernelcache_data);  						} else if (!strcmp(datatype, "NORData")) { -							restore_send_nor_data(restore, ipsw, tss_response); +							restore_send_nor(restore, ipsw, tss_response);  						} else {  							// Unknown DataType!! @@ -428,9 +520,8 @@ void usage(int argc, char* argv[]) {  	printf("  -u, \t\ttarget specific device by its 40-digit device UUID\n");  	printf("  -h, \t\tprints usage information\n");  	printf("  -c, \t\trestore with a custom firmware\n"); -	printf("  -v, \t\tenable incremental levels of verboseness\n"); +	printf("  -v, \t\tenable verbose output\n");  	printf("\n"); -	exit(1);  }  int write_file(const char* filename, char* data, int size) { diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 3dcf1d5..f1861e9 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -22,10 +22,61 @@  #ifndef IDEVICERESTORE_H  #define IDEVICERESTORE_H +#define info(...) printf(__VA_ARGS__)  #define error(...) fprintf(stderr, __VA_ARGS__) -#define info(...) if(idevicerestore_debug >= 1) fprintf(stderr, __VA_ARGS__) -#define debug(...) if(idevicerestore_debug >= 2) fprintf(stderr, __VA_ARGS__) +#define debug(...) if(idevicerestore_debug >= 1) fprintf(stderr, __VA_ARGS__) +#define IPHONE2G_CPID    8900 +#define IPHONE3G_CPID    8900 +#define IPHONE3GS_CPID   8920 +#define IPOD1G_CPID      8900 +#define IPOD2G_CPID      8720 +#define IPOD3G_CPID      8922 +#define IPAD1G_CPID      8930 + +#define IPHONE2G_BDID       0 +#define IPHONE3G_BDID       4 +#define IPHONE3GS_BDID      0 +#define IPOD1G_BDID         2 +#define IPOD2G_BDID         0 +#define IPOD3G_BDID         2 +#define IPAD1G_BDID         2 + +typedef enum { +	UNKNOWN_MODE =       -1, +	DFU_MODE =            0, +	NORMAL_MODE =         1, +	RECOVERY_MODE =       2, +	RESTORE_MODE =        3 +} idevicerestore_mode_t; + +typedef enum { +	UNKNOWN_DEVICE =     -1, +	IPHONE2G_DEVICE =     0, +	IPHONE3G_DEVICE =     1, +	IPHONE3GS_DEVICE =    2, +	IPOD1G_DEVICE =       3, +	IPOD2G_DEVICE =       4, +	IPOD3G_DEVICE =       5, +	IPAD1G_DEVICE =       6 +} idevicerestore_device_t; + +static char* idevicerestore_products[] = { +	"iPhone1,1", +	"iPhone1,2", +	"iPhone2,1", +	"iPod1,1", +	"iPod2,1", +	"iPod3,1", +	"iPad1,1", +	NULL +}; + +extern int idevicerestore_quit;  extern int idevicerestore_debug; +extern int idevicerestore_custom; +extern int idevicerestore_verbose; +extern idevicerestore_mode_t idevicerestore_mode; +extern idevicerestore_device_t idevicerestore_device;  #endif @@ -19,8 +19,8 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef IMG3_H -#define IMG3_H +#ifndef IDEVICERESTORE_IMG3_H +#define IDEVICERESTORE_IMG3_H  typedef enum {      kNorContainer  = 0x696D6733, // img3 @@ -19,8 +19,8 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef IPSW_H -#define IPSW_H +#ifndef IDEVICERESTORE_IPSW_H +#define IDEVICERESTORE_IPSW_H  #include <zip.h> diff --git a/src/normal.c b/src/normal.c index c7baefd..0420a82 100644 --- a/src/normal.c +++ b/src/normal.c @@ -19,10 +19,177 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ +#include <stdio.h>  #include <stdint.h> +#include <libimobiledevice/lockdown.h> +#include <libimobiledevice/libimobiledevice.h>  #include "normal.h" +#include "idevicerestore.h" -int normal_get_ecid(uint64_t* ecid) { +int normal_check_mode(const char* uuid) { +	char* type = NULL; +	idevice_t device = NULL; +	lockdownd_client_t lockdown = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; + +	device_error = idevice_new(&device, uuid); +	if (device_error != IDEVICE_E_SUCCESS) { +		return -1; +	} + +	lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		idevice_free(device); +		return -1; +	} + +	lockdown_error = lockdownd_query_type(lockdown, &type); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return -1; +	} + +	lockdownd_client_free(lockdown); +	idevice_free(device); +	lockdown = NULL; +	device = NULL;  	return 0;  } + +int normal_get_device(const char* uuid) { +	idevice_t device = NULL; +	char* product_type = NULL; +	plist_t product_type_node = NULL; +	lockdownd_client_t lockdown = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; + +	device_error = idevice_new(&device, uuid); +	if (device_error != IDEVICE_E_SUCCESS) { +		return -1; +	} + +	lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		idevice_free(device); +		return -1; +	} + +	lockdown_error = lockdownd_get_value(lockdown, NULL, "ProductType", &product_type_node); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return -1; +	} + +	if (!product_type_node || plist_get_node_type(product_type_node) != PLIST_STRING) { +		if(product_type_node) plist_free(product_type_node); +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return -1; +	} +	plist_get_string_val(product_type_node, &product_type); +	plist_free(product_type_node); + +	lockdownd_client_free(lockdown); +	idevice_free(device); +	lockdown = NULL; +	device = NULL; + +	int i = 0; +	for(i = 0; idevicerestore_products[i] != NULL; i++) { +		if(!strcmp(product_type, idevicerestore_products[i])) { +			idevicerestore_device = i; +			break; +		} +	} + +	return idevicerestore_device; +} + +int normal_enter_recovery(const char* uuid) { +	idevice_t device = NULL; +	lockdownd_client_t lockdown = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; + +	device_error = idevice_new(&device, uuid); +	if (device_error != IDEVICE_E_SUCCESS) { +		error("ERROR: Unable to find device\n"); +		return -1; +	} + +	lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		error("ERROR: Unable to connect to lockdownd service\n"); +		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); +		idevice_free(device); +		return -1; +	} + +	lockdownd_client_free(lockdown); +	idevice_free(device); +	lockdown = NULL; +	device = NULL; +	return 0; +} + +int normal_get_cpid(const char* uuid, uint32_t* cpid) { +	return 0; +} + +int normal_get_bdid(const char* uuid, uint32_t* bdid) { +	return 0; +} + +int normal_get_ecid(const char* uuid, uint64_t* ecid) { +	idevice_t device = NULL; +	plist_t unique_chip_node = NULL; +	lockdownd_client_t lockdown = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; + +	device_error = idevice_new(&device, uuid); +	if(device_error != IDEVICE_E_SUCCESS) { +		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\n"); +		idevice_free(device); +		return -1; +	} + +	lockdown_error = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &unique_chip_node); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		error("ERROR: Unable to get UniqueChipID from lockdownd\n"); +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return -1; +	} + +	if (!unique_chip_node || plist_get_node_type(unique_chip_node) != PLIST_UINT) { +		error("ERROR: Unable to get ECID\n"); +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return -1; +	} +	plist_get_uint_val(unique_chip_node, ecid); +	plist_free(unique_chip_node); + +	lockdownd_client_free(lockdown); +	idevice_free(device); +	lockdown = NULL; +	device = NULL; +} diff --git a/src/normal.h b/src/normal.h index 3e2868d..bde1de0 100644 --- a/src/normal.h +++ b/src/normal.h @@ -19,11 +19,16 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef NORMAL_H -#define NORMAL_H +#ifndef IDEVICERESTORE_NORMAL_H +#define IDEVICERESTORE_NORMAL_H  #include <stdint.h> -int normal_get_ecid(uint64_t* ecid); +int normal_check_mode(const char* uuid); +int normal_get_device(const char* uuid); +int normal_enter_recovery(const char* uuid); +int normal_get_cpid(const char* uuid, uint32_t* cpid); +int normal_get_bdid(const char* uuid, uint32_t* cpid); +int normal_get_ecid(const char* uuid, uint64_t* ecid);  #endif diff --git a/src/recovery.c b/src/recovery.c index 4e2e7ad..9885982 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -29,7 +29,26 @@  #include "recovery.h"  #include "idevicerestore.h" -int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) { +int recovery_check_mode() { +	irecv_client_t recovery = NULL; +	irecv_error_t recovery_error = IRECV_E_SUCCESS; + +	recovery_error = irecv_open(&recovery); +	if (recovery_error != IRECV_E_SUCCESS) { +		return -1; +	} + +	if(recovery->mode == kDfuMode) { +		irecv_close(recovery); +		return -1; +	} + +	irecv_close(recovery); +	recovery = NULL; +	return 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; @@ -77,7 +96,7 @@ irecv_error_t recovery_open_with_timeout(irecv_client_t* client) {  	return error;  } -int recovery_send_ibec(char* ipsw, plist_t tss) { +int recovery_send_ibec(const char* ipsw, plist_t tss) {  	irecv_error_t error = 0;  	irecv_client_t client = NULL;  	char* component = "iBEC"; @@ -125,7 +144,7 @@ int recovery_send_ibec(char* ipsw, plist_t tss) {  	return 0;  } -int recovery_send_applelogo(char* ipsw, plist_t tss) { +int recovery_send_applelogo(const char* ipsw, plist_t tss) {  	irecv_error_t error = 0;  	irecv_client_t client = NULL;  	char* component = "AppleLogo"; @@ -167,7 +186,7 @@ int recovery_send_applelogo(char* ipsw, plist_t tss) {  	return 0;  } -int recovery_send_devicetree(char* ipsw, plist_t tss) { +int recovery_send_devicetree(const char* ipsw, plist_t tss) {  	irecv_error_t error = 0;  	irecv_client_t client = NULL;  	char *component = "RestoreDeviceTree"; @@ -199,7 +218,7 @@ int recovery_send_devicetree(char* ipsw, plist_t tss) {  	return 0;  } -int recovery_send_ramdisk(char* ipsw, plist_t tss) { +int recovery_send_ramdisk(const char* ipsw, plist_t tss) {  	irecv_error_t error = 0;  	irecv_client_t client = NULL;  	char *component = "RestoreRamDisk"; @@ -231,7 +250,7 @@ int recovery_send_ramdisk(char* ipsw, plist_t tss) {  	return 0;  } -int recovery_send_kernelcache(char* ipsw, plist_t tss) { +int recovery_send_kernelcache(const char* ipsw, plist_t tss) {  	irecv_error_t error = 0;  	irecv_client_t client = NULL;  	char *component = "RestoreKernelCache"; @@ -265,5 +284,52 @@ int recovery_send_kernelcache(char* ipsw, plist_t tss) {  int recovery_get_ecid(uint64_t* ecid) { +	irecv_client_t recovery = NULL; +	if(recovery_open_with_timeout(&recovery) < 0) { +		return -1; +	} + +	irecv_error_t error = irecv_get_ecid(recovery, ecid); +	if (error != IRECV_E_SUCCESS) { +		irecv_close(recovery); +		return -1; +	} + +	irecv_close(recovery); +	recovery = NULL; +	return 0; +} + +int recovery_get_cpid(uint32_t* cpid) { +	irecv_client_t recovery = NULL; +	if(recovery_open_with_timeout(&recovery) < 0) { +		return -1; +	} + +	irecv_error_t error = irecv_get_ecid(recovery, cpid); +	if (error != IRECV_E_SUCCESS) { +		irecv_close(recovery); +		return -1; +	} + +	irecv_close(recovery); +	recovery = NULL; +	return 0; +} + +int recovery_get_bdid(uint32_t* bdid) { +	irecv_client_t recovery = NULL; +	if(recovery_open_with_timeout(&recovery) < 0) { +		return -1; +	} + +	irecv_error_t error = irecv_get_ecid(recovery, bdid); +	if (error != IRECV_E_SUCCESS) { +		irecv_close(recovery); +		return -1; +	} + +	irecv_close(recovery); +	recovery = NULL;  	return 0;  } diff --git a/src/recovery.h b/src/recovery.h index 5495638..86e3af2 100644 --- a/src/recovery.h +++ b/src/recovery.h @@ -19,19 +19,22 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef RECOVERY_H -#define RECOVERY_H +#ifndef IDEVICERESTORE_RECOVERY_H +#define IDEVICERESTORE_RECOVERY_H  #include <stdint.h>  #include <plist/plist.h> -int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component); +int recovery_check_mode(); +int recovery_send_signed_component(irecv_client_t client, const char* ipsw, plist_t tss, char* component);  irecv_error_t recovery_open_with_timeout(irecv_client_t* client); -int recovery_send_ibec(char* ipsw, plist_t tss); -int recovery_send_applelogo(char* ipsw, plist_t tss); -int recovery_send_devicetree(char* ipsw, plist_t tss); -int recovery_send_ramdisk(char* ipsw, plist_t tss); -int recovery_send_kernelcache(char* ipsw, plist_t tss); +int recovery_send_ibec(const char* ipsw, plist_t tss); +int recovery_send_applelogo(const char* ipsw, plist_t tss); +int recovery_send_devicetree(const char* ipsw, plist_t tss); +int recovery_send_ramdisk(const char* ipsw, plist_t tss); +int recovery_send_kernelcache(const char* ipsw, plist_t tss);  int recovery_get_ecid(uint64_t* ecid); +int recovery_get_cpid(uint32_t* cpid); +int recovery_get_bdid(uint32_t* bdid);  #endif diff --git a/src/restore.c b/src/restore.c index 485df9b..90d8c0e 100644 --- a/src/restore.c +++ b/src/restore.c @@ -44,6 +44,39 @@  #define WAIT_FOR_DEVICE        33  #define LOAD_NOR               36 +int restore_check_mode(const char* uuid) { +	char* type = NULL; +	uint64_t version = 0; +	idevice_t device = NULL; +	restored_client_t restore = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	restored_error_t restore_error = RESTORE_E_SUCCESS; + +	device_error = idevice_new(&device, uuid); +	if (device_error != IDEVICE_E_SUCCESS) { +		return -1; +	} + +	restore_error = restored_client_new(device, &restore, "idevicerestore"); +	if (restore_error != RESTORE_E_SUCCESS) { +		idevice_free(device); +		return -1; +	} + +	restore_error = restored_query_type(restore, &type, &version); +	if (restore_error != RESTORE_E_SUCCESS) { +		restored_client_free(restore); +		idevice_free(device); +		return -1; +	} + +	restored_client_free(restore); +	idevice_free(device); +	restore = NULL; +	device = NULL; +	return 0; +} +  const char* restore_progress_string(unsigned int operation) {  	switch(operation) {  	case CREATE_PARTITION_MAP: @@ -98,7 +131,7 @@ int restore_handle_progress_msg(restored_client_t client, plist_t msg) {  	plist_t node = NULL;  	uint64_t operation = 0;  	uint64_t uprogress = 0; -	uint32_t progress = 0; +	uint64_t progress = 0;  	node = plist_dict_get_item(msg, "Operation");  	if (node && PLIST_UINT == plist_get_node_type(node)) { @@ -111,14 +144,14 @@ int restore_handle_progress_msg(restored_client_t client, plist_t msg) {  	node = plist_dict_get_item(msg, "Progress");  	if (node && PLIST_UINT == plist_get_node_type(node)) {  		plist_get_uint_val(node, &uprogress); -		progress = (uint32_t) uprogress; +		progress = uprogress;  	} else {  		debug("Failed to parse progress from ProgressMsg plist \n");  		return 0;  	}  	if ((progress > 0) && (progress < 100)) -		info("%s - Progress: %ul%%\n", restore_progress_string(operation), progress); +		info("%s - Progress: %02ull%%\n", restore_progress_string(operation), progress);  	else  		info("%s\n", restore_progress_string(operation)); @@ -130,7 +163,7 @@ int restore_handle_status_msg(restored_client_t client, plist_t msg) {  	return 0;  } -int asr_send_system_image_data_from_file(idevice_t device, restored_client_t client, const char *filesystem) { +int restore_send_filesystem(idevice_t device, restored_client_t client, const char *filesystem) {  	int i = 0;  	char buffer[0x1000];  	uint32_t recv_bytes = 0; @@ -314,7 +347,7 @@ int restore_send_kernelcache(restored_client_t client, char *kernel_data, int le  	return 0;  } -int restore_send_nor_data(restored_client_t client, char* ipsw, plist_t tss) { +int restore_send_nor(restored_client_t client, char* ipsw, plist_t tss) {  	char* llb_path = NULL;  	char* llb_blob = NULL;  	if (get_tss_data_by_name(tss, "LLB", &llb_path, &llb_blob) < 0) { diff --git a/src/restore.h b/src/restore.h index 644658a..f344b5d 100644 --- a/src/restore.h +++ b/src/restore.h @@ -19,18 +19,19 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef RESTORED_H -#define RESTORED_H +#ifndef IDEVICERESTORE_RESTORE_H +#define IDEVICERESTORE_RESTORE_H  #include <libimobiledevice/restore.h>  #include "restore.h" +int restore_check_mode(const char* uuid);  int restore_handle_progress_msg(restored_client_t client, plist_t msg);  int restore_handle_status_msg(restored_client_t client, plist_t msg); -int asr_send_system_image_data_from_file(idevice_t device, restored_client_t client, const char *filesystem); +int restore_send_filesystem(idevice_t device, restored_client_t client, const char *filesystem);  int restore_send_kernelcache(restored_client_t client, char *kernel_data, int len); -int restore_send_nor_data(restored_client_t client, char* ipsw, plist_t tss); +int restore_send_nor(restored_client_t client, char* ipsw, plist_t tss);  const char* restore_progress_string(unsigned int operation);  #endif @@ -19,8 +19,8 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#ifndef TSS_H -#define TSS_H +#ifndef IDEVICERESTORE_TSS_H +#define IDEVICERESTORE_TSS_H  #include <plist/plist.h> | 
