From 996010895b4f92e37ce4ee535cd404b61ba314b5 Mon Sep 17 00:00:00 2001
From: Joshua Hill
Date: Fri, 21 May 2010 04:04:10 -0400
Subject: Added ECID detection

---
 src/Makefile.in      |   8 +++--
 src/idevicerestore.c | 100 +++++++++++++++++++++++++++++++--------------------
 src/ipsw.c           |   4 +++
 src/tss.c            |   3 +-
 src/tss.h            |   2 +-
 5 files changed, 73 insertions(+), 44 deletions(-)

(limited to 'src')

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;
 	}
diff --git a/src/ipsw.c b/src/ipsw.c
index d33d95f..05a92c6 100644
--- a/src/ipsw.c
+++ b/src/ipsw.c
@@ -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));
diff --git a/src/tss.c b/src/tss.c
index a854bc9..2fe6241 100644
--- a/src/tss.c
+++ b/src/tss.c
@@ -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;
 }
diff --git a/src/tss.h b/src/tss.h
index b14c90b..bfa2114 100644
--- a/src/tss.h
+++ b/src/tss.h
@@ -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
-- 
cgit v1.1-32-gdbae