Hi Nerds!

In this post, we will explain how to setup debugging on iOS through USB. Let’s kick this off with the environment.

Environment⌗

You need:

usbmuxd⌗

We need to install usbmuxd. Run the following command in Terminal:

$ brew install libusbmuxd

After installation, we will run this command (used for the SSH session below):

$ iproxy 2222 22 &

Finally, run this command (used for the debugserver session below):

$ iproxy 6666 6666 &

Debugserver⌗

We need to pull debugserver from Xcode. Run this command:

$ ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/

The output should be the available iOS versions:

10.0 10.1 10.2 10.3 11.0 11.1 11.2 11.3 11.4 12.0 12.1 12.2 12.3 12.4 13.0 13.1 13.2 13.3 13.4 13.5 13.6 13.7 14.0 14.1 14.2 14.3 9.0 9.1 9.2 9.3

Choose the iOS version for your device. For this example, we are going to work with 13.7 to extract debugserver.

$ hdiutil attach /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/13.7/DeveloperDiskImage.dmg$ cp /Volumes/DeveloperDiskImage/usr/bin/debugserver .$ hdiutil detach /Volumes/DeveloperDiskImage

Now you should have debugserver in your current directory.

Sign Debugserver⌗

Sign debugserver with the following command:

$ codesign -s - --entitlements entitlements.plist -f debugserver

where entitlements.plist is the following plist:

<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
    <dict>
        <key>com.apple.backboardd.debugapplications</key>
        <true/>
        <key>com.apple.backboardd.launchapplications</key>
        <true/>
        <key>com.apple.diagnosticd.diagnostic</key>
        <true/>
        <key>com.apple.frontboard.debugapplications</key>
        <true/>
        <key>com.apple.frontboard.launchapplications</key>
        <true/>
        <key>com.apple.security.network.client</key>
        <true/>
        <key>com.apple.security.network.server</key>
        <true/>
        <key>com.apple.springboard.debugapplications</key>
        <true/>
        <key>com.apple.system-task-ports</key>
        <true/>
        <key>get-task-allow</key>
        <true/>
        <key>platform-application</key>
        <true/>
        <key>run-unsigned-code</key>
        <true/>
        <key>task_for_pid-allow</key>
        <true/>
    </dict>
</plist>

You can download the entitlements.plist here.

Copy Debugserver to the device⌗

Since we started usbmuxd with iproxy above, we are simply going to scp debugserver to the device. Run this command:

$ scp -P 2222 ./debugserver root@localhost:/usr/bin/

Checking Debugserver on the device⌗

First, we need to SSH into the iOS device. Run this command:

$ ssh root@localhost -p 2222

Next, let’s verify that debugserver is installed by running this command:

ls -la /usr/bin/ | grep -i debugserver

The output should look something like this:

-rwxr-xr-x   1 root wheel   9872352 Jan  2 18:32 debugserver*

Start Debugging⌗

Launch the “Settings” app on your iOS device. We should also validate the process has started by running this command:

ps aux | grep -i Preferences

The output should be similar to this:

mobile         10115   0.0  3.1  4903072  63392   ??  Ss    5:47PM   0:01.11 /Applications/Preferences.app/Preferences

At last! Lets attach debugserver to the Preferences process:

debugserver localhost:6666 -a Preferences

The output should be similar to the following:

debugserver-@(#)PROGRAM:LLDB  PROJECT:lldb-10.0.0 for arm64.
Attaching to process Preferences...
Listening to port 6666 for a connection from localhost...

Now, open a new Terminal window on macOS and run the following:

$ lldb
(lldb) platform select remote-ios
(lldb) process connect connect://localhost:6666

After some time, finally, it will connect and display something like this:

Process 10115 stopped* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP    
    frame #0: 0x00000001ab104634 libsystem_kernel.dylib`mach_msg_trap + 8libsystem_kernel.dylib`mach_msg_trap:->  
        0x1ab104634 <+8>: retlibsystem_kernel.dylib`mach_msg_overwrite_trap:    
        0x1ab104638 <+0>: mov    x16, #-0x20    
        0x1ab10463c <+4>: svc    #0x80    
        0x1ab104640 <+8>: retTarget 0: 
(Preferences) stopped.

The End⌗

Well that wraps it up. Thanks for reading and we hope you enjoyed it.

- EvilPenguin