iOS 动态真机调试原理

前言

说起动态调试,大家普遍第一反应是通过Xcode 安装应用到真机,然后通过添加断点,添加打印等方式来动态的调试程序所遇到的bug或者异常,今天和大家分享一下这个过程的底层原理,希望对动态调试有更深入的了解。

iOS 动态真机调试原理_第1张图片
动态调试原理图

首先我们回顾一下真机调试的过程,

1.打开Xcode

2.通过数据线连接真机和mac

3.在需要的地方添加断点

4.点击Xcode中的run将程序运行到真机上

通过以上的操作我们就与手机建立了一个动态调试的环境,如上图,当我们下发lldb 指令传输给手机的debugserver, debugserver通过监听App运行进程下发指令给App,这时候App 执行了某种操作将结果返回给debugserver,debugserver再将结果告诉给lldb,lldb则会输出结果。

iOS 动态真机调试原理_第2张图片
示例

例如我们在viewController 中添加 touches 方法,当点击屏幕,就会进入到Xcode中lldb 环境,我们在控制台输入指令 po self会得到以下结果
lldb

这样一个过程则是我们上述我们描述的动态的原理中所执行的操作。

上述过程大家可能看图就能很好的理解,可能唯一疑惑的是这个debugserver 是什么东西?

首先我们在以下的路径中找打它:

Xcode/Contents/Deverloper/Platforms/iPhoneOS.platform/DeviceSupport/9.1(任何系统版本都可以)/DeveloperDiskImage.dmg

双击 DeveloperDiskImage.dmg 在 /usr/bin/debugserver
我们可以看到它,它到是什么,我们可以查看一下,利用file 指令

file debugserver

输出结果

debugserver: Mach-O universal binary with 3 architectures: [arm_v7:Mach-O executable arm_v7] [arm64]
debugserver (for architecture armv7):   Mach-O executable arm_v7
debugserver (for architecture armv7s):  Mach-O executable arm_v7s
debugserver (for architecture arm64):   Mach-O 64-bit executable arm64

这下我们应该可以明白了,它是一个Mach-O格式的通用二进制的可执行文件,包含三种指令集架构.

当我们执行真机调试时候,这个文件会被安装到我们手机中,具体目录我们可以通过越狱手机(个人系统9.1)文件系统管理工具iFunBox查看


iOS 动态真机调试原理_第3张图片
/Developer/usr/bin/debugserver

这也就能解释我们第一次真机调试运行缓慢,当然还存在其他原因,这里就不展开分析了。

那么至此全文原理性东西已经解释完毕了,接下来我们可以通过逆向的一些知识,我们手动的实现这个过程,我们说主要的过程

步骤一

首先需要架设一个端口,负责lldb 和 debugserver 之间的指令传输,我们可以使用一个开源的python端口转发脚本实现这一过程,
https://cgit.sukimashita.com/usbmuxd.git/snapshot/usbmuxd-1.0.8.tar.gz 可以通过这个地址下载解压
然后执行

cd ~/Documents/usbmuxd-1.0.8/python-client
python tcprelay.py -t 10011:10011

这样我们就相当于通过访问本地10011端口就可以访问远程的10011端口。

步骤二

我们将debugserver文件重签权限后放入到 /usr/bin 目录下,然后给它赋予可执行权限 chmod +x /usr/bin/debugserver,执行

debugserver *:10011 -a process_name(这里是进程名)

步骤三

在终端在 输入lldb,进入lldb环境

 process connect://localhost:10011

这样我们一个类似Xcode的lldb调试环境就搭建好了,我们可以通过lldb 指令去调试我们想要调试的程序。

你可能感兴趣的:(iOS 动态真机调试原理)