diff options
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) | |||
| 245 | return retval; | 245 | return retval; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | uint32 param1 = buffer[sizeof(AFCPacket)]; | 248 | uint32_t param1 = buffer[sizeof(AFCPacket)]; |
| 249 | free(buffer); | 249 | free(buffer); |
| 250 | 250 | ||
| 251 | if (r_packet->operation == AFC_ERROR && !(client->afc_packet->operation == AFC_DELETE && param1 == 7)) { | 251 | 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 | |||
| 474 | iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to) | 474 | iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to) |
| 475 | { | 475 | { |
| 476 | char *response = NULL; | 476 | char *response = NULL; |
| 477 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); | 477 | char *send = (char *) malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32_t))); |
| 478 | int bytes = 0; | 478 | int bytes = 0; |
| 479 | 479 | ||
| 480 | if (!client || !from || !to || !client->afc_packet || !client->connection) | 480 | 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, | |||
| 660 | iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file) | 660 | iphone_afc_file_mode_t file_mode, iphone_afc_file_t * file) |
| 661 | { | 661 | { |
| 662 | iphone_afc_file_t file_loc = NULL; | 662 | iphone_afc_file_t file_loc = NULL; |
| 663 | uint32 ag = 0; | 663 | uint32_t ag = 0; |
| 664 | int bytes = 0, length = 0; | 664 | int bytes = 0, length = 0; |
| 665 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); | 665 | char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1)); |
| 666 | 666 | ||
| @@ -795,7 +795,7 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file, | |||
| 795 | { | 795 | { |
| 796 | char *acknowledgement = NULL; | 796 | char *acknowledgement = NULL; |
| 797 | const int MAXIMUM_WRITE_SIZE = 1 << 15; | 797 | const int MAXIMUM_WRITE_SIZE = 1 << 15; |
| 798 | uint32 zero = 0, bytes_loc = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0; | 798 | uint32_t zero = 0, bytes_loc = 0, segments = (length / MAXIMUM_WRITE_SIZE), current_count = 0, i = 0; |
| 799 | char *out_buffer = NULL; | 799 | char *out_buffer = NULL; |
| 800 | 800 | ||
| 801 | if (!client || !client->afc_packet || !client->connection || !file || !bytes) | 801 | 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, | |||
| 812 | client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; | 812 | client->afc_packet->entire_length = client->afc_packet->this_length + MAXIMUM_WRITE_SIZE; |
| 813 | client->afc_packet->operation = AFC_WRITE; | 813 | client->afc_packet->operation = AFC_WRITE; |
| 814 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | 814 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); |
| 815 | memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); | 815 | memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); |
| 816 | memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); | 816 | memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t)); |
| 817 | memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); | 817 | memcpy(out_buffer + 8, data + current_count, MAXIMUM_WRITE_SIZE); |
| 818 | bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); | 818 | bytes_loc = dispatch_AFC_packet(client, out_buffer, MAXIMUM_WRITE_SIZE + 8); |
| 819 | if (bytes_loc < 0) { | 819 | if (bytes_loc < 0) { |
| @@ -845,8 +845,8 @@ iphone_afc_write_file(iphone_afc_client_t client, iphone_afc_file_t file, | |||
| 845 | client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); | 845 | client->afc_packet->entire_length = client->afc_packet->this_length + (length - current_count); |
| 846 | client->afc_packet->operation = AFC_WRITE; | 846 | client->afc_packet->operation = AFC_WRITE; |
| 847 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); | 847 | out_buffer = (char *) malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); |
| 848 | memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32)); | 848 | memcpy(out_buffer, (char *) &file->filehandle, sizeof(uint32_t)); |
| 849 | memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32)); | 849 | memcpy(out_buffer + 4, (char *) &zero, sizeof(uint32_t)); |
| 850 | memcpy(out_buffer + 8, data + current_count, (length - current_count)); | 850 | memcpy(out_buffer + 8, data + current_count, (length - current_count)); |
| 851 | bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); | 851 | bytes_loc = dispatch_AFC_packet(client, out_buffer, (length - current_count) + 8); |
| 852 | free(out_buffer); | 852 | free(out_buffer); |
| @@ -881,7 +881,7 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file | |||
| 881 | if (!client || !file) | 881 | if (!client || !file) |
| 882 | return IPHONE_E_INVALID_ARG; | 882 | return IPHONE_E_INVALID_ARG; |
| 883 | char *buffer = malloc(sizeof(char) * 8); | 883 | char *buffer = malloc(sizeof(char) * 8); |
| 884 | uint32 zero = 0; | 884 | uint32_t zero = 0; |
| 885 | int bytes = 0; | 885 | int bytes = 0; |
| 886 | 886 | ||
| 887 | afc_lock(client); | 887 | afc_lock(client); |
| @@ -889,8 +889,8 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file | |||
| 889 | log_debug_msg("afc_close_file: File handle %i\n", file->filehandle); | 889 | log_debug_msg("afc_close_file: File handle %i\n", file->filehandle); |
| 890 | 890 | ||
| 891 | // Send command | 891 | // Send command |
| 892 | memcpy(buffer, &file->filehandle, sizeof(uint32)); | 892 | memcpy(buffer, &file->filehandle, sizeof(uint32_t)); |
| 893 | memcpy(buffer + sizeof(uint32), &zero, sizeof(zero)); | 893 | memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero)); |
| 894 | client->afc_packet->operation = AFC_FILE_CLOSE; | 894 | client->afc_packet->operation = AFC_FILE_CLOSE; |
| 895 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; | 895 | client->afc_packet->entire_length = client->afc_packet->this_length = 0; |
| 896 | bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); | 896 | 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 | |||
| 926 | iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) | 926 | iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) |
| 927 | { | 927 | { |
| 928 | char *buffer = (char *) malloc(sizeof(char) * 24); | 928 | char *buffer = (char *) malloc(sizeof(char) * 24); |
| 929 | uint32 seekto = 0, bytes = 0, zero = 0; | 929 | uint32_t seekto = 0, bytes = 0, zero = 0; |
| 930 | 930 | ||
| 931 | if (seekpos < 0) | 931 | if (seekpos < 0) |
| 932 | seekpos = file->size - abs(seekpos); | 932 | seekpos = file->size - abs(seekpos); |
| @@ -935,12 +935,12 @@ iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_ | |||
| 935 | 935 | ||
| 936 | // Send the command | 936 | // Send the command |
| 937 | seekto = seekpos; | 937 | seekto = seekpos; |
| 938 | memcpy(buffer, &file->filehandle, sizeof(uint32)); // handle | 938 | memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle |
| 939 | memcpy(buffer + 4, &zero, sizeof(uint32)); // pad | 939 | memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad |
| 940 | memcpy(buffer + 8, &zero, sizeof(uint32)); // fromwhere | 940 | memcpy(buffer + 8, &zero, sizeof(uint32_t)); // fromwhere |
| 941 | memcpy(buffer + 12, &zero, sizeof(uint32)); // pad | 941 | memcpy(buffer + 12, &zero, sizeof(uint32_t)); // pad |
| 942 | memcpy(buffer + 16, &seekto, sizeof(uint32)); // offset | 942 | memcpy(buffer + 16, &seekto, sizeof(uint32_t)); // offset |
| 943 | memcpy(buffer + 20, &zero, sizeof(uint32)); // pad | 943 | memcpy(buffer + 20, &zero, sizeof(uint32_t)); // pad |
| 944 | client->afc_packet->operation = AFC_FILE_SEEK; | 944 | client->afc_packet->operation = AFC_FILE_SEEK; |
| 945 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 945 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; |
| 946 | bytes = dispatch_AFC_packet(client, buffer, 23); | 946 | 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_ | |||
| 979 | iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize) | 979 | iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize) |
| 980 | { | 980 | { |
| 981 | char *buffer = (char *) malloc(sizeof(char) * 16); | 981 | char *buffer = (char *) malloc(sizeof(char) * 16); |
| 982 | uint32 bytes = 0, zero = 0; | 982 | uint32_t bytes = 0, zero = 0; |
| 983 | 983 | ||
| 984 | afc_lock(client); | 984 | afc_lock(client); |
| 985 | 985 | ||
| 986 | // Send command | 986 | // Send command |
| 987 | memcpy(buffer, &file->filehandle, sizeof(uint32)); // handle | 987 | memcpy(buffer, &file->filehandle, sizeof(uint32_t)); // handle |
| 988 | memcpy(buffer + 4, &zero, sizeof(uint32)); // pad | 988 | memcpy(buffer + 4, &zero, sizeof(uint32_t)); // pad |
| 989 | memcpy(buffer + 8, &newsize, sizeof(uint32)); // newsize | 989 | memcpy(buffer + 8, &newsize, sizeof(uint32_t)); // newsize |
| 990 | memcpy(buffer + 12, &zero, 3); // pad | 990 | memcpy(buffer + 12, &zero, 3); // pad |
| 991 | client->afc_packet->operation = AFC_FILE_TRUNCATE; | 991 | client->afc_packet->operation = AFC_FILE_TRUNCATE; |
| 992 | client->afc_packet->this_length = client->afc_packet->entire_length = 0; | 992 | 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 | |||
| 1012 | } | 1012 | } |
| 1013 | } | 1013 | } |
| 1014 | 1014 | ||
| 1015 | uint32 iphone_afc_get_file_handle(iphone_afc_file_t file) | 1015 | uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file) |
| 1016 | { | 1016 | { |
| 1017 | return file->filehandle; | 1017 | return file->filehandle; |
| 1018 | } | 1018 | } |
| @@ -29,12 +29,12 @@ | |||
| 29 | #include <glib.h> | 29 | #include <glib.h> |
| 30 | 30 | ||
| 31 | typedef struct { | 31 | typedef struct { |
| 32 | uint32 header1, header2; | 32 | uint32_t header1, header2; |
| 33 | uint32 entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4; | 33 | uint32_t entire_length, unknown1, this_length, unknown2, packet_num, unknown3, operation, unknown4; |
| 34 | } AFCPacket; | 34 | } AFCPacket; |
| 35 | 35 | ||
| 36 | typedef struct { | 36 | typedef struct { |
| 37 | uint32 filehandle, unknown1, size, unknown2; | 37 | uint32_t filehandle, unknown1, size, unknown2; |
| 38 | } AFCFilePacket; | 38 | } AFCFilePacket; |
| 39 | 39 | ||
| 40 | typedef struct __AFCToken { | 40 | typedef struct __AFCToken { |
| @@ -51,7 +51,7 @@ struct iphone_afc_client_int { | |||
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | struct iphone_afc_file_int { | 53 | struct iphone_afc_file_int { |
| 54 | uint32 filehandle, blocks, size, type; | 54 | uint32_t filehandle, blocks, size, type; |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | 57 | ||
| @@ -74,4 +74,4 @@ enum { | |||
| 74 | AFC_WRITE = 0x00000010 | 74 | AFC_WRITE = 0x00000010 |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | uint32 iphone_afc_get_file_handle(iphone_afc_file_t file); | 77 | 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 | |||
| 127 | return IPHONE_E_INVALID_ARG; | 127 | return IPHONE_E_INVALID_ARG; |
| 128 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 128 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 129 | char *receive; | 129 | char *receive; |
| 130 | uint32 datalen = 0, bytes = 0; | 130 | uint32_t datalen = 0, bytes = 0; |
| 131 | 131 | ||
| 132 | if (!client->in_SSL) | 132 | if (!client->in_SSL) |
| 133 | ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes); | 133 | 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) | |||
| 211 | dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); | 211 | dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); |
| 212 | key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); | 212 | key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); |
| 213 | char *XML_content; | 213 | char *XML_content; |
| 214 | uint32 length; | 214 | uint32_t length; |
| 215 | 215 | ||
| 216 | xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); | 216 | xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); |
| 217 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 217 | 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 | |||
| 265 | char **dictionary = NULL; | 265 | char **dictionary = NULL; |
| 266 | int bytes = 0, i = 0; | 266 | int bytes = 0, i = 0; |
| 267 | char *XML_content = NULL; | 267 | char *XML_content = NULL; |
| 268 | uint32 length = 0; | 268 | uint32_t length = 0; |
| 269 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 269 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 270 | 270 | ||
| 271 | /* Setup DevicePublicKey request plist */ | 271 | /* Setup DevicePublicKey request plist */ |
| @@ -420,7 +420,7 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch | |||
| 420 | char **dictionary = NULL; | 420 | char **dictionary = NULL; |
| 421 | int bytes = 0, i = 0; | 421 | int bytes = 0, i = 0; |
| 422 | char *XML_content = NULL; | 422 | char *XML_content = NULL; |
| 423 | uint32 length = 0; | 423 | uint32_t length = 0; |
| 424 | 424 | ||
| 425 | char *device_cert_b64 = NULL; | 425 | char *device_cert_b64 = NULL; |
| 426 | char *host_cert_b64 = NULL; | 426 | char *host_cert_b64 = NULL; |
| @@ -658,7 +658,7 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c | |||
| 658 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); | 658 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); |
| 659 | xmlNode *key; | 659 | xmlNode *key; |
| 660 | char *what2send = NULL, **dictionary = NULL; | 660 | char *what2send = NULL, **dictionary = NULL; |
| 661 | uint32 len = 0, bytes = 0, return_me = 0, i = 0; | 661 | uint32_t len = 0, bytes = 0, return_me = 0, i = 0; |
| 662 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 662 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 663 | // end variables | 663 | // end variables |
| 664 | 664 | ||
| @@ -893,8 +893,8 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char | |||
| 893 | return IPHONE_E_SSL_ERROR; | 893 | return IPHONE_E_SSL_ERROR; |
| 894 | 894 | ||
| 895 | char *XML_query, **dictionary; | 895 | char *XML_query, **dictionary; |
| 896 | uint32 length, i = 0, port_loc = 0, bytes = 0; | 896 | uint32_t length, i = 0, port_loc = 0, bytes = 0; |
| 897 | uint8 result = 0; | 897 | uint8_t result = 0; |
| 898 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 898 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 899 | 899 | ||
| 900 | free(host_id); | 900 | 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 @@ | |||
| 23 | #include <libxml/tree.h> | 23 | #include <libxml/tree.h> |
| 24 | #include <string.h> | 24 | #include <string.h> |
| 25 | #include <assert.h> | 25 | #include <assert.h> |
| 26 | #include "utils.h" | ||
| 26 | #include "plist.h" | 27 | #include "plist.h" |
| 27 | 28 | ||
| 29 | |||
| 28 | const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ | 30 | const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ |
| 29 | <!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\ | 31 | <!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\ |
| 30 | <plist version=\"1.0\">\n\ | 32 | <plist version=\"1.0\">\n\ |
| @@ -243,3 +245,285 @@ void free_dictionary(char **dictionary) | |||
| 243 | 245 | ||
| 244 | free(dictionary); | 246 | free(dictionary); |
| 245 | } | 247 | } |
| 248 | |||
| 249 | /* | ||
| 250 | * Binary propertylist code follows | ||
| 251 | */ | ||
| 252 | |||
| 253 | |||
| 254 | /* | ||
| 255 | * This is how parsing a bplist is going to have to work: | ||
| 256 | * - The entire binary plist is going to have to be in memory. | ||
| 257 | * - A function, parse_nodes(), will have to be a recursive function | ||
| 258 | * which iterates over the binary plist and reads in elements into bplist_node structs | ||
| 259 | * and handles them accordingly. The end result should be a somewhat-hierarchical layout | ||
| 260 | * of bplist_nodes. | ||
| 261 | * - parse_nodes() will return the first node it encounters, which is usually the "root" node. | ||
| 262 | */ | ||
| 263 | |||
| 264 | uint32_t uipow(uint32_t value, uint32_t power) { | ||
| 265 | if (!power) return 1; | ||
| 266 | int i = 0, oVal = value; | ||
| 267 | for (i = 1; i < power; i++) { | ||
| 268 | value *= oVal; | ||
| 269 | } | ||
| 270 | return value; | ||
| 271 | } | ||
| 272 | |||
| 273 | void byte_convert(char *address, size_t size) { | ||
| 274 | int i = 0, j = 0; | ||
| 275 | char tmp = '\0'; | ||
| 276 | |||
| 277 | for (i = 0; i < (size / 2); i++) { | ||
| 278 | tmp = address[i]; | ||
| 279 | j = ((size-1) + 0) - i; | ||
| 280 | address[i] = address[j]; | ||
| 281 | address[j] = tmp; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | bplist_node *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t *position, uint8_t ref_size) { | ||
| 286 | if (!position || !bpbuffer || !bplength) return NULL; | ||
| 287 | |||
| 288 | uint8_t modifier = 0; | ||
| 289 | bplist_node *new_node = (bplist_node*)malloc(sizeof(bplist_node)); | ||
| 290 | bplist_node *length_stupidity = NULL; | ||
| 291 | memset(new_node, 0, sizeof(bplist_node)); // initialize the new struct | ||
| 292 | |||
| 293 | int myPos = *position; | ||
| 294 | if (myPos == bplength || (myPos+1) == bplength) { free(new_node); return NULL; } // end of string | ||
| 295 | |||
| 296 | uint32_t length = 0; | ||
| 297 | if (!myPos) { | ||
| 298 | if (strncmp(bpbuffer, "bplist00", strlen("bplist00"))) { | ||
| 299 | return NULL; // badness! | ||
| 300 | } | ||
| 301 | myPos += strlen("bplist00"); | ||
| 302 | } | ||
| 303 | |||
| 304 | // Get the node's type. | ||
| 305 | if (bpbuffer[myPos] == BPLIST_DATE) { // handle date separately, but do it as a real | ||
| 306 | // better handling of date; basically interpret as real or double | ||
| 307 | new_node->type = BPLIST_DATE; | ||
| 308 | new_node->length = 8; // always 8 for "date" (Apple intended it, not me) | ||
| 309 | myPos++; | ||
| 310 | memcpy(&new_node->realval, bpbuffer+myPos, sizeof(new_node->realval)); | ||
| 311 | byte_convert(&new_node->realval, sizeof(new_node->realval)); | ||
| 312 | myPos += new_node->length; | ||
| 313 | *position = myPos; | ||
| 314 | return new_node; | ||
| 315 | } | ||
| 316 | |||
| 317 | new_node->type = bpbuffer[myPos] & BPLIST_MASK; | ||
| 318 | new_node->length = bpbuffer[myPos] & BPLIST_FILL; | ||
| 319 | if (!new_node->type) { | ||
| 320 | // what? check if it's a boolean. | ||
| 321 | if (bpbuffer[myPos] == BPLIST_TRUE || bpbuffer[myPos] == BPLIST_FALSE) { | ||
| 322 | // okay, so it is. Carry on. | ||
| 323 | new_node->type = bpbuffer[myPos]; | ||
| 324 | new_node->length = 0; | ||
| 325 | } else { | ||
| 326 | // er, what? we have a bad type here. Return NULL. | ||
| 327 | free(new_node); | ||
| 328 | //printf("parse_raw_node: lol type: type given %x\n", bpbuffer[myPos]); | ||
| 329 | return NULL; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | myPos++; // puts us in the data. | ||
| 334 | if (new_node->length == BPLIST_FILL) { // Data happens to contain length... | ||
| 335 | // what? you're going to make me parse an int for the length. You suck. | ||
| 336 | *position = myPos; | ||
| 337 | length_stupidity = parse_raw_node(bpbuffer, bplength, &myPos, ref_size); | ||
| 338 | switch (length_stupidity->length) { | ||
| 339 | case sizeof(uint8_t): | ||
| 340 | new_node->length = length_stupidity->intval8; | ||
| 341 | break; | ||
| 342 | case sizeof(uint16_t): | ||
| 343 | new_node->length = length_stupidity->intval16; | ||
| 344 | break; | ||
| 345 | case sizeof(uint32_t): | ||
| 346 | new_node->length = length_stupidity->intval32; | ||
| 347 | break; | ||
| 348 | case sizeof(uint64_t): | ||
| 349 | new_node->length = length_stupidity->intval64; | ||
| 350 | break; | ||
| 351 | default: | ||
| 352 | free(new_node); | ||
| 353 | free(length_stupidity); | ||
| 354 | return NULL; | ||
| 355 | } | ||
| 356 | // There, we have our fucking length now. | ||
| 357 | *position = myPos; | ||
| 358 | free(length_stupidity); // cleanup | ||
| 359 | } | ||
| 360 | |||
| 361 | // Now we're in the data. | ||
| 362 | // Error-checking sorta | ||
| 363 | if ((myPos + new_node->length) >= bplength) { | ||
| 364 | new_node->length = bplength - myPos; // truncate the object | ||
| 365 | } | ||
| 366 | |||
| 367 | // And now for the greatest show on earth: the giant fucking switch statement. | ||
| 368 | switch (new_node->type) { | ||
| 369 | case BPLIST_INT: | ||
| 370 | new_node->length = uipow(2, new_node->length); // make length less misleading | ||
| 371 | switch (new_node->length) { | ||
| 372 | case sizeof(uint8_t): | ||
| 373 | new_node->intval8 = bpbuffer[myPos]; | ||
| 374 | break; | ||
| 375 | case sizeof(uint16_t): | ||
| 376 | memcpy(&new_node->intval16, bpbuffer+myPos, sizeof(uint16_t)); | ||
| 377 | new_node->intval16 = ntohs(new_node->intval16); | ||
| 378 | break; | ||
| 379 | case sizeof(uint32_t): | ||
| 380 | memcpy(&new_node->intval32, bpbuffer+myPos, sizeof(uint32_t)); | ||
| 381 | new_node->intval32 = ntohl(new_node->intval32); | ||
| 382 | break; | ||
| 383 | case sizeof(uint64_t): | ||
| 384 | memcpy(&new_node->intval64, bpbuffer+myPos, sizeof(uint64_t)); | ||
| 385 | byte_convert(&new_node->intval64, sizeof(uint64_t)); | ||
| 386 | break; | ||
| 387 | default: | ||
| 388 | free(new_node); | ||
| 389 | printf("parse_raw_node: lol: invalid int: size given %i\n", new_node->length); | ||
| 390 | printf("parse_raw_node: lol: by the way sizeof(uint64) = %i\n", sizeof(uint64_t)); | ||
| 391 | return NULL; | ||
| 392 | } | ||
| 393 | break; | ||
| 394 | |||
| 395 | case BPLIST_REAL: | ||
| 396 | new_node->length = uipow(2, new_node->length); | ||
| 397 | memcpy(&new_node->realval, bpbuffer+myPos, new_node->length); // XXX: probable buffer overflow here | ||
| 398 | //new_node->realval = bpbuffer[myPos]; // why not | ||
| 399 | byte_convert(&new_node->realval, sizeof(double)); | ||
| 400 | break; | ||
| 401 | |||
| 402 | case BPLIST_DICT: /* returning a raw dict, it forward-references, so. */ | ||
| 403 | new_node->length = new_node->length * 2; // dicts lie | ||
| 404 | case BPLIST_ARRAY: /* returning a raw array, it forward-references, so. */ | ||
| 405 | 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. | ||
| 406 | case BPLIST_STRING: | ||
| 407 | case BPLIST_DATA: | ||
| 408 | default: /* made to hold raw data. */ | ||
| 409 | modifier = (new_node->intval8 > 0) ? new_node->intval8 : 1; | ||
| 410 | new_node->strval = (char*)malloc(sizeof(char) * (new_node->length * modifier)); | ||
| 411 | memcpy(new_node->strval, bpbuffer+myPos, (new_node->length * modifier)); | ||
| 412 | break; | ||
| 413 | |||
| 414 | case BPLIST_UNICODE: | ||
| 415 | new_node->unicodeval = (wchar_t*)malloc(sizeof(wchar_t) * new_node->length); | ||
| 416 | memcpy(new_node->unicodeval, bpbuffer+myPos, new_node->length); | ||
| 417 | break; | ||
| 418 | } | ||
| 419 | |||
| 420 | myPos += new_node->length; | ||
| 421 | *position = myPos; | ||
| 422 | return new_node; | ||
| 423 | } | ||
| 424 | |||
| 425 | void print_bytes(char *val, size_t size) { | ||
| 426 | int i = 0; | ||
| 427 | for (i = 0; i < size; i++) { | ||
| 428 | printf("Byte %i: 0x%x\n", i, val[i]); | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | bplist_node *parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t *position) { | ||
| 433 | bplist_node **nodeslist = NULL, **newaddr = NULL; | ||
| 434 | bplist_node *new_node = NULL, *root_node = NULL; | ||
| 435 | |||
| 436 | uint32_t nodeslength = 0; | ||
| 437 | uint8_t offset_size = 0, dict_param_size = 0; | ||
| 438 | offset_size = bpbuffer[bplength-26]; | ||
| 439 | dict_param_size = bpbuffer[bplength-25]; | ||
| 440 | uint64_t current_offset = 0; | ||
| 441 | //uint64_t num_objects = *(bpbuffer+(bplength-24)), root_object = *(bpbuffer+(bplength-16)), offset_table_index = *(bpbuffer+(bplength-8)); | ||
| 442 | uint64_t num_objects = 0, root_object = 0, offset_table_index = 0; | ||
| 443 | memcpy(&num_objects, bpbuffer+bplength-24, sizeof(uint64_t)); | ||
| 444 | memcpy(&root_object, bpbuffer+bplength-16, sizeof(uint64_t)); | ||
| 445 | memcpy(&offset_table_index, bpbuffer+bplength-8, sizeof(uint64_t)); | ||
| 446 | byte_convert(&num_objects, sizeof(uint64_t)); | ||
| 447 | byte_convert(&root_object, sizeof(uint64_t)); | ||
| 448 | byte_convert(&offset_table_index, sizeof(uint64_t)); | ||
| 449 | |||
| 450 | log_debug_msg("Offset size: %i\nGiven: %i\n", offset_size, bpbuffer[bplength-26]); | ||
| 451 | log_debug_msg("Ref size: %i\nGiven: %i\n", dict_param_size, bpbuffer[bplength-25]); | ||
| 452 | log_debug_msg("Number of objects: %lli\nGiven: %llu\n", num_objects, *(bpbuffer+bplength-24)); | ||
| 453 | log_debug_msg("Root object index: %lli\nGiven: %llu\n", root_object, *(bpbuffer+bplength-16)); | ||
| 454 | log_debug_msg("Offset table index: %lli\nGiven: %llu\n", offset_table_index, *(bpbuffer+bplength-8)); | ||
| 455 | log_debug_msg("Size of uint64: %i\n", sizeof(uint64_t)); | ||
| 456 | |||
| 457 | int i = 0, j = 0, k = 0, str_i = 0, str_j = 0; | ||
| 458 | uint32_t index1 = 0, index2 = 0; | ||
| 459 | |||
| 460 | nodeslist = (bplist_node**)malloc(sizeof(bplist_node*) * num_objects); | ||
| 461 | if (!nodeslist) return NULL; | ||
| 462 | |||
| 463 | for (i = 0; i < num_objects; i++) { | ||
| 464 | memcpy(¤t_offset, bpbuffer+(offset_table_index+(i*offset_size)), offset_size); | ||
| 465 | //current_offset = (offset_size == 2) ? ntohs(current_offset) : (offset_size == 4) ? ntohl(current_offset) : current_offset; | ||
| 466 | //if (offset_size == 8) byte_convert(¤t_offset, 8); | ||
| 467 | byte_convert(¤t_offset, (offset_size <= sizeof(current_offset)) ? offset_size : sizeof(current_offset)); | ||
| 468 | log_debug_msg("parse_nodes: current_offset = %x\n", current_offset); | ||
| 469 | nodeslist[i] = parse_raw_node(bpbuffer, bplength, ¤t_offset, dict_param_size); | ||
| 470 | log_debug_msg("parse_nodes: parse_raw_node done\n"); | ||
| 471 | } | ||
| 472 | |||
| 473 | |||
| 474 | for (i = 0; i < num_objects; i++) { | ||
| 475 | // set elements for dicts and arrays and leave the rest alone | ||
| 476 | log_debug_msg("parse_nodes: on node %i\n", i); | ||
| 477 | switch (nodeslist[i]->type) { | ||
| 478 | case BPLIST_DICT: | ||
| 479 | log_debug_msg("parse_nodes: dictionary found\n"); | ||
| 480 | nodeslist[i]->subnodes = (bplist_node*)malloc(sizeof(bplist_node) * nodeslist[i]->length); | ||
| 481 | for (j = 0; j < (nodeslist[i]->length / 2); j++) { | ||
| 482 | str_i = j * nodeslist[i]->intval8; | ||
| 483 | str_j = (j + (nodeslist[i]->length / 2)) * nodeslist[i]->intval8; | ||
| 484 | |||
| 485 | memcpy(&index1, nodeslist[i]->strval+str_i, nodeslist[i]->intval8); | ||
| 486 | memcpy(&index2, nodeslist[i]->strval+str_j, nodeslist[i]->intval8); | ||
| 487 | //index1 = (dict_param_size == 1) ? index1 : (dict_param_size == 2) ? ntohs(index1) : (dict_param_size == 4) ? ntohl(index1) : index1; | ||
| 488 | //index2 = (dict_param_size == 1) ? index2 : (dict_param_size == 2) ? ntohs(index2) : (dict_param_size == 4) ? ntohl(index2) : index2; | ||
| 489 | byte_convert(&index1, (dict_param_size <= sizeof(index1)) ? dict_param_size : sizeof(index2)); | ||
| 490 | byte_convert(&index2, (dict_param_size <= sizeof(index2)) ? dict_param_size : sizeof(index2)); | ||
| 491 | //printf("parse_nodes: key index %i value %i\n", index1, index2); | ||
| 492 | //printf("parse_nodes: key type %x and length %i\n", nodeslist[index1]->type, nodeslist[index1]->length); | ||
| 493 | //printf("parse_nodes: value type %x and length %i\n", nodeslist[index2]->type, nodeslist[index2]->length); | ||
| 494 | nodeslist[i]->subnodes[k++] = nodeslist[index1]; | ||
| 495 | nodeslist[i]->subnodes[k++] = nodeslist[index2]; | ||
| 496 | } | ||
| 497 | |||
| 498 | nodeslist[i]->length = nodeslist[i]->length / 2; | ||
| 499 | free(nodeslist[i]->strval); | ||
| 500 | k = 0; | ||
| 501 | break; | ||
| 502 | |||
| 503 | case BPLIST_ARRAY: | ||
| 504 | log_debug_msg("parse_nodes: array found\n"); | ||
| 505 | nodeslist[i]->subnodes = (bplist_node*)malloc(sizeof(bplist_node) * nodeslist[i]->length); // memory allocation helps a lot when storing data | ||
| 506 | |||
| 507 | for (j = 0; j < nodeslist[i]->length; j++) { | ||
| 508 | log_debug_msg("parse_nodes: array index %i\n", j); | ||
| 509 | str_j = j * nodeslist[i]->intval8; | ||
| 510 | //index1 = nodeslist[i]->strval[j]; | ||
| 511 | memcpy(&index1, nodeslist[i]->strval+str_j, nodeslist[i]->intval8); | ||
| 512 | log_debug_msg("parse_nodes: post-memcpy\n"); | ||
| 513 | //index1 = (dict_param_size == 1) ? index1 : (dict_param_size == 2) ? ntohs(index1) : (dict_param_size == 4) ? ntohl(index1) : index1; | ||
| 514 | byte_convert(&index1, (dict_param_size <= sizeof(index1)) ? dict_param_size : sizeof(index1)); | ||
| 515 | log_debug_msg("parse_nodes: post-ntohl\nindex1 = %i\n", index1); | ||
| 516 | nodeslist[i]->subnodes[j] = nodeslist[index1]; | ||
| 517 | log_debug_msg("parse_nodes: post-assignment\n"); | ||
| 518 | } | ||
| 519 | free(nodeslist[i]->strval); | ||
| 520 | break; | ||
| 521 | default: | ||
| 522 | //printf("lol... type %x\n", nodeslist[i]->type); | ||
| 523 | break; | ||
| 524 | } // those are the only two we need to correct for. | ||
| 525 | } | ||
| 526 | |||
| 527 | root_node = nodeslist[root_object]; | ||
| 528 | return root_node; | ||
| 529 | } | ||
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 @@ | |||
| 24 | 24 | ||
| 25 | #include <libxml/parser.h> | 25 | #include <libxml/parser.h> |
| 26 | #include <libxml/tree.h> | 26 | #include <libxml/tree.h> |
| 27 | #include <stdint.h> | ||
| 28 | #include <wchar.h> | ||
| 29 | |||
| 30 | #include <sys/types.h> | ||
| 31 | #include <sys/stat.h> | ||
| 32 | #include <unistd.h> | ||
| 27 | 33 | ||
| 28 | xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); | 34 | xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); |
| 29 | xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); | 35 | 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(); | |||
| 35 | 41 | ||
| 36 | char **read_dict_element_strings(xmlNode * dict); | 42 | char **read_dict_element_strings(xmlNode * dict); |
| 37 | void free_dictionary(char **dictionary); | 43 | void free_dictionary(char **dictionary); |
| 44 | |||
| 45 | /* Binary plist stuff */ | ||
| 46 | |||
| 47 | enum { | ||
| 48 | BPLIST_TRUE = 0x08, | ||
| 49 | BPLIST_FALSE = 0x09, | ||
| 50 | BPLIST_FILL = 0x0F, /* will be used for length grabbing */ | ||
| 51 | BPLIST_INT = 0x10, | ||
| 52 | BPLIST_REAL = 0x20, | ||
| 53 | BPLIST_DATE = 0x33, | ||
| 54 | BPLIST_DATA = 0x40, | ||
| 55 | BPLIST_STRING = 0x50, | ||
| 56 | BPLIST_UNICODE = 0x60, | ||
| 57 | BPLIST_UID = 0x70, | ||
| 58 | BPLIST_ARRAY = 0xA0, | ||
| 59 | BPLIST_SET = 0xC0, | ||
| 60 | BPLIST_DICT = 0xD0, | ||
| 61 | BPLIST_MASK = 0xF0 | ||
| 62 | }; | ||
| 63 | |||
| 64 | typedef struct _bplist_node { | ||
| 65 | struct _bplist_node *next, **subnodes; // subnodes is for arrays, dicts and (potentially) sets. | ||
| 66 | uint64_t length, intval64; | ||
| 67 | uint32_t intval32; // length = subnodes | ||
| 68 | uint16_t intval16; | ||
| 69 | uint8_t intval8; | ||
| 70 | uint8_t type, *indexes; // indexes for array-types; essentially specify the order in which to access for key => value pairs | ||
| 71 | char *strval; | ||
| 72 | double realval; | ||
| 73 | wchar_t *unicodeval; | ||
| 74 | } bplist_node; | ||
| 75 | |||
| 38 | #endif | 76 | #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; | |||
| 37 | * | 37 | * |
| 38 | * @return A USBMux packet | 38 | * @return A USBMux packet |
| 39 | */ | 39 | */ |
| 40 | usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) | 40 | usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port) |
| 41 | { | 41 | { |
| 42 | usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); | 42 | usbmux_tcp_header *conn = (usbmux_tcp_header *) malloc(sizeof(usbmux_tcp_header)); |
| 43 | conn->type = htonl(6); | 43 | 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 @@ | |||
| 22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
| 23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
| 24 | #include <stdint.h> | 24 | #include <stdint.h> |
| 25 | #include "libiphone/libiphone.h" | ||
| 25 | 26 | ||
| 26 | #ifndef USBMUX_H | 27 | #ifndef USBMUX_H |
| 27 | #define USBMUX_H | 28 | #define USBMUX_H |
| @@ -30,17 +31,12 @@ | |||
| 30 | #include "iphone.h" | 31 | #include "iphone.h" |
| 31 | #endif | 32 | #endif |
| 32 | 33 | ||
| 33 | typedef uint16_t uint16; | ||
| 34 | typedef uint32_t uint32; | ||
| 35 | typedef uint8_t uint8; | ||
| 36 | |||
| 37 | |||
| 38 | typedef struct { | 34 | typedef struct { |
| 39 | uint32 type, length; | 35 | uint32_t type, length; |
| 40 | uint16 sport, dport; | 36 | uint16_t sport, dport; |
| 41 | uint32 scnt, ocnt; | 37 | uint32_t scnt, ocnt; |
| 42 | uint8 offset, tcp_flags; | 38 | uint8_t offset, tcp_flags; |
| 43 | uint16 window, nullnull, length16; | 39 | uint16_t window, nullnull, length16; |
| 44 | } usbmux_tcp_header; | 40 | } usbmux_tcp_header; |
| 45 | 41 | ||
| 46 | struct iphone_umux_client_int { | 42 | struct iphone_umux_client_int { |
| @@ -50,10 +46,10 @@ struct iphone_umux_client_int { | |||
| 50 | int r_len; | 46 | int r_len; |
| 51 | }; | 47 | }; |
| 52 | 48 | ||
| 53 | usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); | 49 | usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port); |
| 54 | 50 | ||
| 55 | typedef struct { | 51 | typedef struct { |
| 56 | uint32 type, length, major, minor, allnull; | 52 | uint32_t type, length, major, minor, allnull; |
| 57 | } usbmux_version_header; | 53 | } usbmux_version_header; |
| 58 | 54 | ||
| 59 | usbmux_version_header *version_header(); | 55 | usbmux_version_header *version_header(); |
