iOS 越狱环境debugserver
一、概述
在越狱环境中我们可以很方便的使用cycript
和reveal
来调试应用,但是有个问题是他们都不影响进程,没有办法下断点调试。reveal
主要的是界面调试,有时候我们需要lldb
进行逻辑调试。
二、xcode附加进程
在xcode
的debug
中有个Attach to Process
附加进程:
变成Running
后就附加上了,可以直接断点调试了:
(lldb) pvc
<MainTabBarViewController 0x1168fd800>, state: appeared, view: <UILayoutContainerView 0x115c91f40>
| <MMUINavigationController 0x11692f000>, state: appeared, view: <UILayoutContainerView 0x115c98070>
| | <NewMainFrameViewController 0x116920c00>, state: appeared, view: <MMUIHookView 0x115f81700>
| <MMUINavigationController 0x116c13000>, state: disappeared, view: <UILayoutContainerView 0x115f86a70> not in the window
| | <ContactsViewController 0x11648c600>, state: disappeared, view: (view not loaded)
| <MMUINavigationController 0x11621b200>, state: disappeared, view: <UILayoutContainerView 0x11c27dbd0> not in the window
| | <FindFriendEntryViewController 0x116490800>, state: disappeared, view: (view not loaded)
| <MMUINavigationController 0x116252600>, state: disappeared, view: <UILayoutContainerView 0x11c2d4000> not in the window
| | <MoreViewController 0x1164d0a00>, state: disappeared, view: (view not loaded)
(lldb)
并且可以view debug
:
- 对于越狱设备来说可以附加所有
App
的进程,对了非越狱设备而言只能附加自己的App
。
三、debugserver
Xcode
中的lldb
可以调试手机中的应用,是因为手机中的debugserver
开启的相关服务。所以在越狱环境中我们只需要开启debugserver
服务就可以利用LLDB
远程调试三方应用了。
-
Xcode
中有lldb
给手机中的debugserver
发送指令。 - 手机中的
debugserver
会附加App
,读App
中的内容做一系列操作。 -
debugserver
读取到的结果给到lldb
显示。
3.1 Mac中的debugserver
mac
在/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
目录中能够看到不同iOS
系统版本对应的的镜像文件:
打开dmg
文件,进入usr/bin
目录可以看到debugserver
。这就是xcode
安装到手机中的文件:
3.2 验证
当xcode
第一次连接手机的时候就会将debugserver
安装到手机。
具体安装在手机的/Developer/usr/bin/
目录中:
zaizai:~ root# cd /Developer/usr/bin/
zaizai:/Developer/usr/bin root# ls
DTDeviceArbitration* ScreenShotr* axauditd* debugserver*
zaizai:/Developer/usr/bin root#
将手机中的debugserver
拷贝出来与mac
上的进行md5
验证
➜ md5 debugserver
MD5 (debugserver) = 8ce8fc76bebaa1a3aca530cdbce531a6
➜ scp -P 12345 root@localhost:/Developer/usr/bin/debugserver ./idebugserver
debugserver 100% 9779KB 35.6MB/s 00:00
➜ md5 idebugserver
MD5 (idebugserver) = 8ce8fc76bebaa1a3aca530cdbce531a6
md5
一致验证确认。
⚠️如果手机端是重签过的
debugserver
肯定就不一样了。当然重签也不能放在/Developer/usr/bin/
目录,这个目录的肯定和电脑端对应版本的md5
是一致的。
四、debugserver重签名
4.1 debugserver为什么需要重签
由于debugserver
权限问题debugserver
默认只能附加Xcode
安装的程序。需要对其进行重签名来附加其它程序。当出现Failed to get connection from a remote gdb process
的时候一般都是权限的问题。
对debugserver
重签使用的是ldid
工具 (需要安装),ldid
具体功能可以直接在电脑终端输入ldid
查看:
➜ ~ ldid
usage: ldid -S[entitlements.xml] <binary>
ldid -e MobileSafari
ldid -S cat
ldid -Stfp.xml gdb
-
-e
:查看权限文件,后面可以跟>
导出。 -
-S文件
:重新签名(⚠️-S
后面没有空格)。
4.2 导出权限文件
拷贝Xcode
中和手机版本对应的debugserver
导出权限文件(我这里是iOS14
):
//ldid -e debugserver 可以直接在终端查看权限
ldid -e debugserver > debugserver.entitlements
在
iOS 12
之后debugserver
包含两个架构arm64
和arm64e
:lipo -info debugserver Architectures in the fat file: debugserver are: arm64 arm64e
我们可以拆分架构生成重签对应架构的
debugserver
(当然不拆也没有问题,不拆plist
中两份配置都要改):lipo -thin arm64 debugserver -output debugserver_arm64
然后将自己需要的架构重命名为
debugserver
进行权限文件导出和重签。
4.3 修改导出的权限文件
4.3.1 增加权限
<key>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
4.3.2 删除权限
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>seatbelt-profiles</key>
<array>
<string>debugserver</string>
</array>
4.3.3 完整权限内容
完整内容与自己的统版本有关,这里是iOS14.0
,⚠️是arm64
和arm64e
两个架构的:
<?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>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
</dict>
</plist>
<?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>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
</dict>
</plist>
4.4 重签名debugserver
修改好后好后进行重签名(-S
后面没有空格):
ldid -S权限文件 debugserver文件
ldid -Sdebugserver.entitlements debugserver
4.5 签名和debugserver配置
如果你想用重签名后的debugserver
替换/Developer/usr/bin
目录下的debugserver
那么你想多了。这个目录我们没有修改权限(只读目录)。
zaizai:/Developer/usr/bin root# rm debugserver
rm: cannot remove 'debugserver': Read-only file system
那么我们直接将重新签名后的debugserver
放入/usr/bin/
目录中:
scp -P 12345 debugserver root@localhost:/usr/bin/
至此手机端的debugserver
就已经配置好了。
⚠️
/usr/bin/
目录下有个好处是这个默认配置了环境变量,在任何目录下我们都能使用debugserver
。
五、手动启动debugserver
5.1 开启usb映射
在开启手机端debugserver
前,我们先在端口映射处加一个映射:
//iproxy
iproxy 12345:22 12346:12346
//python /Users/zaizai/HPShell/python-client/tcprelay.py -t 22:12345 12346:12346
同时映射两个端口,iproxy
和python脚本
都可以。
5.2 手机端开启debugserver服务
5.2.1 debugserver功能
进入/usr/bin/
目录输入./debugserver
就可以看都有哪些功能了:
zaizai:/usr/bin root# ./debugserver
debugserver-@(#)PROGRAM:LLDB PROJECT:lldb-1200.2.12
for arm64.
Usage:
debugserver host:port [program-name program-arg1 program-arg2 ...]
debugserver /path/file [program-name program-arg1 program-arg2 ...]
debugserver host:port --attach=<pid>
debugserver /path/file --attach=<pid>
debugserver host:port --attach=<process_name>
debugserver /path/file --attach=<process_name>
可以看到我们可以通过进程id和名字开启:
debugserver 主机地址:端口号 –a 应用进程
- 主机地址:由于主机地址是当前手机,可以使用
localhost
代替。 - 端口号:启动
server
服务,开放端口,让远程的LLDB
通过sever
调试进程。
5.2.2 debugserver开启
手机端先开启debug server
:
zaizai:/usr/bin root# ./debugserver localhost:12346 -a WeChat
debugserver-@(#)PROGRAM:LLDB PROJECT:lldb-1200.2.12
for arm64.
Attaching to process WeChat...
Listening to port 12346 for a connection from localhost...
进入监听状态。
5.3 mac进入lldb环境
在mac
终端直接输入lldb
回车进入lldb
环境,然后连接:
process connect connect://IP:端口
➜ ~ lldb
➜ ~ lldb
(lldb) process connect connect://localhost:12346
Process 24284 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00000001b494e8c4 libsystem_kernel.dylib` mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
-> 0x1b494e8c4 <+8>: ret
libsystem_kernel.dylib'mach_msg_overwrite_trap: 0x1b494e8c8 <+0>: mov x16, #-0x20
0x1b494e8cc <+4>: svc #0x80
0x1b494e8d0 <+8>: ret
libsystem_kernel.dylib'semaphore_signal_trap: 0x1b494e8d4 <+0>: mov x16, #-0x21
0x1b494e8d8 <+4>: svc #0x80
0x1b494e8dc <+8>: ret
libsystem_kernel.dylib'semaphore_signal_all_trap: 0x1b494e8e0 <+0>: mov x16, #-0x22
Target 0: (WeChat) stopped.
(lldb)
连接需要等几秒钟。出现Target stopped
就连接成功了,可以直接输入命令调试了。
5.4 终端lldb调试
image.pnglldb
命令调试:
(lldb) process interrupt
Process 24268 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00000001b494e8c4 libsystem_kernel.dylib` mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
-> 0x1b494e8c4 <+8>: ret
libsystem_kernel.dylib'mach_msg_overwrite_trap: 0x1b494e8c8 <+0>: mov x16, #-0x20
0x1b494e8cc <+4>: svc #0x80
0x1b494e8d0 <+8>: ret
libsystem_kernel.dylib'semaphore_signal_trap: 0x1b494e8d4 <+0>: mov x16, #-0x21
0x1b494e8d8 <+4>: svc #0x80
0x1b494e8dc <+8>: ret
libsystem_kernel.dylib'semaphore_signal_all_trap: 0x1b494e8e0 <+0>: mov x16, #-0x22
Target 0: (WeChat) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x00000001b494e8c4 libsystem_kernel.dylib` mach_msg_trap + 8
frame #1: 0x00000001b494dcc8 libsystem_kernel.dylib` mach_msg + 72
frame #2: 0x0000000189f7874c CoreFoundation` __CFRunLoopServiceMachPort + 376
frame #3: 0x0000000189f72bd0 CoreFoundation` __CFRunLoopRun + 1176
frame #4: 0x0000000189f72200 CoreFoundation` CFRunLoopRunSpecific + 572
frame #5: 0x00000001a006d598 GraphicsServices` GSEventRunModal + 160
frame #6: 0x000000018c838004 UIKitCore` -[UIApplication _run] + 1052
frame #7: 0x000000018c83d5d8 UIKitCore` UIApplicationMain + 164
frame #8: 0x0000000105270328 WeChat` ___lldb_unnamed_symbol30639$$WeChat + 860
frame #9: 0x0000000189c51598 libdyld.dylib` start + 4
(lldb) sbt
frame #0 : 0x1b494e8c4 libsystem_kernel.dylib`mach_msg_trap + 8
frame #1 : 0x1b494dcc8 libsystem_kernel.dylib`mach_msg + 72
frame #2 : 0x189f7874c CoreFoundation`__CFRunLoopServiceMachPort + 376
frame #3 : 0x189f72bd0 CoreFoundation`__CFRunLoopRun + 1176
frame #4 : 0x189f72200 CoreFoundation`CFRunLoopRunSpecific + 572
frame #5 : 0x1a006d598 GraphicsServices`GSEventRunModal + 160
frame #6 : 0x18c838004 UIKitCore`-[UIApplication _run] + 1052
frame #7 : 0x18c83d5d8 UIKitCore`UIApplicationMain + 164
frame #8 : 0x105270328 WeChat`-[ + 860
frame #9 : 0x189c51598 libdyld.dylib`start + 4
(lldb) c
Process 24268 resuming
(lldb)
-
process interrupt
:可以中断进程。 - 退出
lldb
的时候进程会被杀掉。
总结
- 使用附加
- 1.终端附加:
- 手机端:
debugserver 主机名称:端口 -a App名称
-
Mac
端:- 启动
lldb
process connect connect://主机名称:端口
- 启动
- 手机端:
- 2.
Xcode
附加:Debug->Attach to Process
(需要选中设备)
- 1.终端附加:
- 权限:
- 导出权限文件:
ldid -e debugserver > debugserver.entitlements
- 设置权限:
- 增加权限:
platform-application
get-task-allow
task_for_pid-allow
run-unsigned-code
com.apple.system-task-ports
- 删除权限:
com.apple.security.network.server
com.apple.security.network.client
seatbelt-profiles
- 设置权限:
ldid -Sdebugserver.entitlements debugserver
- 增加权限:
- 导出权限文件: