summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2016-09-23 20:07:48 +0200
committerGravatar Nikias Bassen2016-09-23 20:07:48 +0200
commit00424f40574641d1360c9b1115770f5cc5d19a72 (patch)
tree0188e67ffc798aeddab2d75848b715dcb707bf28
parent3fc7a85778d85a1dda1c0c4bedc8467470468476 (diff)
downloadlibimobiledevice-00424f40574641d1360c9b1115770f5cc5d19a72.tar.gz
libimobiledevice-00424f40574641d1360c9b1115770f5cc5d19a72.tar.bz2
idevicebackup2: Add installed application info to Info.plist during backup
For newer iOS versions, apparently >= iOS 8, iTunes stores information about installed applications inside of the Info.plist file. This commit mimics that behavior.
-rw-r--r--tools/idevicebackup2.c115
1 files changed, 110 insertions, 5 deletions
diff --git a/tools/idevicebackup2.c b/tools/idevicebackup2.c
index 3b2c0af..2c868d7 100644
--- a/tools/idevicebackup2.c
+++ b/tools/idevicebackup2.c
@@ -40,6 +40,8 @@
40#include <libimobiledevice/mobilebackup2.h> 40#include <libimobiledevice/mobilebackup2.h>
41#include <libimobiledevice/notification_proxy.h> 41#include <libimobiledevice/notification_proxy.h>
42#include <libimobiledevice/afc.h> 42#include <libimobiledevice/afc.h>
43#include <libimobiledevice/installation_proxy.h>
44#include <libimobiledevice/sbservices.h>
43#include "common/utils.h" 45#include "common/utils.h"
44 46
45#include <endianness.h> 47#include <endianness.h>
@@ -274,7 +276,24 @@ static int rmdir_recursive(const char* path)
274 return remove_directory(path); 276 return remove_directory(path);
275} 277}
276 278
277static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_client_t lockdown, afc_client_t afc) 279static char* get_uuid()
280{
281 const char *chars = "ABCDEF0123456789";
282 int i = 0;
283 char *uuid = (char*)malloc(sizeof(char) * 32);
284
285 srand(time(NULL));
286
287 for (i = 0; i < 32; i++) {
288 uuid[i] = chars[rand() % 16];
289 }
290
291 uuid[32] = '\0';
292
293 return uuid;
294}
295
296static plist_t mobilebackup_factory_info_plist_new(const char* udid, idevice_t device, lockdownd_client_t lockdown, afc_client_t afc)
278{ 297{
279 /* gather data from lockdown */ 298 /* gather data from lockdown */
280 plist_t value_node = NULL; 299 plist_t value_node = NULL;
@@ -286,6 +305,74 @@ static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_c
286 /* get basic device information in one go */ 305 /* get basic device information in one go */
287 lockdownd_get_value(lockdown, NULL, NULL, &root_node); 306 lockdownd_get_value(lockdown, NULL, NULL, &root_node);
288 307
308 /* get a list of installed user applications */
309 plist_t app_dict = plist_new_dict();
310 plist_t installed_apps = plist_new_array();
311 instproxy_client_t ip = NULL;
312 if (instproxy_client_start_service(device, &ip, "idevicebackup2") == INSTPROXY_E_SUCCESS) {
313 plist_t client_opts = instproxy_client_options_new();
314 instproxy_client_options_add(client_opts, "ApplicationType", "User", NULL);
315 instproxy_client_options_set_return_attributes(client_opts, "CFBundleIdentifier", "ApplicationSINF", "iTunesMetadata", NULL);
316
317 plist_t apps = NULL;
318 instproxy_browse(ip, client_opts, &apps);
319
320 sbservices_client_t sbs = NULL;
321 if (sbservices_client_start_service(device, &sbs, "idevicebackup2") != SBSERVICES_E_SUCCESS) {
322 printf("Couldn't establish sbservices connection. Continuing anyway.\n");
323 }
324
325 if (apps && (plist_get_node_type(apps) == PLIST_ARRAY)) {
326 uint32_t app_count = plist_array_get_size(apps);
327 uint32_t i;
328 time_t starttime = time(NULL);
329 for (i = 0; i < app_count; i++) {
330 plist_t app_entry = plist_array_get_item(apps, i);
331 plist_t bundle_id = plist_dict_get_item(app_entry, "CFBundleIdentifier");
332 if (bundle_id) {
333 char *bundle_id_str = NULL;
334 plist_array_append_item(installed_apps, plist_copy(bundle_id));
335
336 plist_get_string_val(bundle_id, &bundle_id_str);
337 plist_t sinf = plist_dict_get_item(app_entry, "ApplicationSINF");
338 plist_t meta = plist_dict_get_item(app_entry, "iTunesMetadata");
339 if (sinf && meta) {
340 plist_t adict = plist_new_dict();
341 plist_dict_set_item(adict, "ApplicationSINF", plist_copy(sinf));
342 if (sbs) {
343 char *pngdata = NULL;
344 uint64_t pngsize = 0;
345 sbservices_get_icon_pngdata(sbs, bundle_id_str, &pngdata, &pngsize);
346 if (pngdata) {
347 plist_dict_set_item(adict, "PlaceholderIcon", plist_new_data(pngdata, pngsize));
348 free(pngdata);
349 }
350 }
351 plist_dict_set_item(adict, "iTunesMetadata", plist_copy(meta));
352 plist_dict_set_item(app_dict, bundle_id_str, adict);
353 }
354 }
355 if ((time(NULL) - starttime) > 5) {
356 // make sure our lockdown connection doesn't time out in case this takes longer
357 lockdownd_query_type(lockdown, NULL);
358 starttime = time(NULL);
359 }
360 }
361 }
362 plist_free(apps);
363
364 if (sbs) {
365 sbservices_client_free(sbs);
366 }
367
368 instproxy_client_options_free(client_opts);
369
370 instproxy_client_free(ip);
371 }
372
373 /* Applications */
374 plist_dict_set_item(ret, "Applications", app_dict);
375
289 /* set fields we understand */ 376 /* set fields we understand */
290 value_node = plist_dict_get_item(root_node, "BuildVersion"); 377 value_node = plist_dict_get_item(root_node, "BuildVersion");
291 plist_dict_set_item(ret, "Build Version", plist_copy(value_node)); 378 plist_dict_set_item(ret, "Build Version", plist_copy(value_node));
@@ -294,8 +381,9 @@ static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_c
294 plist_dict_set_item(ret, "Device Name", plist_copy(value_node)); 381 plist_dict_set_item(ret, "Device Name", plist_copy(value_node));
295 plist_dict_set_item(ret, "Display Name", plist_copy(value_node)); 382 plist_dict_set_item(ret, "Display Name", plist_copy(value_node));
296 383
297 /* FIXME: How is the GUID generated? */ 384 char *uuid = get_uuid();
298 plist_dict_set_item(ret, "GUID", plist_new_string("---")); 385 plist_dict_set_item(ret, "GUID", plist_new_string(uuid));
386 free(uuid);
299 387
300 value_node = plist_dict_get_item(root_node, "IntegratedCircuitCardIdentity"); 388 value_node = plist_dict_get_item(root_node, "IntegratedCircuitCardIdentity");
301 if (value_node) 389 if (value_node)
@@ -305,13 +393,21 @@ static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_c
305 if (value_node) 393 if (value_node)
306 plist_dict_set_item(ret, "IMEI", plist_copy(value_node)); 394 plist_dict_set_item(ret, "IMEI", plist_copy(value_node));
307 395
396 /* Installed Applications */
397 plist_dict_set_item(ret, "Installed Applications", installed_apps);
398
308 plist_dict_set_item(ret, "Last Backup Date", plist_new_date(time(NULL) - MAC_EPOCH, 0)); 399 plist_dict_set_item(ret, "Last Backup Date", plist_new_date(time(NULL) - MAC_EPOCH, 0));
309 400
401 value_node = plist_dict_get_item(root_node, "MobileEquipmentIdentifier");
402 plist_dict_set_item(ret, "MEID", plist_copy(value_node));
403
310 value_node = plist_dict_get_item(root_node, "PhoneNumber"); 404 value_node = plist_dict_get_item(root_node, "PhoneNumber");
311 if (value_node && (plist_get_node_type(value_node) == PLIST_STRING)) { 405 if (value_node && (plist_get_node_type(value_node) == PLIST_STRING)) {
312 plist_dict_set_item(ret, "Phone Number", plist_copy(value_node)); 406 plist_dict_set_item(ret, "Phone Number", plist_copy(value_node));
313 } 407 }
314 408
409 /* FIXME Product Name */
410
315 value_node = plist_dict_get_item(root_node, "ProductType"); 411 value_node = plist_dict_get_item(root_node, "ProductType");
316 plist_dict_set_item(ret, "Product Type", plist_copy(value_node)); 412 plist_dict_set_item(ret, "Product Type", plist_copy(value_node));
317 413
@@ -349,6 +445,7 @@ static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_c
349 "PhotosFolderAlbums", 445 "PhotosFolderAlbums",
350 "PhotosFolderName", 446 "PhotosFolderName",
351 "PhotosFolderPrefs", 447 "PhotosFolderPrefs",
448 "VoiceMemos.plist",
352 "iPhotoAlbumPrefs", 449 "iPhotoAlbumPrefs",
353 "iTunesApplicationIDs", 450 "iTunesApplicationIDs",
354 "iTunesPrefs", 451 "iTunesPrefs",
@@ -375,7 +472,15 @@ static plist_t mobilebackup_factory_info_plist_new(const char* udid, lockdownd_c
375 lockdownd_get_value(lockdown, "com.apple.iTunes", NULL, &itunes_settings); 472 lockdownd_get_value(lockdown, "com.apple.iTunes", NULL, &itunes_settings);
376 plist_dict_set_item(ret, "iTunes Settings", itunes_settings ? itunes_settings : plist_new_dict()); 473 plist_dict_set_item(ret, "iTunes Settings", itunes_settings ? itunes_settings : plist_new_dict());
377 474
378 plist_dict_set_item(ret, "iTunes Version", plist_new_string("10.0.1")); 475 /* since we usually don't have iTunes, let's get the minimum required iTunes version from the device */
476 value_node = NULL;
477 lockdownd_get_value(lockdown, "com.apple.mobile.iTunes", "MinITunesVersion", &value_node);
478 if (value_node) {
479 plist_dict_set_item(ret, "iTunes Version", plist_copy(value_node));
480 plist_free(value_node);
481 } else {
482 plist_dict_set_item(ret, "iTunes Version", plist_new_string("10.0.1"));
483 }
379 484
380 plist_free(root_node); 485 plist_free(root_node);
381 486
@@ -1688,7 +1793,7 @@ checkpoint:
1688 plist_free(info_plist); 1793 plist_free(info_plist);
1689 info_plist = NULL; 1794 info_plist = NULL;
1690 } 1795 }
1691 info_plist = mobilebackup_factory_info_plist_new(udid, lockdown, afc); 1796 info_plist = mobilebackup_factory_info_plist_new(udid, device, lockdown, afc);
1692 remove(info_path); 1797 remove(info_path);
1693 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML); 1798 plist_write_to_filename(info_plist, info_path, PLIST_FORMAT_XML);
1694 free(info_path); 1799 free(info_path);