Commit f4c4b783 authored by Zach C's avatar Zach C Committed by Jonathan Beck

Added binary-plist support (tweaked slightly to move stuff around)

Signed-off-by: 's avatarMatt Colyer <matt@colyer.name>

fix makefile to take correct main function into account
parent 8c3a01e1
......@@ -3,7 +3,7 @@ INCLUDES = -I$(top_srcdir)/include
AM_CFLAGS = $(libxml2_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g
AM_LDFLAGS = $(libxml2_LIBS) $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)
bin_PROGRAMS = iphoneclient lckd-client afccheck
bin_PROGRAMS = iphoneclient lckd-client afccheck plutil
iphoneclient_SOURCES = main.c
iphoneclient_LDADD = ../src/libiphone.la
......@@ -16,4 +16,9 @@ lckd_client_LDADD = ../src/libiphone.la
afccheck_SOURCES = afccheck.c
afccheck_CFLAGS = $(AM_CFLAGS)
afccheck_LDFLAGS = $(AM_LDFLAGS)
afccheck_LDADD = ../src/libiphone.la
\ No newline at end of file
afccheck_LDADD = ../src/libiphone.la
plutil_SOURCES = plutil.c
plutil_CFLAGS = $(AM_CFLAGS)
plutil_LDFLAGS = $(AM_LDFLAGS)
plutil_LDADD = ../src/libiphone.la
/*
* main.c for plistutil
* right now just prints debug shit
*/
#include "../src/plist.h"
#include "plutil.h"
int debug = 0;
void print_nodes(bplist_node *root_node) {
// Yay, great. Let's print the list of nodes recursively...
int i = 0;
if (!root_node) return; // or not, because the programmer's stupid.
switch (root_node->type) {
case BPLIST_DICT:
printf("Dictionary node.\nLength %i\n", root_node->length);
for (i = 0; i < (root_node->length * 2); i+=2) {
// HI!
printf("Key: ");
print_nodes(root_node->subnodes[i]);
printf("Value: ");
print_nodes(root_node->subnodes[i+1]);
}
printf("End dictionary node.\n\n");
break;
case BPLIST_ARRAY:
printf("Array node.\n");
for (i = 0; i < root_node->length; i++) {
printf("\tElement %i: ", i);
print_nodes(root_node->subnodes[i]);
}
break;
case BPLIST_INT:
if (root_node->length == sizeof(uint8_t)) {
printf("Integer: %i\n", root_node->intval8);
} else if (root_node->length == sizeof(uint16_t)) {
printf("Integer: %i\n", root_node->intval16);
} else if (root_node->length == sizeof(uint32_t)) {
printf("Integer: %i\n", root_node->intval32);
}
break;
case BPLIST_STRING:
case BPLIST_DATA:
printf("String/data: ");
fwrite(root_node->strval, sizeof(char), root_node->length, stdout);
fflush(stdout);
printf("\n");
break;
case BPLIST_UNICODE:
printf("Unicode data, may appear crappy: ");
fwrite(root_node->unicodeval, sizeof(wchar_t), root_node->length, stdout);
fflush(stdout);
printf("\n");
break;
case BPLIST_TRUE:
printf("True.\n");
break;
case BPLIST_FALSE:
printf("False.\n");
break;
case BPLIST_REAL:
case BPLIST_DATE:
printf("Real(?): %f\n", root_node->realval);
break;
default:
printf("oops\nType set to %x and length is %i\n", root_node->type, root_node->length);
break;
}
}
int main(int argc, char *argv[]) {
struct stat *filestats = (struct stat *)malloc(sizeof(struct stat));
uint32_t position = 0;
Options *options = parse_arguments(argc, argv);
int argh = 0;
printf("plistutil version 0.2 written by FxChiP\n");
if (!options) {
print_usage();
return 0;
}
debug = options->debug;
FILE *bplist = fopen(options->in_file, "r");
stat(options->in_file, filestats);
printf("here?\n");
char *bplist_entire = (char*)malloc(sizeof(char) * (filestats->st_size + 1));
//argh = fgets(bplist_entire, filestats->st_size, bplist);
argh = fread(bplist_entire, sizeof(char), filestats->st_size, bplist);
printf("read %i bytes\n", argh);
fclose(bplist);
printf("or here?\n");
// bplist_entire contains our stuff
bplist_node *root_node;
root_node = parse_nodes(bplist_entire, filestats->st_size, &position);
printf("plutil debug mode\n\n");
printf("file size %i\n\n", filestats->st_size);
if (!root_node) {
printf("Invalid binary plist (or some other error occurred.)\n");
return 0;
}
print_nodes(root_node);
return 0;
}
Options *parse_arguments(int argc, char *argv[]) {
int i = 0;
Options *options = (Options*)malloc(sizeof(Options));
memset(options, 0, sizeof(Options));
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")) {
if ((i+1) == argc) {
free(options);
return NULL;
}
options->in_file = argv[i+1];
i++;
continue;
}
if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")) {
if ((i+1) == argc) {
free(options);
return NULL;
}
options->out_file = argv[i+1];
i++;
continue;
}
if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v")) {
options->debug = 1;
}
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
free(options);
return NULL;
}
}
if (!options->in_file /*|| !options->out_file*/) {
free(options);
return NULL;
}
return options;
}
void print_usage() {
printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n");
printf("\n");
printf("\t-i or --infile: The file to read in.\n");
printf("\t-o or --outfile: The file to convert to.\n");
printf("\t-d, -v or --debug: Provide extended debug information.\n\n");
}
/*
* main.h - header for plistutil
* Written by FxChiP
*/
typedef struct _options {
char *in_file, *out_file;
uint8_t debug, in_fmt, out_fmt;
} Options;
Options *parse_arguments(int argc, char *argv[]);
void print_usage();
......@@ -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);
......@@ -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);
......
......@@ -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(&current_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(&current_offset, 8);
byte_convert(&current_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, &current_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;
}
......@@ -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
......@@ -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);
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment