Karmatr0n

Programming and Infosec for fun!

How to list all the installed apps in your iDevices

30 Jan 2015

I wrote a program using the idevice rubygem to print a list of all applications installed on each device based on iOS, using the bindings for the libimobiledevice and libplist libraries, and running on Mac OSX or Linux (Santoku or Remnux).

I think It could be useful for forensics or maybe just to identify how many apps you have installed on all your devices.

You have to connect all your devices and run the program to get a list including each UUID and name per device, with a list of installed applications that includes its category, version, name and path to the disk (nand).

The script does not depend on the jailbreak, and you should authorize your computer when each device asks if it should trust in that.

Its design is very simple, the program gets an array of strings with the UUID of each device connected to your computer through the device_list method defined in the iDevice class. So, behind the scenes the idevice gem is using Ruby-FFI to implement the bindings for the functions included in the libimobiledevice and libplist libraries.

Both libraries are implemented in C, the libimobildevice library is designed to support the communication protocols by the USB ports connected to devices based on iOS (iPhone/iPod/iPad/AppleTV) using libusbmuxd (linux) or usbmuxd (macosx). The libplist library is designed to manipulate the Apple Property List format (binary or XML).

To get the name of each device the program uses the device_name method in the iDevice :: LockdownClient object. Then It will get the application list through the browse method in the iDevice::InstProxyClient object, and it prints the attributes defined in the props array.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
require 'bundler/setup'
require 'idevice'

def print_dev_info(idev)
  ldcli = Idevice::LockdownClient.attach(idev:idev)
  puts "%-40s    %s" % ["UUID", "Device name"]
  info = "%-40s => %s" % [idev.udid, ldcli.device_name]
  puts info
  puts "-" * info.length
end

def print_app_properties(cols)
  cols[2] = cols[2].to_s.slice(0,27) + "..." if cols[2].to_s.size > 30
  puts "%-15s %-15s %-30s %s/%s" % cols
end

Idevice.device_list.each do |udid|
  idev = Idevice::Idevice.attach(udid: udid)
  print_dev_info idev

  props = %w(ApplicationType CFBundleVersion CFBundleDisplayName Path
             CFBundleExecutable)
  print_app_properties props
  instpxy = Idevice::InstProxyClient.attach(idev: idev)
  instpxy.browse.sort { |a,b| a[props.at(0)] <=> b[props.at(0)] }.map do |app|
    print_app_properties app.values_at(*props)
  end

  puts ""
end

Get the source code!

Running the script

$ cd app-per-idev
$ bundle install
$ ./app-per-idev

Output

Screenshot

References