libimobiledevice
Posted Tuesday 04 September 2018 at 21:15
Estimated reading time: 10 mins
Anyone who uses both Linux and an iDevice knows the struggle; Apple don't make iTunes for Linux, and all you can really do with your phone on Linux is browse your photos over USB, and even that is frequently unreliable and slow. Thankfully, however, there exists a set of open-source tools that you can use to interact with your iDevice, called libimobiledevice. Whilst they are available on the Debian and Ubuntu repos (sudo apt install libimobiledevice6
), this post aims to explain how to compile them yourself, how to acquire developer disk images, and some basic usage. I'll give apt commands to install any required packages, which should be compatible with Debian and Ubuntu (I am using Xubuntu). If you're using a non-apt-based distro, you'll need to find these packages yourself.
Compiling
Before we can compile libimobiledevice, we must first download the source code from GitHub. Ensure you have git installed and execute:
git clone https://github.com/libimobiledevice/libimobiledevice
Alternatively, you can navigate to the GitHub page and download it from there.
Before we can build libimobiledevice, there are a few packages you'll need to install. These are:
- build-essential
- automake
- autoconf
- libtool
- pkg-config
- cython
- openssl
- libplist-dev
- libplist++-dev
- libusbmuxd-dev
- usbmuxd
sudo apt install build-essential automake autoconf libtool pkg-config cython openssl libplist-dev libplist++-dev libusbmuxd-dev usbmuxd
You will likely have many of these installed already, but this command will make sure you have everything you need.
Navigate to where you have cloned libimobiledevice (by default, this will be ./libimobiledevice
) in your terminal. We now have to configure libimobiledevice and generate our makefile. This is easily done; simply execute ./autogen.sh
in your terminal. If at any point the script complains of a missing library, you should install this through your package manager. For apt-based distros, most libraries are typically named libsomething-dev
.
If it all goes correctly, you should see something like:
Configuration for libimobiledevice 1.2.1:
-------------------------------------------
Install prefix: .........: /usr/local
Debug code ..............: no
Python bindings .........: no
SSL support backend .....: OpenSSL
Now type 'make' to build libimobiledevice 1.2.1,
and then 'make install' for installation.
It should now be a simple matter of running make
in your terminal. If this completes without error, then you have successfully compiled libimobiledevice. You can either use it as-is, install it directly by running make install
in your terminal (not recommended), or, for apt-based distros, you can use checkinstall
to create a .deb package file which will be installed through apt. If you can, I'd highly recommend using checkinstall; it performs essentially the same function as make install
, but by creating a .deb file and installing the package through apt it's much easier to remove your compiled software should you ever want to, and also makes distributing the compiled binaries to another computer much simpler.
Getting Developer Disk Images
libimobiledevice is now mostly fully-functional, but a few of the tools it provides are completely useless without a Developer Disk Image. These are what Xcode uses to perform certain functions, like launching apps from your computer, or remotely taking screenshots. There is a disk image for every major iOS version, and this will work across all minor versions (i.e. the image for iOS 11.4 will work for all 11.4.x versions, but not for any 11.3.x versions).
Developer Disk Images are distributed with Xcode, and can be extracted on Linux from the Xcode application file. You can download this from Apple (iCloud login required). Look for the latest download entitled "Xcode <version>" (at the time of writing, this was "Xcode 9.4.1"), and download it. Be warned; this will be quite a large file (Xcode 9.4.1 was 4.9GB) and it will take up a lot more space as we extract it, so make sure to save it to somewhere with a lot of free space. If you live somewhere (for example, China) where download speeds from Apple can be quite slow, please, just be patient and don't attempt to download Xcode from non-Apple sources, as this is what allowed XcodeGhost to spread.
Unless something has changed since the time of writing, you will be downloading a .xip file. This is a type of file known as an XAR file, or eXtensible ARchive file. The XAR format is basically just another kind of zip file that allows for digital signatures to be added to the file, so that the file contents can be verified before extraction. Your distro's archive manager may be open and extract it automatically, but it's unlikely.
Instead, you're going to need to compile another program. You can download the latest version of the source files from GitHub user mackyle. Just download and extract the tarball, open a terminal window here, and run ./configure && make
. The xar binary can then be found as ./src/xar. To extract your Xcode .xip, use:
src/xar -C <directory to extract to> -xf /path/to/Xcode.xip
This will take some time because of how large the archive is, but will extract two files; Content, and Metadata. We won't be using the Metadata file, but we will need to process Content.
In order to do this, we need a pbzx stream parser. I was able to find the source code for such a parser here, but I was unable to get it to compile because of one of its dependencies. Instead, I was able to find this gist, a Python reimplementation of the pbzx parser. You can download it with:
wget https://gist.github.com/Lekensteyn/6e0840e77bc9bd013f57/raw/d8c757de5293b5c3a1ab644297e2cb97d65378dc/parse_pbzx.py && chmod +x parse_pbzx.py
We can now dump a directory listing of the .xip file. The pbzx parser will interpret the file, allowing cpio to decode it. We can get the directory listing to a file by running ./parse_pbzx.py /path/to/Content | cpio -t > dir_listing
(this will take a long time, though, due to the sheer number of files in the archive). If you want, you can extract the entirety of the archive to the current directory with ./parse_pbzx.py /path/to/Content | cpio -i
, but this, too, will take a long time to get the files you need and will waste a lot of space on your hard drive.
If you were to generate this directory listing, and you searched for DeveloperDiskImage, you'd find the path ./Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
. All the files under this path are Developer Disk Images. Thankfully, cpio has the ability to filter which files are extracted. To extract our iPhone Developer Disk Images, we use the following command:
mkdir -p "Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/" && ./parse_pbzx.py /path/to/Content | cpio -i "./Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/*"
Leave this command running for a while (you can add the -v
argument if you want to make sure it's still working) and check inside the Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport folder we've created. Eventually a bunch of numbered directories, each corresponding to an iOS version, will start to appear here. Inside each of these directories you'll find two files: DeveloperDiskImage.img and DeveloperDiskImage.img.sig. These are the files we need to fully utilise all of libimobiledevice's tools! Once you have all the versions you need, and you can see their file sizes aren't changing, feel free to kill the command and delete all the Xcode archive files.
Using libimobiledevice
If you return, in a terminal, to wherever you compiled libimobiledevice you can begin to make use of the application. All of the tools you'll need to use are found in the tools subdirectory of libimobiledevice, and you can either change to that directory or execute them from here (or, if you decided to install libimobiledevice, you can just run them from anywhere).
Almost all of these tools will require your device to be paired with your computer. Connect your device via USB, and, if necessary, enter your passcode to trust your computer, and use the following command:
tools/idevicepair pair
You should see a message in your terminal if pairing was successful. Now, you are able to perform many userland commands, for example backing up your phone with tools/idevicebackup2
, or get information about your device with tools/ideviceinfo
. All of these commands have helpful --help
messages that will tell you all the arguments you need to do what you want to do.
If you attempt to use tools/idevicedebug
or tools/idevicescreenshot
, you'll be informed that you need to mount your developer disk image. Now we can get some use out of them after we took the time to extract them. To mount them, use the following command:
tools/ideviceimagemounter /path/to/DeveloperDiskImage.dmg /path/to/DeveloperDiskImage.dmg.sig
Make sure to supply the right disk image and sig file for your version of iOS, else mounting will fail. Once the disk images are mounted, you can take screenshots of your phone screen that will be saved directly to your computer, and you can launch apps on your phone from your computer.
Once you're finished with the disk image, simply reboot your device to unmount it. You can either reboot it from your phone, or from your computer with the command:
tools/idevicediagnostics restart
I thought it improtant to document the compiling process and the process of extracting the disk images from Xcode. Neither of these things were explained to me, but through a combination of research and intuition I was able to master libimobiledevice. Both for my own sake and for anyone else trying to do the same in the future, I hope this post will be useful to you.