使用 Choicy 來管理 Frida Gadget
通常来说,我们在越狱后的 iOS 平台都会直接使用 Frida 官方提供的 frida-server 来使用 frida。但是在实际使用中 frida-server 会有一些缺陷。frida-gadget 会是一个更好的选择。使用 opa334 的 Choicy 插件可以很方便的管理 Frida Gadget。
Frida Server 的缺陷
在我日常使用中,发现Frida Server 有以下几个缺陷:
- 迷之稳定性。在我的 iPhone 11/iOS 14.1 设备上,通过 Taurine
越狱后,使用frida时几乎必现内核 panic,设备直接重启。通过unc0ver 或
checkra1n 越狱则没有这个问题。这使得我完全无法在 Taurine
越狱后的设备上使用 frida,不得不改为用 unc0ver,但 unc0ver
还是老旧了。frida 的仓库中有一些 issue
提及这个问题,但都没找到具体的原因:
- https://github.com/frida/frida/issues/2643 和我的情况相近
- https://github.com/frida/frida/issues/1231#issuecomment-605534130 作者似乎表示只支持 unc0ver 越狱
- 易被检测。有些 app 会在检测到安装官方 frida-server 后直接闪退。
与之相对应的,Frida Gadget 很稳定,至少没遇到过直接把内核搞崩的情况。Gadget 的隐蔽性也比 Server 更好。
Frida Gadget
注入 Frida Gadget 非常简单,只需要将 frida-gadget.dylib 和 配置文件
frida-gadget.config ,以及 Substrate 的配置文件 frida-gadget.plist 放入
Substrate 的模块目录
/Library/MobileSubstrate/DynamicLibraries
即可。修改 plist
中的 Filter 来手动指定需要注入的进程。可以通过指定 Bundles 为
com.apple.Security
来注入所有进程。
需要注意,最好不要直接向所有进程注入 frida-gadget.dylib,下面这个配置要配合后面的 Choicy 一起使用,否则可能会产生一些问题。
1 |
|
编辑 frida-gadget.config
来配置 gadget 的行为(可参考 frida-gadget
文档)。推荐配置如下: 1
2
3
4
5
6
7
8
9{
"interaction": {
"type": "listen",
"address": "127.0.0.1",
"port": 27052,
"on_port_conflict": "pick-next",
"on_load": "resume"
}
}
这样会在 com.app.Security
加载的时候,注入
frida-gadget.dylib。而所有 app 都会加载 com.app.Security
这个 bundle,也就是说所有 app 都会被注入 frida-gadget.dylib。跟进
frida-gadget 的配置文件,进程将会在 127.0.0.1:27052
开放
frida 服务。如果该端口冲突,则会选用下一个端口。注入 frida-gadget.dylib
后,会自动恢复进程的执行。
使用 Choicy
我们可以手动编辑 frida-gadget.plist
文件来配置进程过滤规则,不过这样每次都要手动编辑。使用 Choicy
的好处在于可以提供一个手机上的 gui 界面,手动选择那些进程需要注入
frida-gadget。
添加 opa334 的源 https://opa334.github.io/
,下载 Choicy
插件安装后,即可在设置中找到 Choicy 的设置界面。
首先可以配置全局插件配置,选择那些插件全局打开或关闭。
在进程配置一节中,可以针对
SpringBoard
、每个应用、每个守护进程或额外的可执行文件单独配置。
在我们的场景下,可以使用“白名单”和“黑名单”两种配置方法:
- 白名单模式:所有 app 都不会被注入
frida-gadget
,仅有我们手动开启的app才会被注入 - 黑名单模式:所有 app 都会被注入
frida-gadget
,仅有我们手动关闭的app才会被注入
实际应用中应该只有少数 app 需要使用 frida-gadget。白名单配置如下:
- 在
frida-gadget.plist
中确保Filter
的Bundles
为com.apple.Security
或其他所有 app 都加载的 bundle。 - 在 Choicy
的
Global Tweak Configuration
中,关闭 frida-gadget 的开关。 - 进入 Choicy 的 Applications 页面,选择进入你需要注入 firda-gadget
的应用,打开
Overwrite Global Tweak Configuration
,打开Custom Tweak Configuration
选项,在Allow
标签页中打开frida-gadget
的开关。
如果真的有什么需求需要用到黑名单模式,只需要打开
frida-gadget
的全局配置,然后在需要关闭的app中的
Deny
页面里打开 frida-gadget
的开关即可。
连接 Frida Gadget
当某个进程注入 frida-gadget.dylib
后,会从 27052
开始依次选择可用的端口创建 frida
服务。如果只给一个进程配白了,那么这个进程肯定在 27052
上创建(除非该端口已被别的什么服务占用)。可以在 iOS 中使用
lsof -t -i tcp:27052
获取占用该端口的进程 pid,再用 ps
确认进程名。合起来就是 ps -p $(lsof -t -i tcp:27052)
。
如果使用 usb 连接 iOS 设备的话,接下来在 host
端通过
iproxy 27052:27052
转发端口,然后使用
frida -H localhost:27052 gadget
即可连接到
frida-gadget。
如果想使用 wifi 连接 iOS 设备,则需要修改
frida-gadget.config
,将 interaction
中的
address
改为 0.0.0.0
。此时无需使用 iproxy
转发端口,直接用 frida -H <device_ip>:27052 gadget
即可连接到 frida-gadget。
如果有需求需要同时注入多个进程并连接 frida,需要手动确定每个进程的
frida-gadget
开放在哪个端口,然后分别(转发端口并)连接即可。
ps1: 也可以改到 27042 端口,这样 frida -H 连接的时候可以不用指定端口号。
ps2: 使用 frida-ps 看到的进程名为 Gadget
下面这个脚本可以获取所有注入了 frida-gadget
的进程、pid、以及对应的端口号:
1 | frida-port() { |
总结
本文只是抛砖引玉,实际使用中可以按照自己的个人习惯修改 plist,config 等。除了 Choicy 之外,也可用 libhooker configurator、Substrate substitute
使用 Choicy 管理 frida-gadget 时,在多 app 场景下需要手动确认每个 app 的 frida-gadget 开启在哪个端口上。另外无法自定义配置每个 app 所需要的配置文件。我的想法是单独写一个插件来管理 frida-gadget,为每个需要注入 frida-gadget 的 app 单独做一份配置。目前已经新建文件夹了,后面写的差不多了再放出来 XDDDD。