diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/idevicerestore.c | 25 | ||||
-rw-r--r-- | src/img3.c | 162 | ||||
-rw-r--r-- | src/img3.h | 37 |
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); @@ -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; +} @@ -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 |