diff options
-rw-r--r-- | src/Makefile.in | 8 | ||||
-rw-r--r-- | src/idevicerestore.c | 100 | ||||
-rw-r--r-- | src/ipsw.c | 4 | ||||
-rw-r--r-- | src/tss.c | 3 | ||||
-rw-r--r-- | src/tss.h | 2 |
5 files changed, 73 insertions, 44 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 48ce0de..2dc4e8a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -171,18 +171,22 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +libirecovery_CFLAGS = -I/usr/local/include +libirecovery_LIBS = -L/usr/local/lib -lirecovery -lusb-1.0 AM_CFLAGS = \ $(GLOBAL_CFLAGS) \ $(libimobiledevice_CFLAGS) \ $(libplist_CFLAGS) \ $(libzip_CFLAGS) \ - $(libcurl_CFLAGS) + $(libcurl_CFLAGS) \ + $(libirecovery_CFLAGS) AM_LDFLAGS = \ $(libimobiledevice_LIBS) \ $(libplist_LIBS) \ $(libzip_LIBS) \ - $(libcurl_LIBS) + $(libcurl_LIBS) \ + $(libirecovery_LIBS) idevicerestore_SOURCES = idevicerestore.c ipsw.c tss.c base64.c idevicerestore_CFLAGS = $(AM_CFLAGS) diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 4c504e0..a1cc23a 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -47,6 +47,7 @@ int main(int argc, char* argv[]) { int mode = 0; char* ipsw = NULL; char* uuid = NULL; + uint64_t ecid = NULL; while ((opt = getopt(argc, argv, "vdhi:u:")) > 0) { switch (opt) { case 'h': @@ -81,56 +82,77 @@ int main(int argc, char* argv[]) { } idevice_t device = NULL; - irecv_device_t* recovery = NULL; - irecv_error_t recovery_error = IRECV_SUCCESS; + 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; - info("Checking for device in normal mode\n"); - if(uuid != NULL) { - device_error = idevice_new(&device, uuid); - if(device_error != IDEVICE_E_SUCCESS) { - info("Unable to find device in normal mode\n"); - recovery = irecv_init(); - recovery_error = irecv_open(recovery, uuid); - if(recovery_error != IRECV_SUCCESS) { - info("Unable to find device in recovery mode\n"); - error("ERROR: Unable to find device, is it plugged in?\n"); - irecv_exit(recovery); - return -1; - } - info("Found device in recovery mode\n"); - mode = RECOVERY_MODE; - - } else { - info("Found device in normal mode\n"); - mode = NORMAL_MODE; + lockdownd_error_t lockdown_error = LOCKDOWN_E_SUCCESS; + + 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, uuid); + 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"); + mode = RECOVERY_MODE; } else { - device_error = idevice_new(&device, NULL); - if(device_error != IDEVICE_E_SUCCESS) { - info("Unable to find device in normal mode\n"); - recovery = irecv_init(); - recovery_error = irecv_open(recovery, NULL); - if(recovery_error != IRECV_SUCCESS) { - info("Unable to find device in recovery mode\n"); - error("ERROR: Unable to find device, is it plugged in?\n"); - irecv_exit(recovery); - return -1; - } - info("Found device in recovery mode\n"); - mode = RECOVERY_MODE; - - } else { - info("Found device in normal mode\n"); - mode = NORMAL_MODE; + info("Found device in normal mode\n"); + mode = NORMAL_MODE; + } + + if(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); + info("Found ECID %llu\n", ecid); + } + + if(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; + } + info("Found ECID %llu\n", ecid); } info("Extracting BuildManifest.plist from IPSW\n"); ipsw_archive* archive = ipsw_open(ipsw); + if(archive == NULL) { + error("ERROR: Unable to open IPSW\n"); + return -1; + } + ipsw_file* buildmanifest = ipsw_extract_file(archive, "BuildManifest.plist"); if(buildmanifest == NULL) { - error("ERRPR: Unable to extract BuildManifest.plist IPSW\n"); + error("ERROR: Unable to extract BuildManifest.plist IPSW\n"); ipsw_close(archive); return -1; } @@ -24,6 +24,10 @@ #include <string.h> #include "ipsw.h" +#define error(...) fprintf(stderr, __VA_ARGS__) +#define info(...) if(verbose >= 1) fprintf(stderr, __VA_ARGS__) +#define debug(...) if(verbose >= 2) fprintf(stderr, __VA_ARGS__) + ipsw_archive* ipsw_open(const char* ipsw) { int err = 0; ipsw_archive* archive = (ipsw_archive*) malloc(sizeof(ipsw_archive)); @@ -23,7 +23,7 @@ #include <stdlib.h> #include <plist/plist.h> -plist_t tss_create_request(plist_t buildmanifest) { +plist_t tss_create_request(plist_t buildmanifest, const char* ecid) { plist_t build_identities_array = plist_dict_get_item(buildmanifest, "BuildIdentities"); if(!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { error("ERROR: Unable to find BuildIdentities array\n"); @@ -73,6 +73,5 @@ plist_t tss_create_request(plist_t buildmanifest) { sscanf(security_domain_string, "%x", &security_domain); - return NULL; } @@ -24,6 +24,6 @@ #include <plist/plist.h> -plist_t tss_create_request(plist_t buildmanifest); +plist_t tss_create_request(plist_t buildmanifest, const char* ecid); #endif |