Wednesday 29 May 2013

Remote Debugging iOS using lldb...

As per previous post, I attended HITB 2013 Amsterdam in April. I decided to do the mobile hacking course run by Blake Turrentine from HotWan, @Pod2g & @P0sixninja.
One thing I picked up from the course was the remote debugging of user land applications using lldb. In order to do this you need to have the following:
  • A mac with Xcode installed
  • Jailbroken Device (iOS.6.1) running ssh
Step 1 - First you need to mount the DeveloperDiskImage.dmg for 6.1. In a terminal window type the following:
  • hdiutil attach /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/6.1\ \(10B141\)/DeveloperDiskImage.dmg
Step 2 - Create a temporary directory on your mac and copy the debugserver to it:
  • mkdir debug
  • cd debug
  • cp /Volumes/DeveloperDiskImage/usr/bin/debugserver . 

Step 3 - Next, you need to code sign the executable using an entitlements file. To make the entitlements file do the following:
  • nano entitlements.plist
  • copy and paste the text below into the terminal window 
<?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.springboard.debugapplications</key>
    <true/>
    <key>run-unsigned-code</key>
    <true/>
    <key>get-task-allow</key>
    <true/>
    <key>task_for_pid-allow</key>
    <true/>
</dict>
</plist>

  • press ctrl+x to quit, then Y to save and hit return to exit nano
  • You should have something like below if you cat entitlements.plist 
  • If you don't want to make the entitlements file just download it from the link here
Step 4 - Now you need to sign the executable with the entitlements file you just created:
  • codesign -s  - --entitlements entitlements.plist -f debugserver 

Step 5 - You can unmount the developer .dmg.
  • hdiutil detach /Volumes/DeveloperDiskImage/

Step 6 - Copy the executable to the iPad (this assumes you have ssh running on the device, if you don't you need to do that first). I use usbmux to connect to my iPad via usb, but you could connect via WiFi using the IP address.
  • Starting usbmuxd to forward local port  2222 on my mac to 22 on the remote device
  • Use scp to copy to Device, when prompted enter the password for the root account on your Device (iPad / iPhone). You could use cyberduck or any file transfer application you have. 
  • scp -P 2222 debugserver root@localhost:/var/root

Step 7 - ssh onto the device, start the debugserver and select a port for the server to listen on:
  • ./debugserver localhost:1234 --attach=<TheProcessNameYouWantToDebug>
If you get the error below:

dyld: Library not loaded: /Developer/Library/PrivateFrameworks/ARMDisassembler.framework/ARMDisassemblerReferenced from: /private/var/root/./debugserverReason: image not found


You need to start Xcode with the device connected via usb to your mac and navigate to Window > Organizer (or press cmd + shift + 2) then select the Devices and choose your device from the left hand side pane and ensure the device is configured for development (see apple developer documentation here)


If you are not enrolled in the Apple developer program and have no intention too then you can mount the "DeveloperDiskImage.dmg for 6.1" again (as per step 1) and copy the contents of  /Volumes/DeveloperDiskImage/Library to the /Developer directory on the device. This worked for me before I realised you needed to enrol the device as a development device :) 

Step 8 - If the debug server has started ok and is listening the terminal session will appear to hang as below:


Step 9 - If you are using usbmuxd you will need to ensure the port you just set the debug server to listen on is being forwarded from your mac over usb to the remote port (if you are using IP add to connect to the device you don't need to worry about this).
  • sudo ./Tools/iPhone/usbmuxd/usbmuxd-1.0.8/python-client/tcprelay.py -t 1234:1234

Step 10 - On your mac you can now start lldb 
  • Type lldb at a command prompt
  • Once lldb console has started type platform select remote-ios and hit enter.

Step 11 - Connect to the debugserver running on the device:
  • process connect connect://localhost:1234

Step 12 - You are now attached to the process and can debug using lldb commands
  • register read
  • bt


The following link (http://lldb.llvm.org/lldb-gdb.html) is a gdb to lldb comparison chart that might help if you know the gdb command you want but don't know the lldb command.

I need to do some more work with lldb as I have never really used it, I'm hoping this will be a useful way to look into some apps I have been wanting to reverse for a little while.

3 comments:

  1. what can be done here ?

    (lldb) platform select remote-ios
    Platform: remote-ios
    Connected: no
    SDK Path: error: unable to locate SDK
    (lldb)

    ReplyDelete
    Replies
    1. Is the device configured for development in xcode organiser?

      Delete
  2. do you also go on ios kernel debug? I can't connect the kernel via lldb, always fail, any suggestion?

    ReplyDelete