summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Joshua Hill2010-05-24 15:35:08 -0400
committerGravatar Joshua Hill2010-05-24 15:35:08 -0400
commit92c2879d16148f47ff38f3490f24768bb8eb61f6 (patch)
tree4357e98965ecdc2bbb8ce43ef4c8bfc9f2b17c0a
parentdb663abb4d7fd66b5433d46d46b7cdeda22fccdc (diff)
downloadidevicerestore-92c2879d16148f47ff38f3490f24768bb8eb61f6.tar.gz
idevicerestore-92c2879d16148f47ff38f3490f24768bb8eb61f6.tar.bz2
Have it sending DeviceTree now and started on ramdisk. Started to clean up a little bit, but not everything yet.
-rw-r--r--src/idevicerestore.c469
-rw-r--r--src/ipsw.c11
-rw-r--r--src/ipsw.h8
-rw-r--r--src/tss.c8
4 files changed, 401 insertions, 95 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 1c8b24a..ec449d9 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -41,6 +41,11 @@ int idevicerestore_debug = 0;
void usage(int argc, char* argv[]);
int write_file(const char* filename, char* data, int size);
+int send_ibec(char* ipsw, plist_t tss);
+int send_devicetree(char* ipsw, plist_t tss);
+int send_ramdisk(char* ipsw, plist_t tss);
+int send_kernelcache(char* ipsw, plist_t tss);
+int get_tss_data(plist_t tss, const char* entry, char** path, char** blob);
int main(int argc, char* argv[]) {
int opt = 0;
@@ -76,7 +81,7 @@ int main(int argc, char* argv[]) {
}
}
- if(ipsw == NULL) {
+ if (ipsw == NULL) {
error("ERROR: Please supply an IPSW\n");
return -1;
}
@@ -90,10 +95,10 @@ int main(int argc, char* argv[]) {
info("Checking for device in normal mode...\n");
device_error = idevice_new(&device, uuid);
- if(device_error != IDEVICE_E_SUCCESS) {
+ 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) {
+ recovery_error = irecv_open(&recovery);
+ if (recovery_error != IRECV_E_SUCCESS) {
error("ERROR: Unable to find device, is it plugged in?\n");
return -1;
}
@@ -105,9 +110,9 @@ int main(int argc, char* argv[]) {
mode = NORMAL_MODE;
}
- if(mode == NORMAL_MODE) {
+ if (mode == NORMAL_MODE) {
lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
- if(lockdown_error != LOCKDOWN_E_SUCCESS) {
+ if (lockdown_error != LOCKDOWN_E_SUCCESS) {
error("ERROR: Unable to connect to lockdownd\n");
idevice_free(device);
return -1;
@@ -115,14 +120,14 @@ int main(int argc, char* argv[]) {
plist_t unique_chip_node = NULL;
lockdown_error = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &unique_chip_node);
- if(lockdown_error != LOCKDOWN_E_SUCCESS) {
+ 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) {
+ 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);
@@ -134,10 +139,9 @@ int main(int argc, char* argv[]) {
idevice_free(device);
lockdown = NULL;
device = NULL;
- }
- else if(mode == RECOVERY_MODE) {
+ } else if (mode == RECOVERY_MODE) {
recovery_error = irecv_get_ecid(recovery, &ecid);
- if(recovery_error != IRECV_E_SUCCESS) {
+ if (recovery_error != IRECV_E_SUCCESS) {
error("ERROR: Unable to get device ECID\n");
irecv_close(recovery);
return -1;
@@ -146,7 +150,7 @@ int main(int argc, char* argv[]) {
recovery = NULL;
}
- if(ecid != 0) {
+ if (ecid != 0) {
info("Found ECID %llu\n", ecid);
} else {
error("Unable to find device ECID\n");
@@ -154,27 +158,19 @@ int main(int argc, char* argv[]) {
}
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) {
+ ipsw_file* buildmanifest = ipsw_extract_file(ipsw, "BuildManifest.plist");
+ if (buildmanifest == NULL) {
error("ERROR: Unable to extract BuildManifest.plist IPSW\n");
- ipsw_close(archive);
return -1;
}
plist_t manifest = NULL;
plist_from_xml(buildmanifest->data, buildmanifest->size, &manifest);
ipsw_free_file(buildmanifest);
- ipsw_close(archive);
info("Creating TSS request\n");
plist_t tss_request = tss_create_request(manifest, ecid);
- if(tss_request == NULL) {
+ if (tss_request == NULL) {
error("ERROR: Unable to create TSS request\n");
plist_free(manifest);
return -1;
@@ -183,7 +179,7 @@ int main(int argc, char* argv[]) {
info("Sending TSS request\n");
plist_t tss_response = tss_send_request(tss_request);
- if(tss_response == NULL) {
+ if (tss_response == NULL) {
error("ERROR: Unable to get response from TSS server\n");
plist_free(tss_request);
return -1;
@@ -191,18 +187,18 @@ int main(int argc, char* argv[]) {
plist_free(tss_request);
info("Got TSS response\n");
- if(mode == NORMAL_MODE) {
+ 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) {
+ 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) {
+ if (lockdown_error != LOCKDOWN_E_SUCCESS) {
error("ERROR: Unable to connect to lockdownd service\n");
plist_free(tss_response);
idevice_free(device);
@@ -210,7 +206,7 @@ int main(int argc, char* argv[]) {
}
lockdown_error = lockdownd_enter_recovery(lockdown);
- if(lockdown_error != LOCKDOWN_E_SUCCESS) {
+ if (lockdown_error != LOCKDOWN_E_SUCCESS) {
error("ERROR: Unable to place device in recovery mode\n");
lockdownd_client_free(lockdown);
plist_free(tss_response);
@@ -224,117 +220,212 @@ int main(int argc, char* argv[]) {
device = NULL;
}
- recovery_error = irecv_open(&recovery, uuid);
- while(recovery_error != IRECV_E_SUCCESS) {
+ if (send_ibec(ipsw, tss_response) < 0) {
+ error("ERROR: Unable to send iBEC\n");
+ return -1;
+ }
+
+ // Reconnect to iBEC
+ info("Connecting to iBEC\n");
+ recovery_error = irecv_open(&recovery);
+ 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;
+ recovery_error = irecv_open(&recovery);
+ if (recovery_error == IRECV_E_SUCCESS) {
break;
}
}
- info("Extracting iBEC from IPSW\n");
- archive = ipsw_open(ipsw);
- if(archive == NULL) {
- error("ERROR: Unable to open IPSW\n");
+ // Sending DeviceTree
+ info("Extracting DeviceTree from IPSW\n");
+ plist_t devicetree_entry = plist_dict_get_item(tss_response, "RestoreDeviceTree");
+ if (!devicetree_entry || plist_get_node_type(devicetree_entry) != PLIST_DICT) {
+ error("ERROR: Unable to find DeviceTree entry in TSS response\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");
+ char* devicetree_path = NULL;
+ plist_t devicetree_path_node = plist_dict_get_item(devicetree_entry, "Path");
+ if (!devicetree_path_node || plist_get_node_type(devicetree_path_node) != PLIST_STRING) {
+ error("ERROR: Unable to find DeviceTree path in entry\n");
plist_free(tss_response);
+ plist_free(devicetree_entry);
irecv_close(recovery);
- ipsw_close(archive);
+ recovery = NULL;
return -1;
}
+ plist_get_string_val(devicetree_path_node, &devicetree_path);
- 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");
+ char* devicetree_blob = NULL;
+ uint64_t devicetree_blob_size = 0;
+ plist_t devicetree_blob_node = plist_dict_get_item(devicetree_entry, "Blob");
+ if (!devicetree_blob_node || plist_get_node_type(devicetree_blob_node) != PLIST_DATA) {
+ error("ERROR: Unable to find DeviceTree blob in entry\n");
plist_free(tss_response);
- plist_free(ibec_entry);
+ plist_free(devicetree_entry);
irecv_close(recovery);
- ipsw_close(archive);
recovery = NULL;
return -1;
}
- plist_get_string_val(ibec_path_node, &ibec_path);
+ plist_get_data_val(devicetree_blob_node, &devicetree_blob, &devicetree_blob_size);
+ plist_free(devicetree_blob_node);
+ plist_free(devicetree_entry);
- char* ibec_blob = NULL;
- uint64_t ibec_blob_size = 0;
- plist_t ibec_blob_node = plist_dict_get_item(ibec_entry, "Blob");
- if(!ibec_blob_node || plist_get_node_type(ibec_blob_node) != PLIST_DATA) {
- error("ERROR: Unable to find iBEC blob in entry\n");
- plist_free(tss_response);
- plist_free(ibec_entry);
+ ipsw_file* devicetree = ipsw_extract_file(ipsw, devicetree_path);
+ if (devicetree == NULL) {
+ error("ERROR: Unable to extract %s from IPSW\n", devicetree_path);
irecv_close(recovery);
- ipsw_close(archive);
recovery = NULL;
return -1;
}
- plist_get_data_val(ibec_blob_node, &ibec_blob, &ibec_blob_size);
- plist_free(ibec_blob_node);
- 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);
+ img3_file* devicetree_img3 = img3_parse_file(devicetree->data, devicetree->size);
+ if (devicetree_img3 == NULL) {
+ error("ERROR: Unable to parse IMG3: %s\n", devicetree_path);
+ irecv_close(recovery);
+ ipsw_free_file(devicetree);
+ recovery = NULL;
+ return -1;
+ }
+ ipsw_free_file(devicetree);
+
+ img3_replace_signature(devicetree_img3, devicetree_blob);
+ free(devicetree_blob);
+
+ int devicetree_size = 0;
+ char* devicetree_data = NULL;
+ img3_get_data(devicetree_img3, &devicetree_data, &devicetree_size);
+ write_file("devicetree.img3", devicetree_data, devicetree_size);
+ recovery_error = irecv_send_buffer(recovery, devicetree_data, devicetree_size);
+ if (recovery_error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to send IMG3: %s\n", devicetree_path);
irecv_close(recovery);
- ipsw_close(archive);
+ img3_free(devicetree_img3);
recovery = NULL;
return -1;
}
- ipsw_close(archive);
+ img3_free(devicetree_img3);
- 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);
+ recovery_error = irecv_send_command(recovery, "devicetree");
+ if (recovery_error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to execute DeviceTree\n");
irecv_close(recovery);
- ipsw_free_file(ibec);
+ img3_free(devicetree_img3);
recovery = NULL;
return -1;
}
- ipsw_free_file(ibec);
+ free(devicetree_data);
+ sleep(1);
+
+ // Sending RestoreRamdisk
+ info("Extracting Ramdisk from IPSW\n");
+ plist_t ramdisk_entry = plist_dict_get_item(tss_response, "RestoreRamDisk");
+ if (!ramdisk_entry || plist_get_node_type(ramdisk_entry) != PLIST_DICT) {
+ error("ERROR: Unable to find RestoreRamDisk entry in TSS response\n");
+ plist_free(tss_response);
+ irecv_close(recovery);
+ return -1;
+ }
- img3_replace_signature(ibec_img3, ibec_blob);
+ char* ramdisk_path = NULL;
+ plist_t ramdisk_path_node = plist_dict_get_item(ramdisk_entry, "Path");
+ if (!ramdisk_path_node || plist_get_node_type(ramdisk_path_node) != PLIST_STRING) {
+ error("ERROR: Unable to find RestoreRamDisk path in entry\n");
+ plist_free(tss_response);
+ plist_free(ramdisk_entry);
+ irecv_close(recovery);
+ recovery = NULL;
+ return -1;
+ }
+ plist_get_string_val(ramdisk_path_node, &ramdisk_path);
- int ibec_size = 0;
- char* ibec_data = NULL;
- img3_get_data(ibec_img3, &ibec_data, &ibec_size);
- write_file("ibec.dfu", ibec_data, ibec_size);
- recovery_error = irecv_send_buffer(recovery, ibec_data, ibec_size);
- if(recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to send IMG3: %s\n", ibec_path);
+ char* ramdisk_blob = NULL;
+ uint64_t ramdisk_blob_size = 0;
+ plist_t ramdisk_blob_node = plist_dict_get_item(ramdisk_entry, "Blob");
+ if (!ramdisk_blob_node || plist_get_node_type(ramdisk_blob_node) != PLIST_DATA) {
+ error("ERROR: Unable to find RestoreRamdisk blob in entry\n");
+ plist_free(tss_response);
+ plist_free(ramdisk_entry);
irecv_close(recovery);
- img3_free(ibec_img3);
recovery = NULL;
return -1;
}
+ plist_get_data_val(ramdisk_blob_node, &ramdisk_blob, &ramdisk_blob_size);
+ plist_free(ramdisk_blob_node);
+ plist_free(ramdisk_entry);
- recovery_error = irecv_send_command(recovery, "go");
- if(recovery_error != IRECV_E_SUCCESS) {
- error("ERROR: Unable to execute iBEC\n");
+ ipsw_file* ramdisk = ipsw_extract_file(ipsw, ramdisk_path);
+ if (ramdisk == NULL) {
+ error("ERROR: Unable to extract %s from IPSW\n", ramdisk_path);
irecv_close(recovery);
- img3_free(ibec_img3);
recovery = NULL;
return -1;
}
- free(ibec_data);
+ img3_file* ramdisk_img3 = img3_parse_file(ramdisk->data, ramdisk->size);
+ if (ramdisk_img3 == NULL) {
+ error("ERROR: Unable to parse IMG3: %s\n", ramdisk_path);
+ irecv_close(recovery);
+ ipsw_free_file(ramdisk);
+ recovery = NULL;
+ return -1;
+ }
+ ipsw_free_file(ramdisk);
+
+ img3_replace_signature(ramdisk_img3, ramdisk_blob);
+ free(ramdisk_blob);
+
+ int ramdisk_size = 0;
+ char* ramdisk_data = NULL;
+ img3_get_data(ramdisk_img3, &ramdisk_data, &ramdisk_size);
+ write_file("ramdisk.dmg", ramdisk_data, ramdisk_size);
+ recovery_error = irecv_send_buffer(recovery, ramdisk_data, ramdisk_size);
+ if (recovery_error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to send IMG3: %s\n", ramdisk_path);
+ irecv_close(recovery);
+ img3_free(ramdisk_img3);
+ recovery = NULL;
+ return -1;
+ }
+ img3_free(ramdisk_img3);
+
+ recovery_error = irecv_send_command(recovery, "ramdisk");
+ if (recovery_error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to execute DeviceTree\n");
+ irecv_close(recovery);
+ recovery = NULL;
+ return -1;
+ }
+ free(ramdisk_data);
+ irecv_close(recovery);
+ recovery = NULL;
+
+ printf("Please unplug your device, then plug it back in, hit any key to continue\n");
+ getchar();
+
+ // Reconnect to iBEC
+ recovery_error = irecv_open(&recovery);
+ while (recovery_error != IRECV_E_SUCCESS) {
+ sleep(1);
+ info("Retrying connection...\n");
+ recovery_error = irecv_open(&recovery);
+ if (recovery_error == IRECV_E_SUCCESS) {
+ break;
+ }
+ }
+
irecv_close(recovery);
+ recovery = NULL;
plist_free(tss_response);
return 0;
}
void usage(int argc, char* argv[]) {
char *name = strrchr(argv[0], '/');
- printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
+ printf("Usage: %s [OPTIONS]\n", (name ? name + 1 : argv[0]));
printf("Restore firmware and filesystem to iPhone/iPod Touch.\n");
printf(" -d, \t\tenable communication debugging\n");
printf(" -v, \t\tenable incremental levels of verboseness\n");
@@ -357,10 +448,218 @@ int write_file(const char* filename, char* data, int size) {
int bytes = fwrite(data, 1, size, file);
fclose(file);
- if(bytes != size) {
+ if (bytes != size) {
error("ERROR: Unable to write entire file: %s: %d %d\n", filename, bytes, size);
return -1;
}
return size;
}
+
+int get_tss_data(plist_t tss, const char* entry, char** ppath, char** pblob) {
+ *ppath = NULL;
+ *pblob = NULL;
+
+ plist_t node = plist_dict_get_item(tss, entry);
+ if (!node || plist_get_node_type(node) != PLIST_DICT) {
+ error("ERROR: Unable to find %s entry in TSS response\n", entry);
+ return -1;
+ }
+
+ char* path = NULL;
+ plist_t path_node = plist_dict_get_item(node, "Path");
+ if (!path_node || plist_get_node_type(path_node) != PLIST_STRING) {
+ error("ERROR: Unable to find %s path in entry\n", entry);
+ plist_free(node);
+ return -1;
+ }
+ plist_get_string_val(path_node, &path);
+ plist_free(path_node);
+
+ char* blob = NULL;
+ uint64_t blob_size = 0;
+ plist_t blob_node = plist_dict_get_item(node, "Blob");
+ if (!blob_node || plist_get_node_type(blob_node) != PLIST_DATA) {
+ error("ERROR: Unable to find %s blob in entry\n", entry);
+ plist_free(node);
+ free(path);
+ return -1;
+ }
+
+ plist_get_data_val(blob_node, &blob, &blob_size);
+ plist_free(blob_node);
+ plist_free(node);
+
+ *ppath = path;
+ *pblob = blob;
+ return 0;
+}
+
+int send_ibec(char* ipsw, plist_t tss) {
+ int i = 0;
+ irecv_client_t client = NULL;
+ info("Connecting to iBoot...\n");
+ irecv_error_t error = irecv_open(&client);
+ for (i = 10; i > 0; i--) {
+ if (error == IRECV_E_SUCCESS) {
+ irecv_send_command(client, "setenv auto-boot true");
+ irecv_send_command(client, "saveenv");
+ break;
+ }
+ sleep(1);
+ info("Retrying connection...\n");
+ error = irecv_open(&client);
+ }
+
+ char* path = NULL;
+ char* blob = NULL;
+ info("Extracting iBEC data from TSS response\n");
+ if (get_tss_data(tss, "iBEC", &path, &blob) < 0) {
+ error("ERROR: Unable to get data for TSS entry\n");
+ irecv_close(client);
+ client = NULL;
+ return -1;
+ }
+
+ info("Extracting %s from %s\n", path, ipsw);
+ ipsw_file* ibec = ipsw_extract_file(ipsw, path);
+ if (ibec == NULL) {
+ error("ERROR: Unable to extract %s from %s\n", path, ipsw);
+ irecv_close(client);
+ client = NULL;
+ free(path);
+ free(blob);
+ return -1;
+ }
+
+ img3_file* img3 = img3_parse_file(ibec->data, ibec->size);
+ if (img3 == NULL) {
+ error("ERROR: Unable to parse IMG3: %s\n", path);
+ ipsw_free_file(ibec);
+ irecv_close(client);
+ client = NULL;
+ free(path);
+ free(blob);
+ return -1;
+ }
+ if (ibec) {
+ ipsw_free_file(ibec);
+ ibec = NULL;
+ }
+
+ if (img3_replace_signature(img3, blob) < 0) {
+ error("ERROR: Unable to replace IMG3 signature\n");
+ irecv_close(client);
+ client = NULL;
+ free(path);
+ free(blob);
+ return -1;
+ }
+ if (blob) {
+ free(blob);
+ blob = NULL;
+ }
+
+ int size = 0;
+ char* data = NULL;
+ if (img3_get_data(img3, &data, &size) < 0) {
+ error("ERROR: Unable to reconstruct IMG3\n");
+ irecv_close(client);
+ img3_free(img3);
+ client = NULL;
+ free(path);
+ return -1;
+ }
+
+ path = strrchr(path, '/');
+ write_file(path + 1, data, size);
+ error = irecv_send_buffer(client, data, size);
+ if (error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to send IMG3: %s\n", path);
+ irecv_close(client);
+ img3_free(img3);
+ client = NULL;
+ free(data);
+ free(path);
+ return -1;
+ }
+ if (img3) {
+ img3_free(img3);
+ img3 = NULL;
+ }
+ if (data) {
+ free(data);
+ data = NULL;
+ }
+ if (path) {
+ free(path);
+ path = NULL;
+ }
+
+ error = irecv_send_command(client, "go");
+ if (error != IRECV_E_SUCCESS) {
+ error("ERROR: Unable to execute iBEC\n");
+ irecv_close(client);
+ client = NULL;
+ free(data);
+ return -1;
+ }
+
+ irecv_close(client);
+ client = NULL;
+ return 0;
+}
+
+int send_devicetree(char* ipsw, plist_t tss) {
+ int i = 0;
+ info("Sending devicetree\n");
+ irecv_client_t client = NULL;
+ irecv_error_t error = irecv_open(&client);
+ for (i = 10; i > 0; i--) {
+ if (error == IRECV_E_SUCCESS) {
+ break;
+ }
+ sleep(1);
+ info("Retrying connection...\n");
+ error = irecv_open(&client);
+ }
+
+ irecv_close(client);
+ return 0;
+}
+
+int send_ramdisk(char* ipsw, plist_t tss) {
+ int i = 0;
+ info("Sending ramdisk\n");
+ irecv_client_t client = NULL;
+ irecv_error_t error = irecv_open(&client);
+ for (i = 10; i > 0; i--) {
+ if (error == IRECV_E_SUCCESS) {
+ break;
+ }
+ sleep(1);
+ info("Retrying connection...\n");
+ error = irecv_open(&client);
+ }
+
+ irecv_close(client);
+ return 0;
+}
+
+int send_kernelcache(char* ipsw, plist_t tss) {
+ int i = 0;
+ info("Sending kernelcache\n");
+ irecv_client_t client = NULL;
+ irecv_error_t error = irecv_open(&client);
+ for (i = 10; i > 0; i--) {
+ if (error == IRECV_E_SUCCESS) {
+ break;
+ }
+ sleep(1);
+ info("Retrying connection...\n");
+ error = irecv_open(&client);
+ }
+
+ irecv_close(client);
+ return 0;
+}
diff --git a/src/ipsw.c b/src/ipsw.c
index f601201..56fd216 100644
--- a/src/ipsw.c
+++ b/src/ipsw.c
@@ -26,6 +26,13 @@
#include "ipsw.h"
#include "idevicerestore.h"
+typedef struct {
+ struct zip* zip;
+} ipsw_archive;
+
+ipsw_archive* ipsw_open(const char* ipsw);
+void ipsw_close(ipsw_archive* archive);
+
ipsw_archive* ipsw_open(const char* ipsw) {
int err = 0;
ipsw_archive* archive = (ipsw_archive*) malloc(sizeof(ipsw_archive));
@@ -44,7 +51,8 @@ ipsw_archive* ipsw_open(const char* ipsw) {
return archive;
}
-ipsw_file* ipsw_extract_file(ipsw_archive* archive, const char* filename) {
+ipsw_file* ipsw_extract_file(const char* ipsw, const char* filename) {
+ ipsw_archive* archive = ipsw_open(ipsw);
if(archive == NULL || archive->zip == NULL) {
error("ERROR: Invalid archive\n");
return NULL;
@@ -95,6 +103,7 @@ ipsw_file* ipsw_extract_file(ipsw_archive* archive, const char* filename) {
}
zip_fclose(zfile);
+ ipsw_close(archive);
return file;
}
diff --git a/src/ipsw.h b/src/ipsw.h
index 5cbad19..6a49937 100644
--- a/src/ipsw.h
+++ b/src/ipsw.h
@@ -25,19 +25,13 @@
#include <zip.h>
typedef struct {
- struct zip* zip;
-} ipsw_archive;
-
-typedef struct {
int index;
char* name;
unsigned int size;
unsigned char* data;
} ipsw_file;
-ipsw_archive* ipsw_open(const char* ipsw);
-ipsw_file* ipsw_extract_file(ipsw_archive* archive, const char* filename);
+ipsw_file* ipsw_extract_file(const char* ipsw, const char* filename);
void ipsw_free_file(ipsw_file* file);
-void ipsw_close(ipsw_archive* archive);
#endif
diff --git a/src/tss.c b/src/tss.c
index 2b2991d..81b0658 100644
--- a/src/tss.c
+++ b/src/tss.c
@@ -109,6 +109,7 @@ plist_t tss_create_request(plist_t buildmanifest, uint64_t ecid) {
plist_dict_insert_item(tss_request, "ApBoardID", plist_new_uint(board_id));
plist_dict_insert_item(tss_request, "ApSecurityDomain", plist_new_uint(security_domain));
plist_dict_insert_item(tss_request, "UniqueBuildID", plist_new_data(unique_build_data, unique_build_size));
+ free(unique_build_data);
// Add all firmware files to TSS request
plist_t manifest_node = plist_dict_get_item(restore_identity_dict, "Manifest");
@@ -135,11 +136,13 @@ plist_t tss_create_request(plist_t buildmanifest, uint64_t ecid) {
plist_dict_insert_item(tss_request, key, tss_entry);
free(key);
}
+ plist_free(manifest_node);
int sz = 0;
char* xml = NULL;
plist_to_xml(tss_request, &xml, &sz);
- printf("%s", xml);
+ debug("%s", xml);
+ free(xml);
return tss_request;
}
@@ -218,7 +221,8 @@ plist_t tss_send_request(plist_t tss_request) {
int sz = 0;
char* xml = NULL;
plist_to_xml(tss_response, &xml, &sz);
- printf("%s", xml);
+ debug("%s", xml);
+ free(xml);
return tss_response;
}