Mobile Debugging

iOS

When you are assessing an application, attaching a debugger can be a powerful technique for understanding the application's inner workings. A couple of debuggers work on iOS and the one that works best for you will depend upon what you are trying to debug and the resources available to you. If you have done any debugging on UNIX-like platforms or debugged an iOS application under XCode, you are likely familiar with the tools used for debugging: gdb or lldb.

gdb

The version of gdb in the default cydia repositories does not work well with newer versions of iOS. You need to reinstall gdb via http://cydia.radare.org.

These versions of gdb are limited to 32-bit devices. You must thin the binary to the required architecture, which you can do using lipo:

  1. Crack the app and put the cracked binary in /var/mobile/
  2. Open MobileTerminal, and run this command:
    lipo <nameofbinaryhere> -thin armv7 -output <nameofnewbinary>
  3. Take the new binary you created and replace the old binary in the app folder.
  4. Set the permissions of the new binary to:
    Mobile
    Mobile
    Read, write, execute
    Read, write, execute
    Read, write, execute
  5. Open up the app (I just like to do this)

Unfortunately, the non-Apple version of GNU gdb is currently unable to debug universal (or 'fat') binaries (ones that contain both 32-bit and 64-bit executables).

One option is to use lipo to extract a single architecture and run gdb on that:

lipo -thin x86_64 -output app-x86_64 ./app
or
lipo -thin i386 -output app-i386 ./app

If you'd prefer to debug the combined executable, you could try using LLDB, or an Apple version of gdb.

LLDB

1. Extract debugserver

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

6.0     7.0     8.0     8.2     8.4     9.1  
6.1     7.1     8.1     8.3     9.0     9.2 (13C75)

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

2. Sign debugserver

$ codesign -s - --entitlements entitlements.plist -f debugserver
// content of entitlements.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.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>  

3. Copy debugserver to iOS

$ scp ./debugserver root@192.168.0.101:/usr/bin/

4. Debugging

On your mac, ssh to your phone

$ ssh root@[your_iphone_ip]

// it's recommended to use USB
See: [ssh-with-usd](http://ninoishere.com/ssh-to-ios-via-usb/)  

Find your target App

ITS-iPhone-6s-black:/private/var/mobile/Containers/Bundle/Application root# find -name 'yourapp'  
./3FDA7FA6-48BE-4567-94D2-F9AB0AE3D394/yourapp.app/yourapp

Start debugserver

ITS-iPhone-6s-black:/private/var/mobile/Containers/Bundle/Application root# debugserver *:2008 ./3FDA7FA6-48BE-4567-94D2-F9AB0AE3D394/yourapp.app/yourapp  
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-340.3.51.1  
 for arm64.
Listening to port 2008 for a connection from *...  
Got a connection, launched process ./3FDA7FA6-48BE-4567-94D2-F9AB0AE3D394/yourapp.app/yourapp (pid = 4979).  

Open a new tab in terminal on your mac

$ lldb
(lldb) platform select remote-ios
(lldb) process connect connect://[your_iphone_ip]:2008

Use the following commands to load all images:

(lldb) settings set target.process.stop-on-sharedlibrary-events 1
(lldb) c
(lldb) settings set target.process.stop-on-sharedlibrary-events 0

Dump your app's image:

(lldb) image dump sections yourapp

2. Android

2.1 gdb

1. 下载 NDK

Need prebuilt gdbserver, Download NDK.

2. 上传 gdbserver (arm)

NDK中包含多个 gdbserver 供不同平台, 对于 android device, 我们需要 arm.

先将gdbserver上传到 device 上, 建议放置到 /system/bin下, 这样可从机器中任何路径调用.

/system通常情况下, 是只读 (ro).

root@universal_5410:/ # mount  
rootfs / rootfs rw,noatime,nodiratime 0 0  
tmpfs /dev tmpfs rw,nosuid,noatime,nodiratime,mode=755 0 0  
devpts /dev/pts devpts rw,noatime,nodiratime,mode=600 0 0  
proc /proc proc rw,noatime,nodiratime 0 0  
sysfs /sys sysfs rw,noatime,nodiratime 0 0  
/sys/kernel/debug /sys/kernel/debug debugfs rw,noatime,nodiratime 0 0
none /acct cgroup rw,noatime,nodiratime,cpuacct 0 0  
none /sys/fs/cgroup tmpfs rw,noatime,nodiratime,mode=750,gid=1000 0 0  
tmpfs /mnt/asec tmpfs rw,noatime,nodiratime,mode=755,gid=1000 0 0  
tmpfs /mnt/obb tmpfs rw,noatime,nodiratime,mode=755,gid=1000 0 0  
none /dev/cpuctl cgroup rw,noatime,nodiratime,cpu 0 0  
/dev/block/platform/dw_mmc.0/by-name/SYSTEM /system ext4 rw,noatime,nodiratime,discard,journal_checksum,journal_async_commit,errors=continue,data=ordered 0 0
/dev/block/platform/dw_mmc.0/by-name/CACHE /cache ext4 rw,nosuid,nodev,noatime,nodiratime,discard,journal_checksum,journal_async_commit,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/platform/dw_mmc.0/by-name/USERDATA /data ext4 rw,nosuid,nodev,noatime,nodiratime,discard,journal_checksum,journal_async_commit,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/platform/dw_mmc.0/by-name/EFS /efs ext4 rw,nosuid,nodev,noatime,nodiratime,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,noatime,nodiratime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
tmpfs /mnt/ntfs tmpfs rw,noatime,nodiratime,mode=777,gid=1000 0 0  

需要重新挂载 (rw). 否则使用adb push的时候将提示 readonly.

➜  gdbserver adb push /Users/its/Project/tools/android/android-ndk-r13b/prebuilt/android-arm/gdbserver/gdbserver /system/bin

你有可能无法重新挂载/system, 假如机器是被厂商锁住的.

建议珍惜生命, 换一台机器, 不要纠缠. 或者上传到其他目录.

3. Attach your app

Open a new tab on Mac.

➜  ~ adb forward tcp:1234 tcp:1234
➜  ~ adb shell
root@universal_5410:/ # gdbserver :1234 --attach [pid_of_your_app]  
Attached; pid = 3671  
Listening on port 1234  
Remote debugging from host 127.0.0.1    // This line only appears once it was connected  

4. Debug

Open a new tab on your Mac.

Start gdb

➜  gdbserver /Users/its/Project/tools/android/android-ndk-r13b/prebuilt/darwin-x86_64/bin/gdb
GNU gdb (GDB) 7.11  
Copyright (C) 2016 Free Software Foundation, Inc.  
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>  
This is free software: you are free to change and redistribute it.  
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"  
and "show warranty" for details.  
This GDB was configured as "x86_64-apple-darwin14.5.0".  
Type "show configuration" for configuration details.  
For bug reporting instructions, please see:  
<http://www.gnu.org/software/gdb/bugs/>.  
Find the GDB manual and other documentation resources online at:  
<http://www.gnu.org/software/gdb/documentation/>.  
For help, type "help".  
Type "apropos word" to search for commands related to "word".  

target port

(gdb) target remote :1234
Remote debugging using :1234  
Reading /system/bin/app_process32_xposed from remote target...  
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.  
Reading /system/bin/app_process32_xposed from remote target...  
Reading symbols from target:/system/bin/app_process32_xposed...Reading /system/bin/.debug/app_process32_xposed from remote target...  
(no debugging symbols found)...done.
Reading /system/bin/linker from remote target...  
warning: Could not load shared library symbols for 114 libraries, e.g. libc.so.  
Use the "info sharedlibrary" command to see the complete listing.  
Do you need "set solib-search-path" or "set sysroot"?  
Reading symbols from target:/system/bin/linker...Reading /system/bin/.debug/linker from remote target...  
(no debugging symbols found)...done.
Reading /system/bin/linker from remote target...  
0xb6f9ae4c in ?? ()  
(gdb) x/10i $pc
=> 0xb6f9ae4c:    pop {r4, r5, r6, r7}
   0xb6f9ae50:    cmn r0, #4096   ; 0x1000
   0xb6f9ae54:    bxls    lr
   0xb6f9ae58:    rsb r0, r0, #0
   0xb6f9ae5c:    b   0xb6fc672c
   0xb6f9ae60:    andeq   r0, r0, r10, asr r1
   0xb6f9ae64:    mov r12, r7
   0xb6f9ae68:    mov r7, #1
   0xb6f9ae6c:    svc 0x00000000
   0xb6f9ae70:    mov r7, r12
(gdb) info registers
r0             0xfffffffc    4294967292  
r1             0xbeffeec8    3204443848  
r2             0x10    16  
r3             0x5a    90  
r4             0x0    0  
r5             0x8    8  
r6             0x0    0  
r7             0x15a    346  
r8             0x0    0  
r9             0x0    0  
r10            0x0    0  
r11            0x5a    90  
r12            0xbeffee58    3204443736  
sp             0xbeffee48    0xbeffee48  
lr             0xb6f60e23    -1225388509  
pc             0xb6f9ae4c    0xb6f9ae4c  
cpsr           0xf0010    983056  
(gdb)

Ref

iOS

Android