summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/idevicerestore.c25
-rw-r--r--src/img3.c162
-rw-r--r--src/img3.h37
3 files changed, 208 insertions, 16 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 0b294b9..0a5e7f1 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -260,8 +260,25 @@ int main(int argc, char* argv[]) {
plist_free(ibec_entry);
irecv_close(recovery);
ipsw_close(archive);
+ recovery = NULL;
+ return -1;
}
plist_get_string_val(ibec_path_node, &ibec_path);
+
+ 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);
+ 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);
@@ -269,6 +286,7 @@ int main(int argc, char* argv[]) {
error("ERROR: Unable to extract %s from IPSW\n", ibec_path);
irecv_close(recovery);
ipsw_close(archive);
+ recovery = NULL;
return -1;
}
ipsw_close(archive);
@@ -278,16 +296,19 @@ int main(int argc, char* argv[]) {
error("ERROR: Unable to parse IMG3: %s\n", ibec_path);
irecv_close(recovery);
ipsw_free_file(ibec);
+ recovery = NULL;
return -1;
}
ipsw_free_file(ibec);
- tss_stitch_img3(tss_response, &ibec_img3);
- recovery_error = irecv_send_file(recovery, ibec_img3->data);
+ img3_replace_signature(ibec_img3, ibec_blob);
+ recovery_error = irecv_send_file(recovery, img3_get_data(ibec_img3));
if(recovery_error != IRECV_E_SUCCESS) {
error("ERROR: Unable to send IMG3: %s\n", ibec_path);
irecv_close(recovery);
img3_free(ibec_img3);
+ recovery = NULL;
+ return -1;
}
irecv_close(recovery);
diff --git a/src/img3.c b/src/img3.c
index 4daa6b6..cf2e91c 100644
--- a/src/img3.c
+++ b/src/img3.c
@@ -21,21 +21,171 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "img3.h"
#include "idevicerestore.h"
-img3_file* img3_parse_file(unsigned char* data, unsigned int size) {
+img3_file* img3_parse_file(unsigned char* data, int size) {
+ int data_offset = 0;
img3_header* header = (img3_header*) data;
- if(header->imageType != kImg3Container) {
+ if(header->signature != kImg3Container) {
error("ERROR: Invalid IMG3 file\n");
return NULL;
}
- return NULL;
+
+ img3_file* image = (img3_file*) malloc(sizeof(img3_file));
+ if(image == NULL) {
+ error("ERROR: Unable to allocate memory for IMG3 file\n");
+ return NULL;
+ }
+ memset(image, '\0', sizeof(img3_file));
+
+ image->header = (img3_header*) malloc(sizeof(img3_header));
+ if(image->header == NULL) {
+ error("ERROR: Unable to allocate memory for IMG3 header\n");
+ img3_free(image);
+ return NULL;
+ }
+ memcpy(image->header, data, sizeof(img3_header));
+ data_offset += sizeof(img3_header);
+
+ img3_element_header* current = NULL;
+ while(data_offset < size) {
+ current = (img3_element_header*) &data[data_offset];
+ switch(current->signature) {
+ case kTypeElement:
+ image->type_element = img3_parse_element(&data[data_offset]);
+ if(image->type_element == NULL) {
+ error("ERROR: Unable to parse TYPE element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed TYPE element\n");
+ break;
+
+ case kDataElement:
+ image->data_element = img3_parse_element(&data[data_offset]);
+ if(image->data_element == NULL) {
+ error("ERROR: Unable to parse DATA element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed DATA element\n");
+ break;
+
+ case kVersElement:
+ image->vers_element = img3_parse_element(&data[data_offset]);
+ if(image->vers_element == NULL) {
+ error("ERROR: Unable to parse VERS element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed VERS element\n");
+ break;
+
+ case kSepoElement:
+ image->sepo_element = img3_parse_element(&data[data_offset]);
+ if(image->sepo_element == NULL) {
+ error("ERROR: Unable to parse SEPO element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed SEPO element\n");
+ break;
+
+ case kBordElement:
+ image->bord_element = img3_parse_element(&data[data_offset]);
+ if(image->bord_element == NULL) {
+ error("ERROR: Unable to parse BORD element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed BORD element\n");
+ break;
+
+ case kKbagElement:
+ if(image->kbag1_element == NULL) {
+ image->kbag1_element = img3_parse_element(&data[data_offset]);
+ image->kbag1_element = img3_parse_element(&data[data_offset]);
+ if(image->kbag1_element == NULL) {
+ error("ERROR: Unable to parse first KBAG element\n");
+ img3_free(image);
+ return NULL;
+ }
+
+ } else {
+ image->kbag2_element = img3_parse_element(&data[data_offset]);
+ image->kbag2_element = img3_parse_element(&data[data_offset]);
+ if(image->kbag2_element == NULL) {
+ error("ERROR: Unable to parse second KBAG element\n");
+ img3_free(image);
+ return NULL;
+ }
+ }
+ debug("Parsed KBAG element\n");
+ break;
+
+ case kEcidElement:
+ image->ecid_element = img3_parse_element(&data[data_offset]);
+ if(image->ecid_element == NULL) {
+ error("ERROR: Unable to parse ECID element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed ECID element\n");
+ break;
+
+ case kShshElement:
+ image->shsh_element = img3_parse_element(&data[data_offset]);
+ if(image->shsh_element == NULL) {
+ error("ERROR: Unable to parse SHSH element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed SHSH element\n");
+ break;
+
+ case kCertElement:
+ image->cert_element = img3_parse_element(&data[data_offset]);
+ if(image->cert_element == NULL) {
+ error("ERROR: Unable to parse CERT element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed CERT element\n");
+ break;
+
+ default:
+ error("ERROR: Unknown IMG3 element type\n");
+ img3_free(image);
+ return NULL;
+ }
+ data_offset += current->full_size;
+ }
+
+ return image;
+}
+
+img3_element* img3_parse_element(char* element) {
+ img3_element_header* element_header = (img3_element_header*) element;
+ return 1;
}
-void img3_free(img3_file* file) {
- if(file != NULL) {
- free(file);
+void img3_free(img3_file* image) {
+ if(image != NULL) {
+ if(image->header != NULL) {
+ free(image->header);
+ }
+
+ free(image);
}
}
+
+void img3_replace_signature(img3_file* image, char* signature) {
+ return;
+}
+
+char* img3_get_data(img3_file* image) {
+ return NULL;
+}
diff --git a/src/img3.h b/src/img3.h
index 75fcd5c..f2519f0 100644
--- a/src/img3.h
+++ b/src/img3.h
@@ -38,6 +38,7 @@ typedef enum {
kChipElement = 0x43484950, // CHIP
kProdElement = 0x50524F44, // PROD
kSdomElement = 0x53444F4D, // SDOM
+ kVersElement = 0x56455253, // VERS
kBordElement = 0x424F5244, // BORD
kSepoElement = 0x5345504F, // SEPO
kEcidElement = 0x45434944 // ECID
@@ -45,23 +46,43 @@ typedef enum {
typedef struct {
unsigned int signature;
- unsigned int fullSize;
- unsigned int dataSize;
- unsigned int shshOffset;
- unsigned int imageType;
+ unsigned int full_size;
+ unsigned int data_size;
+ unsigned int shsh_offset;
+ unsigned int image_type;
} img3_header;
typedef struct {
unsigned int signature;
- unsigned int fullSize;
- unsigned int dataSize;
+ unsigned int full_size;
+ unsigned int data_size;
} img3_element_header;
typedef struct {
+ img3_element_header* header;
+ img3_element_type type;
unsigned char* data;
+} img3_element;
+
+typedef struct {
+ char* data;
+ img3_header* header;
+ img3_element* type_element;
+ img3_element* data_element;
+ img3_element* vers_element;
+ img3_element* sepo_element;
+ img3_element* bord_element;
+ img3_element* kbag1_element;
+ img3_element* kbag2_element;
+ img3_element* ecid_element;
+ img3_element* shsh_element;
+ img3_element* cert_element;
} img3_file;
-img3_file* img3_parse_file(unsigned char* data, unsigned int size);
-void img3_free(img3_file* file);
+img3_file* img3_parse_file(unsigned char* data, int size);
+img3_element* img3_parse_element(char* data);
+void img3_replace_signature(img3_file* image, char* signature);
+void img3_free(img3_file* image);
+char* img3_get_data(img3_file* image);
#endif