利用 DebugServer 以及 LLDB 进行远程调试。
LDID
下载
LDID 是一款可以用于查看权限签名,以及重签名权限的工具。
下载完成后,将其放置在系统执行目录下:
1 | /usr/local/bin |
并修改权限:
1 | chmod 777 /usr/local/bin/ldid |
添加 task_for_pid 权限
将以下内容保存为 entitlement.xml 文件:
1 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
对 DebugServer(后面会介绍) 进行重签名:
1 | ldid -Sentitlement.xml debugserver |
注意,S后不需要空格。
不然会报错:
1 | ldid.cpp(383): _assert(false); errno=0 |
DebugServer
DeveloperDiskImage
首先,显示 XCode 的包内容,找到iOS设备系统对应的 DeveloperDiskImage.dmg,以 9.3 为例,路径如下:
1 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/9.3/DeveloperDiskImage.dmg |
DebugServer
双击 DeveloperDiskImage.dmg,找到 debugserver 可执行文件,路径为:
1 | /usr/bin/debugserver |
重签名
重签名过程参考前面的 LDID 章节。
远程执行
直接通过 SSH/CyberDuck 将 debugserver 可执行文件拷到设备的以下目录:
1 | /usr/bin |
可能出现权限不足的情况,直接 chmod 777 解决。
完成后,直接 SSH 执行:
1 | debugserver |
Hook 住特定的 App,例如微信,命令:
1 | debugserver *:12345 -a "Wechat" |
这里的12345,是可以任意设置的端口号,用于跟 LLDB 连接。
LLDB
连接
LLDB 是 XCode 内置的调试工具。
与 DebugServer 建立连接,命令:
1 | lldb |
常见的 LLDB 命令参考:LLDB COMMAND MAP。
查看偏移量
这里,以 QQ 音乐为例,先让其继续运行:
1 | c |
然后,查看所有 image 地址:
1 | image list -o -f |
可以看到,QQ 音乐在虚拟内存中的基址地址,和模块的起始地址分别为:
1 | 0x0000000000048000 |
这所以会偏移,是因为 ASLR 机制,计算公式为:
1 | 模块偏移后的基地址 = ASLR偏移量 + 模块偏移前基地址 |
这里,可以计算出模块的起始地址应该为:
1 | 0x0000000100000000 |
在 Hopper 中查看,确认其地址无误。
创建断点
基于此公式,我们可以通过查看其可执行文件中的地址,然后加上偏移量,来添加断点,进行调试,例如,跳转到语音识别页面的方法的基准地址为:
加上 ASLR 偏移量,结果为:
1 | 100b13518 + 48000 = 100b5b518 |
在偏移后的地址出创建断点:
触发断点后,确认其汇编代码完全一致。
断点调试
可以用 ni 或者 si 等命令进行单步调试:
查看某个寄存器的值:
1 | p/po 寄存器 |
也可以修改某个寄存器的值:
1 | register write 寄存器 值 |