summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Zach C2008-08-31 11:25:22 -0700
committerGravatar Jonathan Beck2008-11-24 22:49:07 +0100
commitf4c4b783c8dbe2fe8e7e6f6b5f19f0d44b489c9a (patch)
tree9ef8c57fe298a4ae9e0a443d7103e6126c869020
parent8c3a01e11bb9c74e2a1bb7da143cb35469f29fba (diff)
downloadlibimobiledevice-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
-rw-r--r--dev/Makefile.am9
-rw-r--r--dev/plutil.c171
-rw-r--r--dev/plutil.h13
-rw-r--r--src/AFC.c46
-rw-r--r--src/AFC.h10
-rw-r--r--src/lockdown.c14
-rw-r--r--src/plist.c284
-rw-r--r--src/plist.h38
-rw-r--r--src/usbmux.c2
-rw-r--r--src/usbmux.h20
10 files changed, 557 insertions, 50 deletions
diff --git a/dev/Makefile.am b/dev/Makefile.am
index 4833728..95b4d61 100644
--- a/dev/Makefile.am
+++ b/dev/Makefile.am
@@ -3,7 +3,7 @@ INCLUDES = -I$(top_srcdir)/include
3AM_CFLAGS = $(libxml2_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g 3AM_CFLAGS = $(libxml2_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g
4AM_LDFLAGS = $(libxml2_LIBS) $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) 4AM_LDFLAGS = $(libxml2_LIBS) $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)
5 5
6bin_PROGRAMS = iphoneclient lckd-client afccheck 6bin_PROGRAMS = iphoneclient lckd-client afccheck plutil
7 7
8iphoneclient_SOURCES = main.c 8iphoneclient_SOURCES = main.c
9iphoneclient_LDADD = ../src/libiphone.la 9iphoneclient_LDADD = ../src/libiphone.la
@@ -16,4 +16,9 @@ lckd_client_LDADD = ../src/libiphone.la
16afccheck_SOURCES = afccheck.c 16afccheck_SOURCES = afccheck.c
17afccheck_CFLAGS = $(AM_CFLAGS) 17afccheck_CFLAGS = $(AM_CFLAGS)
18afccheck_LDFLAGS = $(AM_LDFLAGS) 18afccheck_LDFLAGS = $(AM_LDFLAGS)
19afccheck_LDADD = ../src/libiphone.la \ No newline at end of file 19afccheck_LDADD = ../src/libiphone.la
20
21plutil_SOURCES = plutil.c
22plutil_CFLAGS = $(AM_CFLAGS)
23plutil_LDFLAGS = $(AM_LDFLAGS)
24plutil_LDADD = ../src/libiphone.la
diff --git a/dev/plutil.c b/dev/plutil.c
new file mode 100644
index 0000000..208d7df
--- /dev/null
+++ b/dev/plutil.c
@@ -0,0 +1,171 @@
1/*
2 * main.c for plistutil
3 * right now just prints debug shit
4 */
5
6#include "../src/plist.h"
7#include "plutil.h"
8
9int debug = 0;
10
11void print_nodes(bplist_node *root_node) {
12 // Yay, great. Let's print the list of nodes recursively...
13 int i = 0;
14 if (!root_node) return; // or not, because the programmer's stupid.
15
16 switch (root_node->type) {
17 case BPLIST_DICT:
18 printf("Dictionary node.\nLength %i\n", root_node->length);
19 for (i = 0; i < (root_node->length * 2); i+=2) {
20 // HI!
21 printf("Key: ");
22 print_nodes(root_node->subnodes[i]);
23 printf("Value: ");
24 print_nodes(root_node->subnodes[i+1]);
25 }
26 printf("End dictionary node.\n\n");
27 break;
28
29 case BPLIST_ARRAY:
30 printf("Array node.\n");
31 for (i = 0; i < root_node->length; i++) {
32 printf("\tElement %i: ", i);
33 print_nodes(root_node->subnodes[i]);
34 }
35 break;
36
37 case BPLIST_INT:
38 if (root_node->length == sizeof(uint8_t)) {
39 printf("Integer: %i\n", root_node->intval8);
40 } else if (root_node->length == sizeof(uint16_t)) {
41 printf("Integer: %i\n", root_node->intval16);
42 } else if (root_node->length == sizeof(uint32_t)) {
43 printf("Integer: %i\n", root_node->intval32);
44 }
45 break;
46
47 case BPLIST_STRING:
48 case BPLIST_DATA:
49 printf("String/data: ");
50 fwrite(root_node->strval, sizeof(char), root_node->length, stdout);
51 fflush(stdout);
52 printf("\n");
53 break;
54
55 case BPLIST_UNICODE:
56 printf("Unicode data, may appear crappy: ");
57 fwrite(root_node->unicodeval, sizeof(wchar_t), root_node->length, stdout);
58 fflush(stdout);
59 printf("\n");
60 break;
61
62 case BPLIST_TRUE:
63 printf("True.\n");
64 break;
65
66 case BPLIST_FALSE:
67 printf("False.\n");
68 break;
69
70 case BPLIST_REAL:
71 case BPLIST_DATE:
72 printf("Real(?): %f\n", root_node->realval);
73 break;
74
75 default:
76 printf("oops\nType set to %x and length is %i\n", root_node->type, root_node->length);
77 break;
78 }
79}
80
81int main(int argc, char *argv[]) {
82 struct stat *filestats = (struct stat *)malloc(sizeof(struct stat));
83 uint32_t position = 0;
84 Options *options = parse_arguments(argc, argv);
85 int argh = 0;
86
87 printf("plistutil version 0.2 written by FxChiP\n");
88
89 if (!options) {
90 print_usage();
91 return 0;
92 }
93
94 debug = options->debug;
95
96 FILE *bplist = fopen(options->in_file, "r");
97
98 stat(options->in_file, filestats);
99
100 printf("here?\n");
101 char *bplist_entire = (char*)malloc(sizeof(char) * (filestats->st_size + 1));
102 //argh = fgets(bplist_entire, filestats->st_size, bplist);
103 argh = fread(bplist_entire, sizeof(char), filestats->st_size, bplist);
104 printf("read %i bytes\n", argh);
105 fclose(bplist);
106 printf("or here?\n");
107 // bplist_entire contains our stuff
108 bplist_node *root_node;
109 root_node = parse_nodes(bplist_entire, filestats->st_size, &position);
110 printf("plutil debug mode\n\n");
111 printf("file size %i\n\n", filestats->st_size);
112 if (!root_node) {
113 printf("Invalid binary plist (or some other error occurred.)\n");
114 return 0;
115 }
116 print_nodes(root_node);
117 return 0;
118 }
119
120Options *parse_arguments(int argc, char *argv[]) {
121 int i = 0;
122
123 Options *options = (Options*)malloc(sizeof(Options));
124 memset(options, 0, sizeof(Options));
125
126 for (i = 1; i < argc; i++) {
127 if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")) {
128 if ((i+1) == argc) {
129 free(options);
130 return NULL;
131 }
132 options->in_file = argv[i+1];
133 i++;
134 continue;
135 }
136
137 if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")) {
138 if ((i+1) == argc) {
139 free(options);
140 return NULL;
141 }
142 options->out_file = argv[i+1];
143 i++;
144 continue;
145 }
146
147 if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v")) {
148 options->debug = 1;
149 }
150
151 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
152 free(options);
153 return NULL;
154 }
155 }
156
157 if (!options->in_file /*|| !options->out_file*/) {
158 free(options);
159 return NULL;
160 }
161
162 return options;
163}
164
165void print_usage() {
166 printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n");
167 printf("\n");
168 printf("\t-i or --infile: The file to read in.\n");
169 printf("\t-o or --outfile: The file to convert to.\n");
170 printf("\t-d, -v or --debug: Provide extended debug information.\n\n");
171}
diff --git a/dev/plutil.h b/dev/plutil.h
new file mode 100644
index 0000000..2146307
--- /dev/null
+++ b/dev/plutil.h
@@ -0,0 +1,13 @@
1
2/*
3 * main.h - header for plistutil
4 * Written by FxChiP
5 */
6
7typedef struct _options {
8 char *in_file, *out_file;
9 uint8_t debug, in_fmt, out_fmt;
10} Options;
11
12Options *parse_arguments(int argc, char *argv[]);
13void print_usage();
diff --git a/src/AFC.c b/src/AFC.c
index 54ea1bb..899bd47 100644
--- a/src/AFC.c
+++ b/src/AFC.c
@@ -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
474iphone_error_t iphone_afc_rename_file(iphone_afc_client_t client, const char *from, const char *to) 474iphone_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
926iphone_error_t iphone_afc_seek_file(iphone_afc_client_t client, iphone_afc_file_t file, int seekpos) 926iphone_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_
979iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_file_t file, uint32_t newsize) 979iphone_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
1015uint32 iphone_afc_get_file_handle(iphone_afc_file_t file) 1015uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)
1016{ 1016{
1017 return file->filehandle; 1017 return file->filehandle;
1018} 1018}
diff --git a/src/AFC.h b/src/AFC.h
index 463c13e..5e4d17c 100644
--- a/src/AFC.h
+++ b/src/AFC.h
@@ -29,12 +29,12 @@
29#include <glib.h> 29#include <glib.h>
30 30
31typedef struct { 31typedef 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
36typedef struct { 36typedef struct {
37 uint32 filehandle, unknown1, size, unknown2; 37 uint32_t filehandle, unknown1, size, unknown2;
38} AFCFilePacket; 38} AFCFilePacket;
39 39
40typedef struct __AFCToken { 40typedef struct __AFCToken {
@@ -51,7 +51,7 @@ struct iphone_afc_client_int {
51}; 51};
52 52
53struct iphone_afc_file_int { 53struct 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
77uint32 iphone_afc_get_file_handle(iphone_afc_file_t file); 77uint32_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
28const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ 30const 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
264uint32_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
273void 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
285bplist_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
425void 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
432bplist_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(&current_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(&current_offset, 8);
467 byte_convert(&current_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, &current_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
28xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); 34xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth);
29xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); 35xmlNode *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
36char **read_dict_element_strings(xmlNode * dict); 42char **read_dict_element_strings(xmlNode * dict);
37void free_dictionary(char **dictionary); 43void free_dictionary(char **dictionary);
44
45/* Binary plist stuff */
46
47enum {
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
64typedef 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 */
40usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port) 40usbmux_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
33typedef uint16_t uint16;
34typedef uint32_t uint32;
35typedef uint8_t uint8;
36
37
38typedef struct { 34typedef 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
46struct iphone_umux_client_int { 42struct 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
53usbmux_tcp_header *new_mux_packet(uint16 s_port, uint16 d_port); 49usbmux_tcp_header *new_mux_packet(uint16_t s_port, uint16_t d_port);
54 50
55typedef struct { 51typedef 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
59usbmux_version_header *version_header(); 55usbmux_version_header *version_header();