diff options
| author | 2008-08-31 11:25:22 -0700 | |
|---|---|---|
| committer | 2008-11-24 22:49:07 +0100 | |
| commit | f4c4b783c8dbe2fe8e7e6f6b5f19f0d44b489c9a (patch) | |
| tree | 9ef8c57fe298a4ae9e0a443d7103e6126c869020 /src | |
| parent | 8c3a01e11bb9c74e2a1bb7da143cb35469f29fba (diff) | |
| download | libimobiledevice-f4c4b783c8dbe2fe8e7e6f6b5f19f0d44b489c9a.tar.gz libimobiledevice-f4c4b783c8dbe2fe8e7e6f6b5f19f0d44b489c9a.tar.bz2 | |
Added binary-plist support (tweaked slightly to move stuff around)
Signed-off-by: Matt Colyer <matt@colyer.name>
fix makefile to take correct main function into account
Diffstat (limited to 'src')
| -rw-r--r-- | src/AFC.c | 46 | ||||
| -rw-r--r-- | src/AFC.h | 10 | ||||
| -rw-r--r-- | src/lockdown.c | 14 | ||||
| -rw-r--r-- | src/plist.c | 284 | ||||
| -rw-r--r-- | src/plist.h | 38 | ||||
| -rw-r--r-- | src/usbmux.c | 2 | ||||
| -rw-r--r-- | src/usbmux.h | 20 | 
7 files changed, 366 insertions, 48 deletions
| @@ -245,7 +245,7 @@ static int receive_AFC_data(iphone_afc_client_t client, char **dump_here)  		return retval;  	} -	uint32 param1 = buffer[sizeof(AFCPacket)]; +	uint32_t param1 = buffer[sizeof(AFCPacket)];  	free(buffer);  	if (r_packet->operation == AFC_ERROR && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)) { @@ -474,7 +474,7 @@ iphone_error_t iphone_afc_delete_file(iphone_afc_client_t client, const char *pa  iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to)  {  	char *response = NULL; -	char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); +	char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t)));  	int bytes = 0;  	if (!client || !from || !to || !client->afc_packet || !client->connection) @@ -660,7 +660,7 @@ iphone_afc_open_file(iphone_afc_client_t client, const char *filename,  					 iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file)  {  	iphone_afc_file_t file_loc = NULL; -	uint32 ag = 0; +	uint32_t ag = 0;  	int bytes = 0, length = 0;  	char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); @@ -795,7 +795,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,  {  	char *acknowledgement = NULL;  	const int MAXIMUM_WRITE_SIZE = 1 << 15; -	uint32 zero = 0, bytes_loc = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0; +	uint32_t zero = 0, bytes_loc = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0;  	char *out_buffer = NULL;  	if (!client || !client->afc_packet || !client->connection || !file || !bytes) @@ -812,8 +812,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,  		client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE;  		client->afc_packet->operation = AFC_WRITE;  		out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); -		memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); -		memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); +		memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); +		memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));  		memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE);  		bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8);  		if (bytes_loc < 0) { @@ -845,8 +845,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file,  	client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count);  	client->afc_packet->operation = AFC_WRITE;  	out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); -	memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); -	memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); +	memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); +	memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t));  	memcpy(out_buffer + 8, data + current_count, (length - current_count));  	bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8);  	free(out_buffer); @@ -881,7 +881,7 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file  	if (!client || !file)  		return IPHONE_E_INVALID_ARG;  	char *buffer = malloc(sizeof(char) * 8); -	uint32 zero = 0; +	uint32_t zero = 0;  	int bytes = 0;  	afc_lock(client); @@ -889,8 +889,8 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file  	log_debug_msg("afc_close_file: File handle %i\n", file->filehandle);  	// Send command -	memcpy(buffer, &file->filehandle, sizeof(uint32)); -	memcpy(buffer + sizeof(uint32), &zero, sizeof(zero)); +	memcpy(buffer, &file->filehandle, sizeof(uint32_t)); +	memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero));  	client->afc_packet->operation = AFC_FILE_CLOSE;  	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); @@ -926,7 +926,7 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file  iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos)  {  	char *buffer = (char *) malloc(sizeof(char) * 24); -	uint32 seekto = 0, bytes = 0, zero = 0; +	uint32_t seekto = 0, bytes = 0, zero = 0;  	if (seekpos < 0)  		seekpos = file->size - abs(seekpos); @@ -935,12 +935,12 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_  	// Send the command  	seekto = seekpos; -	memcpy(buffer, &file->filehandle, sizeof(uint32));	// handle -	memcpy(buffer + 4, &zero, sizeof(uint32));	// pad -	memcpy(buffer + 8, &zero, sizeof(uint32));	// fromwhere -	memcpy(buffer + 12, &zero, sizeof(uint32));	// pad -	memcpy(buffer + 16, &seekto, sizeof(uint32));	// offset -	memcpy(buffer + 20, &zero, sizeof(uint32));	// pad +	memcpy(buffer, &file->filehandle, sizeof(uint32_t));	// handle +	memcpy(buffer + 4, &zero, sizeof(uint32_t));	// pad +	memcpy(buffer + 8, &zero, sizeof(uint32_t));	// fromwhere +	memcpy(buffer + 12, &zero, sizeof(uint32_t));	// pad +	memcpy(buffer + 16, &seekto, sizeof(uint32_t));	// offset +	memcpy(buffer + 20, &zero, sizeof(uint32_t));	// pad  	client->afc_packet->operation = AFC_FILE_SEEK;  	client->afc_packet->this_length = client->afc_packet->entire_length = 0;  	bytes = dispatch_AFC_packet(client, buffer, 23); @@ -979,14 +979,14 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_  iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize)  {  	char *buffer = (char *) malloc(sizeof(char) * 16); -	uint32 bytes = 0, zero = 0; +	uint32_t bytes = 0, zero = 0;  	afc_lock(client);  	// Send command -	memcpy(buffer, &file->filehandle, sizeof(uint32));	// handle -	memcpy(buffer + 4, &zero, sizeof(uint32));	// pad -	memcpy(buffer + 8, &newsize, sizeof(uint32));	// newsize +	memcpy(buffer, &file->filehandle, sizeof(uint32_t));	// handle +	memcpy(buffer + 4, &zero, sizeof(uint32_t));	// pad +	memcpy(buffer + 8, &newsize, sizeof(uint32_t));	// newsize  	memcpy(buffer + 12, &zero, 3);	// pad  	client->afc_packet->operation = AFC_FILE_TRUNCATE;  	client->afc_packet->this_length = client->afc_packet->entire_length = 0; @@ -1012,7 +1012,7 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f  	}  } -uint32 iphone_afc_get_file_handle(iphone_afc_file_t file) +uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)  {  	return file->filehandle;  } @@ -29,12 +29,12 @@  #include <glib.h>  typedef struct { -	uint32 header1, header2; -	uint32 entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4; +	uint32_t header1, header2; +	uint32_t entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4;  } AFCPacket;  typedef struct { -	uint32 filehandle, unknown1, size, unknown2; +	uint32_t filehandle, unknown1, size, unknown2;  } AFCFilePacket;  typedef struct __AFCToken { @@ -51,7 +51,7 @@ struct iphone_afc_client_int {  };  struct iphone_afc_file_int { -	uint32 filehandle, blocks, size, type; +	uint32_t filehandle, blocks, size, type;  }; @@ -74,4 +74,4 @@ enum {  	AFC_WRITE = 0x00000010  }; -uint32 iphone_afc_get_file_handle(iphone_afc_file_t file); +uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file); diff --git a/src/lockdown.c b/src/lockdown.c index 65cbf90..6b8f298 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -127,7 +127,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u  		return IPHONE_E_INVALID_ARG;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	char *receive; -	uint32 datalen = 0, bytes = 0; +	uint32_t datalen = 0, bytes = 0;  	if (!client->in_SSL)  		ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); @@ -211,7 +211,7 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control)  	dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);  	key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1);  	char *XML_content; -	uint32 length; +	uint32_t length;  	xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length);  	ret = iphone_lckd_send(control, XML_content, length, &bytes); @@ -265,7 +265,7 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r  	char **dictionary = NULL;  	int bytes = 0, i = 0;  	char *XML_content = NULL; -	uint32 length = 0; +	uint32_t length = 0;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	/* Setup DevicePublicKey request plist */ @@ -420,7 +420,7 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch  	char **dictionary = NULL;  	int bytes = 0, i = 0;  	char *XML_content = NULL; -	uint32 length = 0; +	uint32_t length = 0;  	char *device_cert_b64 = NULL;  	char *host_cert_b64 = NULL; @@ -658,7 +658,7 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c  	xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);  	xmlNode *key;  	char *what2send = NULL, **dictionary = NULL; -	uint32 len = 0, bytes = 0, return_me = 0, i = 0; +	uint32_t len = 0, bytes = 0, return_me = 0, i = 0;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	// end variables @@ -893,8 +893,8 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char  		return IPHONE_E_SSL_ERROR;  	char *XML_query, **dictionary; -	uint32 length, i = 0, port_loc = 0, bytes = 0; -	uint8 result = 0; +	uint32_t length, i = 0, port_loc = 0, bytes = 0; +	uint8_t result = 0;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;  	free(host_id); diff --git a/src/plist.c b/src/plist.c index c4d6bfa..0024577 100644 --- a/src/plist.c +++ b/src/plist.c @@ -23,8 +23,10 @@  #include <libxml/tree.h>  #include <string.h>  #include <assert.h> +#include "utils.h"  #include "plist.h" +  const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\  <!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\  <plist version=\"1.0\">\n\ @@ -243,3 +245,285 @@ void free_dictionary(char **dictionary)  	free(dictionary);  } + +/* + * Binary propertylist code follows + */ + + +/* + * This is how parsing a bplist is going to have to work: + * 		- The entire binary plist is going to have to be in memory. + * 		- A function, parse_nodes(), will have to be a recursive function + * 		  which iterates over the binary plist and reads in elements into bplist_node structs + * 		  and handles them accordingly. The end result should be a somewhat-hierarchical layout  + * 		  of bplist_nodes. + * 		- parse_nodes() will return the first node it encounters, which is usually the "root" node.  + */ + +uint32_t uipow(uint32_t value, uint32_t power) { +	if (!power) return 1; +	int i = 0, oVal = value; +	for (i = 1; i < power; i++) { +		value *= oVal; +	} +	return value; +} + +void byte_convert(char *address, size_t size) { +	int i = 0, j = 0; +	char tmp = '\0'; +	 +	for (i = 0; i < (size / 2); i++) { +		tmp = address[i]; +		j = ((size-1) + 0) - i; +		address[i] = address[j]; +		address[j] = tmp; +	} +} +		 +bplist_node *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t *position, uint8_t ref_size) { +	if (!position || !bpbuffer || !bplength) return NULL; +	 +	uint8_t modifier = 0; +	bplist_node *new_node = (bplist_node*)malloc(sizeof(bplist_node)); +	bplist_node *length_stupidity = NULL; +	memset(new_node, 0, sizeof(bplist_node)); // initialize the new struct +	 +	int myPos = *position; +	if (myPos == bplength || (myPos+1) == bplength) { free(new_node); return NULL; } // end of string +	 +	uint32_t length = 0; +	if (!myPos) { +		if (strncmp(bpbuffer, "bplist00", strlen("bplist00"))) { +			return NULL; // badness! +		} +		myPos += strlen("bplist00"); +	} +	 +	// Get the node's type. +	if (bpbuffer[myPos] == BPLIST_DATE) { // handle date separately, but do it as a real +		// better handling of date; basically interpret as real or double +		new_node->type = BPLIST_DATE; +		new_node->length = 8; // always 8 for "date" (Apple intended it, not me) +		myPos++; +		memcpy(&new_node->realval, bpbuffer+myPos, sizeof(new_node->realval)); +		byte_convert(&new_node->realval, sizeof(new_node->realval)); +		myPos += new_node->length; +		*position = myPos; +		return new_node; +	} +	 +	new_node->type = bpbuffer[myPos] & BPLIST_MASK; +	new_node->length = bpbuffer[myPos] & BPLIST_FILL; +	if (!new_node->type) { +		// what? check if it's a boolean. +		if (bpbuffer[myPos] == BPLIST_TRUE || bpbuffer[myPos] == BPLIST_FALSE) { +			// okay, so it is. Carry on. +			new_node->type = bpbuffer[myPos]; +			new_node->length = 0; +		} else {  +			// er, what? we have a bad type here. Return NULL. +			free(new_node); +			//printf("parse_raw_node: lol type: type given %x\n", bpbuffer[myPos]); +			return NULL; +		} +	} +	 +	myPos++; // puts us in the data. +	if (new_node->length == BPLIST_FILL) { // Data happens to contain length... +		// what? you're going to make me parse an int for the length. You suck. +		*position = myPos; +		length_stupidity = parse_raw_node(bpbuffer, bplength, &myPos, ref_size); +		switch (length_stupidity->length) { +			case sizeof(uint8_t): +				new_node->length = length_stupidity->intval8; +				break; +			case sizeof(uint16_t): +				new_node->length = length_stupidity->intval16; +				break; +			case sizeof(uint32_t): +				new_node->length = length_stupidity->intval32; +				break; +			case sizeof(uint64_t): +				new_node->length = length_stupidity->intval64; +				break; +			default: +				free(new_node); +				free(length_stupidity); +				return NULL; +		} +		// There, we have our fucking length now. +		*position = myPos; +		free(length_stupidity); // cleanup +	} + +	// Now we're in the data.  +	// Error-checking sorta +	if ((myPos + new_node->length) >= bplength) { +		new_node->length = bplength - myPos; // truncate the object +	} +	 +	// And now for the greatest show on earth: the giant fucking switch statement. +	switch (new_node->type) { +		case BPLIST_INT: +			new_node->length = uipow(2, new_node->length); // make length less misleading +			switch (new_node->length) { +				case sizeof(uint8_t): +					new_node->intval8 = bpbuffer[myPos]; +					break; +				case sizeof(uint16_t): +					memcpy(&new_node->intval16, bpbuffer+myPos, sizeof(uint16_t)); +					new_node->intval16 = ntohs(new_node->intval16); +					break; +				case sizeof(uint32_t): +					memcpy(&new_node->intval32, bpbuffer+myPos, sizeof(uint32_t)); +					new_node->intval32 = ntohl(new_node->intval32); +					break; +				case sizeof(uint64_t): +					memcpy(&new_node->intval64, bpbuffer+myPos, sizeof(uint64_t)); +					byte_convert(&new_node->intval64, sizeof(uint64_t)); +					break; +				default: +					free(new_node); +					printf("parse_raw_node: lol: invalid int: size given %i\n", new_node->length); +					printf("parse_raw_node: lol: by the way sizeof(uint64) = %i\n", sizeof(uint64_t)); +					return NULL; +			} +			break; +		 +		case BPLIST_REAL: +			new_node->length = uipow(2, new_node->length); +			memcpy(&new_node->realval, bpbuffer+myPos, new_node->length); // XXX: probable buffer overflow here +			//new_node->realval = bpbuffer[myPos]; // why not +			byte_convert(&new_node->realval, sizeof(double)); +			break; +			 +		case BPLIST_DICT: /* returning a raw dict, it forward-references, so. */ +			new_node->length = new_node->length * 2; // dicts lie +		case BPLIST_ARRAY: /* returning a raw array, it forward-references, so. */ +			new_node->intval8 = ref_size; // in arrays and dicts, the "ref size" alluded to in the trailer applies, and should be stored in intval8 so as to save space.  +		case BPLIST_STRING: +		case BPLIST_DATA: +		default: /* made to hold raw data. */ +			modifier = (new_node->intval8 > 0) ? new_node->intval8 : 1; +			new_node->strval = (char*)malloc(sizeof(char) * (new_node->length * modifier)); +			memcpy(new_node->strval, bpbuffer+myPos, (new_node->length * modifier)); +			break; +		 +		case BPLIST_UNICODE: +			new_node->unicodeval = (wchar_t*)malloc(sizeof(wchar_t) * new_node->length); +			memcpy(new_node->unicodeval, bpbuffer+myPos, new_node->length); +			break; +	} +	 +	myPos += new_node->length; +	*position = myPos; +	return new_node; +} + +void print_bytes(char *val, size_t size) { +	int i = 0; +	for (i = 0; i < size; i++) { +		printf("Byte %i: 0x%x\n", i, val[i]); +	} +} + +bplist_node *parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t *position) { +	bplist_node **nodeslist = NULL, **newaddr = NULL; +	bplist_node *new_node = NULL, *root_node = NULL; +	 +	uint32_t nodeslength = 0; +	uint8_t offset_size = 0, dict_param_size = 0; +	offset_size = bpbuffer[bplength-26]; +	dict_param_size = bpbuffer[bplength-25];  +	uint64_t current_offset = 0; +	//uint64_t num_objects = *(bpbuffer+(bplength-24)), root_object = *(bpbuffer+(bplength-16)), offset_table_index = *(bpbuffer+(bplength-8)); +	uint64_t num_objects = 0, root_object = 0, offset_table_index = 0; +	memcpy(&num_objects, bpbuffer+bplength-24, sizeof(uint64_t)); +	memcpy(&root_object, bpbuffer+bplength-16, sizeof(uint64_t)); +	memcpy(&offset_table_index, bpbuffer+bplength-8, sizeof(uint64_t)); +	byte_convert(&num_objects, sizeof(uint64_t)); +	byte_convert(&root_object, sizeof(uint64_t)); +	byte_convert(&offset_table_index, sizeof(uint64_t)); +	 +	log_debug_msg("Offset size: %i\nGiven: %i\n", offset_size, bpbuffer[bplength-26]); +	log_debug_msg("Ref size: %i\nGiven: %i\n", dict_param_size, bpbuffer[bplength-25]); +	log_debug_msg("Number of objects: %lli\nGiven: %llu\n", num_objects, *(bpbuffer+bplength-24)); +	log_debug_msg("Root object index: %lli\nGiven: %llu\n", root_object, *(bpbuffer+bplength-16)); +	log_debug_msg("Offset table index: %lli\nGiven: %llu\n", offset_table_index, *(bpbuffer+bplength-8)); +	log_debug_msg("Size of uint64: %i\n", sizeof(uint64_t)); +	 +	int i = 0, j = 0, k = 0, str_i = 0, str_j = 0; +	uint32_t index1 = 0, index2 = 0; +	 +	nodeslist = (bplist_node**)malloc(sizeof(bplist_node*) * num_objects); +	if (!nodeslist) return NULL; + +	for (i = 0; i < num_objects; i++) { +		memcpy(¤t_offset, bpbuffer+(offset_table_index+(i*offset_size)), offset_size); +		//current_offset = (offset_size == 2) ? ntohs(current_offset) : (offset_size == 4) ? ntohl(current_offset) : current_offset; +		//if (offset_size == 8) byte_convert(¤t_offset, 8); +		byte_convert(¤t_offset, (offset_size <= sizeof(current_offset)) ? offset_size : sizeof(current_offset)); +		log_debug_msg("parse_nodes: current_offset = %x\n", current_offset); +		nodeslist[i] = parse_raw_node(bpbuffer, bplength, ¤t_offset, dict_param_size); +		log_debug_msg("parse_nodes: parse_raw_node done\n"); +	} + + +	for (i = 0; i < num_objects; i++) { +		// set elements for dicts and arrays and leave the rest alone +		log_debug_msg("parse_nodes: on node %i\n", i); +		switch (nodeslist[i]->type) { +			case BPLIST_DICT: +				log_debug_msg("parse_nodes: dictionary found\n"); +				nodeslist[i]->subnodes = (bplist_node*)malloc(sizeof(bplist_node) * nodeslist[i]->length); +				for (j = 0; j < (nodeslist[i]->length / 2); j++) { +					str_i = j * nodeslist[i]->intval8; +					str_j = (j + (nodeslist[i]->length / 2)) * nodeslist[i]->intval8; + +					memcpy(&index1, nodeslist[i]->strval+str_i, nodeslist[i]->intval8); +					memcpy(&index2, nodeslist[i]->strval+str_j, nodeslist[i]->intval8); +					//index1 = (dict_param_size == 1) ? index1 : (dict_param_size == 2) ? ntohs(index1) : (dict_param_size == 4) ? ntohl(index1) : index1; +					//index2 = (dict_param_size == 1) ? index2 : (dict_param_size == 2) ? ntohs(index2) : (dict_param_size == 4) ? ntohl(index2) : index2; +					byte_convert(&index1, (dict_param_size <= sizeof(index1)) ? dict_param_size : sizeof(index2)); +					byte_convert(&index2, (dict_param_size <= sizeof(index2)) ? dict_param_size : sizeof(index2)); +					//printf("parse_nodes: key index %i value %i\n", index1, index2); +					//printf("parse_nodes: key type %x and length %i\n", nodeslist[index1]->type, nodeslist[index1]->length); +					//printf("parse_nodes: value type %x and length %i\n", nodeslist[index2]->type, nodeslist[index2]->length); +					nodeslist[i]->subnodes[k++] = nodeslist[index1]; +					nodeslist[i]->subnodes[k++] = nodeslist[index2]; +				} +				 +				nodeslist[i]->length = nodeslist[i]->length / 2; +				free(nodeslist[i]->strval);  +				k = 0; +				break; +			 +			case BPLIST_ARRAY: +				log_debug_msg("parse_nodes: array found\n"); +				nodeslist[i]->subnodes = (bplist_node*)malloc(sizeof(bplist_node) * nodeslist[i]->length); // memory allocation helps a lot when storing data +				 +				for (j = 0; j < nodeslist[i]->length; j++) { +					log_debug_msg("parse_nodes: array index %i\n", j); +					str_j = j * nodeslist[i]->intval8; +					//index1 = nodeslist[i]->strval[j]; +					memcpy(&index1, nodeslist[i]->strval+str_j, nodeslist[i]->intval8); +					log_debug_msg("parse_nodes: post-memcpy\n"); +					//index1 = (dict_param_size == 1) ? index1 : (dict_param_size == 2) ? ntohs(index1) : (dict_param_size == 4) ? ntohl(index1) : index1; +					byte_convert(&index1, (dict_param_size <= sizeof(index1)) ? dict_param_size : sizeof(index1)); +					log_debug_msg("parse_nodes: post-ntohl\nindex1 = %i\n", index1); +					nodeslist[i]->subnodes[j] = nodeslist[index1]; +					log_debug_msg("parse_nodes: post-assignment\n"); +				} +				free(nodeslist[i]->strval); +				break; +			default: +				//printf("lol... type %x\n", nodeslist[i]->type); +				break; +		} // those are the only two we need to correct for. +	} +	 +	root_node = nodeslist[root_object]; +	return root_node; +} diff --git a/src/plist.h b/src/plist.h index b27a0c5..98c7d91 100644 --- a/src/plist.h +++ b/src/plist.h @@ -24,6 +24,12 @@  #include <libxml/parser.h>  #include <libxml/tree.h> +#include <stdint.h> +#include <wchar.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h>  xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth);  xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); @@ -35,4 +41,36 @@ xmlDocPtr new_plist();  char **read_dict_element_strings(xmlNode * dict);  void free_dictionary(char **dictionary); + +/* Binary plist stuff */ + +enum { +	BPLIST_TRUE = 0x08, +	BPLIST_FALSE = 0x09, +	BPLIST_FILL = 0x0F, /* will be used for length grabbing */ +	BPLIST_INT = 0x10, +	BPLIST_REAL = 0x20, +	BPLIST_DATE = 0x33, +	BPLIST_DATA = 0x40, +	BPLIST_STRING = 0x50, +	BPLIST_UNICODE = 0x60, +	BPLIST_UID = 0x70, +	BPLIST_ARRAY = 0xA0, +	BPLIST_SET = 0xC0, +	BPLIST_DICT = 0xD0, +	BPLIST_MASK = 0xF0 +}; + +typedef struct _bplist_node { +	struct _bplist_node *next, **subnodes; // subnodes is for arrays, dicts and (potentially) sets.  +	uint64_t length, intval64; +	uint32_t intval32; // length = subnodes  +	uint16_t intval16; +	uint8_t intval8; +	uint8_t type, *indexes; // indexes for array-types; essentially specify the order in which to access for key => value pairs +	char *strval; +	double realval; +	wchar_t *unicodeval; +} bplist_node; +  #endif diff --git a/src/usbmux.c b/src/usbmux.c index 2114758..f0499fa 100644 --- a/src/usbmux.c +++ b/src/usbmux.c @@ -37,7 +37,7 @@ static int clients = 0;   *   * @return A USBMux packet   */ -usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) +usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port)  {  	usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header));  	conn->type = htonl(6); diff --git a/src/usbmux.h b/src/usbmux.h index da8a361..4b18e07 100644 --- a/src/usbmux.h +++ b/src/usbmux.h @@ -22,6 +22,7 @@  #include <sys/types.h>  #include <stdlib.h>  #include <stdint.h> +#include "libiphone/libiphone.h"  #ifndef USBMUX_H  #define USBMUX_H @@ -30,17 +31,12 @@  #include "iphone.h"  #endif -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint8_t uint8; - -  typedef struct { -	uint32 type, length; -	uint16 sport, dport; -	uint32 scnt, ocnt; -	uint8 offset, tcp_flags; -	uint16 window, nullnull, length16; +	uint32_t type, length; +	uint16_t sport, dport; +	uint32_t scnt, ocnt; +	uint8_t offset, tcp_flags; +	uint16_t window, nullnull, length16;  } usbmux_tcp_header;  struct iphone_umux_client_int { @@ -50,10 +46,10 @@ struct iphone_umux_client_int {  	int r_len;  }; -usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); +usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port);  typedef struct { -	uint32 type, length, major, minor, allnull; +	uint32_t type, length, major, minor, allnull;  } usbmux_version_header;  usbmux_version_header *version_header(); | 
