在上一篇文章中说到在app中使用了ptrace,sysctl等收到来反调试。到底有没有成功呢?我们使用LLDB+Debugserver来尝试能否动态调试加了反调试功能的app。
1、LLDB
LLDB是LLVM编译器附带的调试器。
在iOS开发中,经常会用到xcode内置的调试器进行断点调试,在老版本的xcode中使用的调试器是GDB,而4.0更新编译器后的新版本使用的就是LLDB。
而不管是GDB还是LLDB之所以能够调试程序都是调用ptrace来跟踪进程来实现的。
2、debugserver
在调试程序时,debugserver和lldb是协同工作的。debugserver依附在app上并监听APP的运行,并且它还可以控制app执行各种命令。lldb在外部通过和debugserver建立连接获取APP的运行状态,然后通知debugserver对app进行调试。
在xcode对真机进行调试的时候,xcode先将debugserver依附到app上,然后通过lldb对app进行调试。
如果能够连接上越狱手机上的其他app的debugserver,我们也可以在终端对任意app使用lldb进行调试。
debugserver在mac上的路径
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/15.5/DeveloperDiskImage.dmg/usr/bin/debugserver
debugserver在iphone上的路径
/Developer/usr/bin
3、使用debugserver+lldb调试app
解决debugserver权限
默认的debugserver只能调试xcode安装的app,如果要调试任意app,需要给debugserver添加调试相关权限。
从越狱手机的/Developer/usr/bin路径复制debugserver文件到mac中,在终端使用ldid修改签名。
如果提示命令不存在,可能你的mac还未安装ldid,可先自行搜索安装后再继续。
第一步,导出entitlements权限文件。
ldid -e debugserver > debugserver.entitlements
这时因为debugserver.entitlements中包含arm64和arm64e两个版本,该文件权限都是重复两次的,所以无法直接用xcode打开,使用文本编辑或sublime打开。文件内容如下
第二步,修改权限文件,修改为以下内容
<?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.backboardd.debugapplications</key>
<true/>
<key>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.frontboard.debugapplications</key>
<true/>
<key>com.apple.frontboard.launchapplications</key>
<true/>
<key>com.apple.springboard.debugapplications</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>platform-application</key>
<true/>
<key>run-unsigned-code</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
</dict>
</plist>
第三步,使用ldid对debugserver重新签名
ldid -Sdebugserver.entitlements debugserver
将重新签名后的debugserver放到手机目录/usr/bin/下
如果运行没有权限,执行以下命令给debugserver添加运行权限
chmod +x /usr/bin/debugserver
这样,我们就可以使用ssh连接越狱手机,在终端使用debugserver去依附到其他app了
4、使用SSH连接越狱手机
在越狱手机中使用Cydia安装OpenSSH后,我们就可以在电脑端使用ssh连接我们的手机了。
使用wifi连接手机
保证iphone的wifi和mac的wifi连接到同一路由器,并获取到iphone的ip地址,执行以下命令
ssh root@192.168.xx.xx
会收到如下认证提示
Are you sure you want to continue connecting (yes/no/[fingerprint])?
输入yes
然后输入默认密码alpine,出现以下界面则代表连接成功
xxxiPhone:~ root#
5、使debugserver依附到要调试的app进程上
在上一步通过ssh远程连接手机后,清除手机后台程序,只运行要调试的app并保持前台运行,通过ps -e命令查看所有进程
可以看到我们要调试的app一般是/var/containers/Bundle/Application路径的。
输入以下命令
debugserver ip地址:端口号 -a 进程id或进程名称
这里我们要连接我们加了ptrace防护的app
debugserver 127.0.0.1:10001 -a 6044
出现以下信息
debugserver-@(#)PROGRAM:LLDB PROJECT:lldb-900.3.106
for arm64.
Attaching to process 6044...
Segmentation fault: 11
说明我们的ptrace生效了,有效拦截了debugserver
第二次,我们注释掉ptrace反调试相关代码,再尝试debugserver依附
出现以下信息,则代表依附成功
debugserver-@(#)PROGRAM:LLDB PROJECT:lldb-900.3.106
for arm64.
Attaching to process 6150...
Listening to port 10001 for a connection from localhost...
6、启动lldb,连接手机端的debugserver
在mac新开一个终端窗口,输入lldb,启动lldb
输入以下命令使lldb和debugserver建立连接
process connect connect://192.168.11.169:10001
但是这里有个坑,我直接连接老是失败,可以通过usb的方式连接
使用USB连接
由于wifi连接调试可能会有卡顿等问题,可以使用USB的方式来连接
安装usbmuxd
brew install usbmuxd
使用usbmuxd中的iproxy工具,可以将USB连接的iphone的一个端口映射到mac的一个端口上
iproxy 2233 10001
会出现以下等待连接界面
Creating listening port 2233 for device port 10001
waiting for connection
这相当于将iphone的10001端口和电脑的2233端口建立了映射,那么ssh只需要和本地的2233端口通信即可
这次我们再次尝试连接
process connect connect://localhost:2233
Process 6409 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x0000000196502784 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
-> 0x196502784 <+8>: ret
libsystem_kernel.dylib`mach_msg_overwrite_trap:
0x196502788 <+0>: mov x16, #-0x20
0x19650278c <+4>: svc #0x80
0x196502790 <+8>: ret
Target 0: (testapp) stopped.
(lldb)
已经可以成功进行调试了。这是程序是卡住状态,我们执行lldb的c命令让程序继续运行
(lldb) c
Process 6409 resuming
程序恢复了运行,接下来就可以使用lldb来调试程序啦。
如果程序加入了sysctl监测调试,那么这里程序就会监测到app正在被调试而退出。
因为本文只想测试ptrace和sysctl是否能够一定程度实现反调试,所以接下来使用lldb调试程序的流程就不在这里说明了。
在这里贴上LLDB常用命令