- debugserver 获取方式
第一步:导出Debugserer
$ ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
$ hdiutil mount /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/15.5/DeveloperDiskImage.dmg
正在检查"Whole_Disk"的校验和...
..................................................................................................................................................................................................................................................
Whole_Disk:已验证CRC32 $D034FA6C
已验证CRC32 $8E250F8D
/dev/disk4 /Volumes/DeveloperDiskImage
$ cp /Volumes/DeveloperDiskImage/usr/bin/debugserver .
$ hdiutil unmount /Volumes/DeveloperDiskImage
"/Volumes/DeveloperDiskImage" unmounted successfully.
$ file debugserver
debugserver: Mach-O universal binary with 2 architectures: [arm64:Mach-O 64-bit executable arm64] [arm64e:Mach-O 64-bit executable arm64e]
debugserver (for architecture arm64): Mach-O 64-bit executable arm64
debugserver (for architecture arm64e): Mach-O 64-bit executable arm64e
$ xcrun -sdk iphoneos lipo -thin arm64 debugserver -output debugserver_arm64
设置 entitlements
View
codesign -d -v --entitlements - --xml debugserver_arm64
Executable=/Users/sskaje/Work/hiksemi/debugserver_arm64
Identifier=com.apple.debugserver
Format=Mach-O thin (arm64)
CodeDirectory v=20400 size=5134 flags=0x2(adhoc) hashes=150+7 location=embedded
Signature=adhoc
Info.plist entries=5
TeamIdentifier=not set
Sealed Resources=none
Internal requirements count=0 size=12
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>seatbelt-profiles</key><array><string>debugserver</string></array><key>com.apple.private.cs.debugger</key><true/><key>com.apple.private.memorystatus</key><true/><key>com.apple.security.network.client</key><true/><key>com.apple.security.network.server</key><true/><key>com.apple.private.logging.diagnostic</key><true/><key>com.apple.backboardd.debugapplications</key><true/><key>com.apple.frontboard.debugapplications</key><true/><key>com.apple.backboardd.launchapplications</key><true/><key>com.apple.frontboard.launchapplications</key><true/><key>com.apple.springboard.debugapplications</key><true/></dict></plist>
ent.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.private.cs.debugger</key><true/>
<key>com.apple.private.memorystatus</key><true/>
<key>com.apple.security.network.client</key><true/>
<key>com.apple.security.network.server</key><true/>
<key>com.apple.private.logging.diagnostic</key><true/>
<key>com.apple.backboardd.debugapplications</key><true/>
<key>com.apple.frontboard.debugapplications</key><true/>
<key>com.apple.backboardd.launchapplications</key><true/>
<key>com.apple.frontboard.launchapplications</key><true/>
<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>
debugserver has entitlements
<key>seatbelt-profiles</key>
<array>
<string>debugserver</string>
</array>
- Rootness Roothide 部署
首先设置debugserver 瘦身
lipo -thin arm64 ~/Desktop/debugserver -output ~/Desktop/debugserver
,
设置权限:
<?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>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.backboardd.debugapplications</key>
<true/>
<key>com.apple.frontboard.launchapplications</key>
<true/>
<key>com.apple.frontboard.debugapplications</key>
<true/>
<key>com.apple.private.logging.diagnostic</key>
<true/>
<key>com.apple.private.memorystatus</key>
<true/>
<key>com.apple.private.cs.debugger</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
</dict>
</plist>
codesign -f -s - --entitlements debugserver.entitlements debugserver
scp mobile@192:/var/mobile/
进入iphone: sudo -i 切换到root 用户
设置权限: chmod +x debugserver
复制到 usr/bin 目录
复制到 /var/jb/usr/bin (rootless, 或者 roothide 需要复制到这里 )
- 调试调用
./debugserver *:1234 -a 6019
A attach 方式, 此命令执行完成后,app会进入等到挂载状态,app会被卡住点击无反应。正常现象!
如果此命令报错,如出现 Segmentation fault: 11 等情况,说明 App 做了反动态调试保护。遇到此种情况,需先确定 App 采用了哪种保护方案,然后进一步找到对应措施,干掉它的反动态调试保护。
第二步:监听进程,进入挂载状态
重新打开一个 Mac 终端执行 lldb 进入 lldb 调试状态。然后输入
process connect connect://iPhoneIP:port
iPhoneIP 替换为 iPhone 的 IP 地址;port 改为刚才指定的端口,即 1234。
待命令执行完成后,App 即进入挂载状态。
第三步:获取 App 的 ASLR 偏移量
ASLR偏移量其实就是虚拟内存的地址相对于模块基地址的偏移量。有两个概念需要熟悉一下:
- 模块在内存中的起始地址 ---- 模块基地址
- ASLR偏移 ---- 虚拟内存起始地址与模块基地址的偏移量
在 lldb 调试器模式下,执行 imge list -o -f

模块偏移后的基地址 = ASLR 偏移量 + 模块偏移前基地址(方法的 IMP 地址)
上面这个公式是尤为重要的,因为 Class-dump 中显示的都是"模块偏移前基地址",而 lldb 要操作的都是"模块偏移后的基地址"。所以从 Class-dump 到 lldb 要做一个地址偏移量的转换。
至此,已得到了 App 的 ASLR 偏移量和方法的 IMP 地址。
第四步:打断点,调试
在 lldb 模式下执行,br s -a 'ASLR 偏移量+ IMP',然后执行 c,使 App 跑起来,触发一个方法调用,就会进入断点模式。输入 po $arg1 打印第一个参数。
然后,配合着抓包工具 Charles(比如分析网络请求加密逻辑) 和 Class-dump(比如修改某个类的方法返回值)等工具,你就可以随意动态调试 App 了,就像在 XCode 里调试一样!
br 命令说明
br dis 1 -- 禁用(disable)编号为1的断点
br en 1 -- 启用(enable)编号为1的断点
br dis -- 禁用所有断点
br en -- 启用所有断点
br del 1 -- 删除(delete)编号为1的断点
br del -- 删除所有断点
br list -- 列出所有断点