summaryrefslogtreecommitdiffstats
path: root/src/img3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/img3.c')
-rw-r--r--src/img3.c143
1 files changed, 83 insertions, 60 deletions
diff --git a/src/img3.c b/src/img3.c
index ec7bcbf..1969ece 100644
--- a/src/img3.c
+++ b/src/img3.c
@@ -24,25 +24,26 @@
#include <string.h>
#include "img3.h"
+#include "common.h"
#include "idevicerestore.h"
img3_file* img3_parse_file(char* data, int size) {
int data_offset = 0;
img3_header* header = (img3_header*) data;
- if(header->signature != kImg3Container) {
+ if (header->signature != kImg3Container) {
error("ERROR: Invalid IMG3 file\n");
return NULL;
}
img3_file* image = (img3_file*) malloc(sizeof(img3_file));
- if(image == NULL) {
+ 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) {
+ if (image->header == NULL) {
error("ERROR: Unable to allocate memory for IMG3 header\n");
img3_free(image);
return NULL;
@@ -51,12 +52,12 @@ img3_file* img3_parse_file(char* data, int size) {
data_offset += sizeof(img3_header);
img3_element_header* current = NULL;
- while(data_offset < size) {
+ while (data_offset < size) {
current = (img3_element_header*) &data[data_offset];
- switch(current->signature) {
+ switch (current->signature) {
case kTypeElement:
image->type_element = img3_parse_element(&data[data_offset]);
- if(image->type_element == NULL) {
+ if (image->type_element == NULL) {
error("ERROR: Unable to parse TYPE element\n");
img3_free(image);
return NULL;
@@ -66,7 +67,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kDataElement:
image->data_element = img3_parse_element(&data[data_offset]);
- if(image->data_element == NULL) {
+ if (image->data_element == NULL) {
error("ERROR: Unable to parse DATA element\n");
img3_free(image);
return NULL;
@@ -76,7 +77,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kVersElement:
image->vers_element = img3_parse_element(&data[data_offset]);
- if(image->vers_element == NULL) {
+ if (image->vers_element == NULL) {
error("ERROR: Unable to parse VERS element\n");
img3_free(image);
return NULL;
@@ -86,7 +87,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kSepoElement:
image->sepo_element = img3_parse_element(&data[data_offset]);
- if(image->sepo_element == NULL) {
+ if (image->sepo_element == NULL) {
error("ERROR: Unable to parse SEPO element\n");
img3_free(image);
return NULL;
@@ -96,7 +97,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kBordElement:
image->bord_element = img3_parse_element(&data[data_offset]);
- if(image->bord_element == NULL) {
+ if (image->bord_element == NULL) {
error("ERROR: Unable to parse BORD element\n");
img3_free(image);
return NULL;
@@ -105,9 +106,9 @@ img3_file* img3_parse_file(char* data, int size) {
break;
case kKbagElement:
- if(image->kbag1_element == NULL) {
+ if (image->kbag1_element == NULL) {
image->kbag1_element = img3_parse_element(&data[data_offset]);
- if(image->kbag1_element == NULL) {
+ if (image->kbag1_element == NULL) {
error("ERROR: Unable to parse first KBAG element\n");
img3_free(image);
return NULL;
@@ -115,7 +116,7 @@ img3_file* img3_parse_file(char* data, int size) {
} else {
image->kbag2_element = img3_parse_element(&data[data_offset]);
- if(image->kbag2_element == NULL) {
+ if (image->kbag2_element == NULL) {
error("ERROR: Unable to parse second KBAG element\n");
img3_free(image);
return NULL;
@@ -126,7 +127,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kEcidElement:
image->ecid_element = img3_parse_element(&data[data_offset]);
- if(image->ecid_element == NULL) {
+ if (image->ecid_element == NULL) {
error("ERROR: Unable to parse ECID element\n");
img3_free(image);
return NULL;
@@ -136,7 +137,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kShshElement:
image->shsh_element = img3_parse_element(&data[data_offset]);
- if(image->shsh_element == NULL) {
+ if (image->shsh_element == NULL) {
error("ERROR: Unable to parse SHSH element\n");
img3_free(image);
return NULL;
@@ -146,7 +147,7 @@ img3_file* img3_parse_file(char* data, int size) {
case kCertElement:
image->cert_element = img3_parse_element(&data[data_offset]);
- if(image->cert_element == NULL) {
+ if (image->cert_element == NULL) {
error("ERROR: Unable to parse CERT element\n");
img3_free(image);
return NULL;
@@ -154,6 +155,16 @@ img3_file* img3_parse_file(char* data, int size) {
debug("Parsed CERT element\n");
break;
+ case kUnknElement:
+ image->unkn_element = img3_parse_element(&data[data_offset]);
+ if (image->unkn_element == NULL) {
+ error("ERROR: Unable to parse UNKN element\n");
+ img3_free(image);
+ return NULL;
+ }
+ debug("Parsed UNKN element\n");
+ break;
+
default:
error("ERROR: Unknown IMG3 element type\n");
img3_free(image);
@@ -168,14 +179,14 @@ img3_file* img3_parse_file(char* data, int size) {
img3_element* img3_parse_element(char* data) {
img3_element_header* element_header = (img3_element_header*) data;
img3_element* element = (img3_element*) malloc(sizeof(img3_element));
- if(element == NULL) {
+ if (element == NULL) {
error("ERROR: Unable to allocate memory for IMG3 element\n");
return NULL;
}
memset(element, '\0', sizeof(img3_element));
element->data = (char*) malloc(element_header->full_size);
- if(element->data == NULL) {
+ if (element->data == NULL) {
error("ERROR: Unable to allocate memory for IMG3 element data\n");
free(element);
return NULL;
@@ -188,69 +199,74 @@ img3_element* img3_parse_element(char* data) {
}
void img3_free(img3_file* image) {
- if(image != NULL) {
- if(image->header != NULL) {
+ if (image != NULL) {
+ if (image->header != NULL) {
free(image->header);
}
- if(image->type_element != NULL) {
+ if (image->type_element != NULL) {
img3_free_element(image->type_element);
image->type_element = NULL;
}
- if(image->data_element != NULL) {
+ if (image->data_element != NULL) {
img3_free_element(image->data_element);
image->data_element = NULL;
}
- if(image->vers_element != NULL) {
+ if (image->vers_element != NULL) {
img3_free_element(image->vers_element);
image->vers_element = NULL;
}
- if(image->sepo_element != NULL) {
+ if (image->sepo_element != NULL) {
img3_free_element(image->sepo_element);
image->sepo_element = NULL;
}
- if(image->bord_element != NULL) {
+ if (image->bord_element != NULL) {
img3_free_element(image->bord_element);
image->bord_element = NULL;
}
- if(image->kbag1_element != NULL) {
+ if (image->kbag1_element != NULL) {
img3_free_element(image->kbag1_element);
image->kbag1_element = NULL;
}
- if(image->kbag2_element != NULL) {
+ if (image->kbag2_element != NULL) {
img3_free_element(image->kbag2_element);
image->kbag2_element = NULL;
}
- if(image->ecid_element != NULL) {
+ if (image->ecid_element != NULL) {
img3_free_element(image->ecid_element);
image->ecid_element = NULL;
}
- if(image->shsh_element != NULL) {
+ if (image->shsh_element != NULL) {
img3_free_element(image->shsh_element);
image->shsh_element = NULL;
}
- if(image->cert_element != NULL) {
+ if (image->cert_element != NULL) {
img3_free_element(image->cert_element);
image->cert_element = NULL;
}
+ if (image->unkn_element != NULL) {
+ img3_free_element(image->unkn_element);
+ image->unkn_element = NULL;
+ }
+
free(image);
image = NULL;
}
}
void img3_free_element(img3_element* element) {
- if(element != NULL) {
- if(element->data != NULL) {
+ if (element != NULL) {
+ if (element->data != NULL) {
free(element->data);
element->data = NULL;
}
@@ -262,37 +278,37 @@ void img3_free_element(img3_element* element) {
int img3_replace_signature(img3_file* image, char* signature) {
int offset = 0;
img3_element* ecid = img3_parse_element(&signature[offset]);
- if(ecid == NULL || ecid->type != kEcidElement) {
+ if (ecid == NULL || ecid->type != kEcidElement) {
error("ERROR: Unable to find ECID element in signature\n");
return -1;
}
offset += ecid->header->full_size;
img3_element* shsh = img3_parse_element(&signature[offset]);
- if(shsh == NULL || shsh->type != kShshElement) {
+ if (shsh == NULL || shsh->type != kShshElement) {
error("ERROR: Unable to find SHSH element in signature\n");
return -1;
}
offset += shsh->header->full_size;
img3_element* cert = img3_parse_element(&signature[offset]);
- if(cert == NULL || cert->type != kCertElement) {
+ if (cert == NULL || cert->type != kCertElement) {
error("ERROR: Unable to find CERT element in signature\n");
return -1;
}
offset += cert->header->full_size;
- if(image->ecid_element != NULL) {
+ if (image->ecid_element != NULL) {
img3_free_element(image->ecid_element);
}
image->ecid_element = ecid;
- if(image->shsh_element != NULL) {
+ if (image->shsh_element != NULL) {
img3_free_element(image->shsh_element);
}
image->shsh_element = shsh;
- if(image->cert_element != NULL) {
+ if (image->cert_element != NULL) {
img3_free_element(image->cert_element);
}
image->cert_element = cert;
@@ -305,39 +321,42 @@ int img3_get_data(img3_file* image, char** pdata, int* psize) {
int size = sizeof(img3_header);
// Add up the size of the image first so we can allocate our memory
- if(image->type_element != NULL) {
+ if (image->type_element != NULL) {
size += image->type_element->header->full_size;
}
- if(image->data_element != NULL) {
+ if (image->data_element != NULL) {
size += image->data_element->header->full_size;
}
- if(image->vers_element != NULL) {
+ if (image->vers_element != NULL) {
size += image->vers_element->header->full_size;
}
- if(image->sepo_element != NULL) {
+ if (image->sepo_element != NULL) {
size += image->sepo_element->header->full_size;
}
- if(image->bord_element != NULL) {
+ if (image->bord_element != NULL) {
size += image->bord_element->header->full_size;
}
- if(image->kbag1_element != NULL) {
+ if (image->kbag1_element != NULL) {
size += image->kbag1_element->header->full_size;
}
- if(image->kbag2_element != NULL) {
+ if (image->kbag2_element != NULL) {
size += image->kbag2_element->header->full_size;
}
- if(image->ecid_element != NULL) {
+ if (image->ecid_element != NULL) {
size += image->ecid_element->header->full_size;
}
- if(image->shsh_element != NULL) {
+ if (image->shsh_element != NULL) {
size += image->shsh_element->header->full_size;
}
- if(image->cert_element != NULL) {
+ if (image->cert_element != NULL) {
size += image->cert_element->header->full_size;
}
+ if (image->unkn_element != NULL) {
+ size += image->unkn_element->header->full_size;
+ }
char* data = (char*) malloc(size);
- if(data == NULL) {
+ if (data == NULL) {
error("ERROR: Unable to allocate memory for IMG3 data\n");
return -1;
}
@@ -351,49 +370,53 @@ int img3_get_data(img3_file* image, char** pdata, int* psize) {
offset += sizeof(img3_header);
// Copy each section over to the new buffer
- if(image->type_element != NULL) {
+ if (image->type_element != NULL) {
memcpy(&data[offset], image->type_element->data, image->type_element->header->full_size);
offset += image->type_element->header->full_size;
}
- if(image->data_element != NULL) {
+ if (image->data_element != NULL) {
memcpy(&data[offset], image->data_element->data, image->data_element->header->full_size);
offset += image->data_element->header->full_size;
}
- if(image->vers_element != NULL) {
+ if (image->vers_element != NULL) {
memcpy(&data[offset], image->vers_element->data, image->vers_element->header->full_size);
offset += image->vers_element->header->full_size;
}
- if(image->sepo_element != NULL) {
+ if (image->sepo_element != NULL) {
memcpy(&data[offset], image->sepo_element->data, image->sepo_element->header->full_size);
offset += image->sepo_element->header->full_size;
}
- if(image->bord_element != NULL) {
+ if (image->bord_element != NULL) {
memcpy(&data[offset], image->bord_element->data, image->bord_element->header->full_size);
offset += image->bord_element->header->full_size;
}
- if(image->kbag1_element != NULL) {
+ if (image->kbag1_element != NULL) {
memcpy(&data[offset], image->kbag1_element->data, image->kbag1_element->header->full_size);
offset += image->kbag1_element->header->full_size;
}
- if(image->kbag2_element != NULL) {
+ if (image->kbag2_element != NULL) {
memcpy(&data[offset], image->kbag2_element->data, image->kbag2_element->header->full_size);
offset += image->kbag2_element->header->full_size;
}
- if(image->ecid_element != NULL) {
+ if (image->ecid_element != NULL) {
memcpy(&data[offset], image->ecid_element->data, image->ecid_element->header->full_size);
offset += image->ecid_element->header->full_size;
}
- if(image->shsh_element != NULL) {
+ if (image->shsh_element != NULL) {
memcpy(&data[offset], image->shsh_element->data, image->shsh_element->header->full_size);
header->shsh_offset = offset - sizeof(img3_header);
offset += image->shsh_element->header->full_size;
}
- if(image->cert_element != NULL) {
+ if (image->cert_element != NULL) {
memcpy(&data[offset], image->cert_element->data, image->cert_element->header->full_size);
offset += image->cert_element->header->full_size;
}
+ if (image->unkn_element != NULL) {
+ memcpy(&data[offset], image->unkn_element->data, image->unkn_element->header->full_size);
+ offset += image->unkn_element->header->full_size;
+ }
- if(offset != size) {
+ if (offset != size) {
error("ERROR: Incorrectly sized image data\n");
free(data);
*pdata = 0;