diff options
| author | 2010-05-23 03:53:02 -0400 | |
|---|---|---|
| committer | 2010-05-23 03:53:02 -0400 | |
| commit | ab1f7cb3c283b468235562b0b85db498b0a93766 (patch) | |
| tree | 8a75406d3433afaa80eb3a037bc6b218f7137def /src | |
| parent | ead23ad2b1bcfff151fd7f476fa32f949d509c6a (diff) | |
| download | idevicerestore-ab1f7cb3c283b468235562b0b85db498b0a93766.tar.gz idevicerestore-ab1f7cb3c283b468235562b0b85db498b0a93766.tar.bz2 | |
More work on img3.c/h done, implemented basic img3 file parsing and img3 element parsing
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 | 
