Remote iOS application debugging from Linux over USB
I recently had to debug an iOS application. As I am more a GNU/Linux user than an OS X one, I wanted to do it from my Linux machine. The easiest way would be to remotely debug over WiFi, but this might get quite frustrating, because of the recurring connection interruptions. Good news everyone: it is possible to do it over USB!
Here is what you need:
- a jailbroken iOS device (I used an iOS 9.0.2 one) with OpenSSH installed
- an OS X installation with Xcode for the
debugserver
(iOS equivalent ofgdbserver
) - that fancy USB proprietary cable
- your favorite Linux installation
Getting debugserver
This part is taken from that guide.
Once your iOS device is jailbroken with OpenSSH installed, it is time to go on
your OS X installation to prepare debugserver
which is sort of an iOS
application equivalent of gdbserver
. The Xcode application has developer disk
images for the supported iOS version:
Choose the one corresponding to the version of your jailbroken device. For example with a jailbroken iOS 9.0.2:
It should be mounted to /Volumes/DeveloperDiskImage
Copy debugserver
:
You can now unmount the developer disk image:
Create the entitlements.plist
file that will be used to resign the debugserver
:
Resign the debugserver
:
And finally copy the newly signed debugserver
to your Linux machine (e.g. with SSH).
Preparing the Linux host
I mentioned that debugserver
is an iOS application equivalent to the
gdbserver
. It’s not entirely true because it is not compatible with gdb
but
with lldb
, the debugger of the llvm project.
For example on a Debian based distribution:
Or on an Archlinux:
Launch usbmuxd
service, for example with systemd:
If your distribution doesn’t use systemd, the package should come with an init or upstart script that you can use to launch it.
Connect your jailbroken iOS device to your Linux host and create an SSH tunnel:
Now you should be able to SSH to your iOS device through port 2222. If not
already done, you should change the default alpine
root password now.
Back to your Linux machine, copy the debugserver
to the iOS device:
Now everything is set to debug your favorite application.
Finally debug something
To remotely debug an application, debugserver
binds to a port so that you can
connect to it with lldb
. Creating a tunnel with iproxy
to that specific port
won’t work, we have to create a proper SSH tunnel. With the previous tunnel
still active, create the SSH tunnel from the Linux machine:
This means that any connection on port 12345
on localhost of the Linux
machine will be redirected to the port 23456
of the iOS device through the
tunnel.
On the iOS device, debugserver
allows the following parrameters:
It can launch an application or attach to a running one and it listens either on a Unix or TCP socket. In our case, we have to use a TCP socket.
Here is an example of debugserver
attaching to process number 1844
and
listening on port 23456
for incoming connection from lldb
:
Now on the Linux machine, with both tunnels still open, run lldb
and attach
to the debugserver
:
For those that like to add extra functionalities to their debugger, such as
peda on gdb
, there is lisa that seems to add similar
functionalities as peda to lldb
.