前言
说起动态调试,大家普遍第一反应是通过Xcode 安装应用到真机,然后通过添加断点,添加打印等方式来动态的调试程序所遇到的bug或者异常,今天和大家分享一下这个过程的底层原理,希望对动态调试有更深入的了解。
动态调试原理图首先我们回顾一下真机调试的过程,
1.打开Xcode
2.通过数据线连接真机和mac
3.在需要的地方添加断点
4.点击Xcode中的run将程序运行到真机上
通过以上的操作我们就与手机建立了一个动态调试的环境,如上图,当我们下发lldb 指令传输给手机的debugserver, debugserver通过监听App运行进程下发指令给App,这时候App 执行了某种操作将结果返回给debugserver,debugserver再将结果告诉给lldb,lldb则会输出结果。
示例例如我们在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查看
/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 指令去调试我们想要调试的程序。
网友评论