第2章 Android 部署指南

2.1 frida-server 部署(需要 Root)

前置条件

  • Root 权限的 Android 设备或模拟器
  • ADB 已安装且设备已连接
  • 匹配版本的 frida-server 二进制文件
  • Android 14/15 设备建议使用 17.6.0+ 版本(轻量级 Zygote hooking,无需 ptrace 注入)

部署步骤

# 1. 确认设备架构
adb shell getprop ro.product.cpu.abilist
# 输出示例: arm64-v8a,armeabi-v7a,armeabi
 
# 2. 推送到设备
adb push frida-server-17.9.11-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"
 
# 3. 启动 server(必须 root)
# 方式一:adb root (userdebug 版本)
adb root
adb shell "/data/local/tmp/frida-server &"
 
# 方式二:su (正式版本)
adb shell "su -c '/data/local/tmp/frida-server &'"
 
# 4. 验证
frida-ps -U
# 应列出设备上所有运行进程

17.9.x 新增:自定义控制端点

# 使用 localabstract socket(更隐蔽,避免端口扫描检测)
adb shell "su -c '/data/local/tmp/frida-server -l localabstract:my-frida &'"
 
# 客户端通过 adb 连接(无需 forward)
frida -D <device-id> -f com.target.app

使用本地脚本一键部署

cd /home/zbc/pangu/GeneralAndroid/main/hideapi/frida
./push_frida_server_to_device.sh

脚本功能:

  • 自动检测设备连接状态
  • 推送 frida-server 到 /data/local/tmp/
  • 检查是否已有实例运行(避免重复启动)
  • 以 root 后台启动并验证进程

注意事项

  • Server 默认监听 localhost:27042
  • 重启手机后需要重新 push 和启动
  • 可重命名二进制避免检测: mv frida-server hluda-server
  • 多设备时设置 export ANDROID_SERIAL=<序列号>
  • 17.9.0+: 64 位设备自动跳过 32 位 helper 加载,启动速度更快
  • 17.6.0+: 不再注入 Zygote/system_server,Android 14/15 稳定性大幅提升

2.2 SELinux 处理

SELinux 可能阻止 Frida 的内存访问和进程操作:

# 检查 SELinux 状态
adb shell getenforce
 
# 临时设置宽容模式(需要 root)
adb shell "su -c setenforce 0"

常见 SELinux 错误

  • PTRACE_ATTACH failed: SELinux 拒绝 ptrace 访问
  • Failed to spawn: SELinux 阻止 instrumented 上下文中的进程创建
  • open(/proc/$pid/mem) failed: SELinux 拒绝 /proc/pid/mem 读写(17.6.0+ 的新注入方式需要此权限)

17.6.0+ SELinux 变更说明

自 17.6.0 起,Frida 使用 /proc/$pid/mem 进行内存修补而非 ptrace 注入。SELinux 策略需相应调整:

持久化方案(Magisk sepolicy.rule):

allow frida_server app_data_file file { read write open }
allow frida_server zygote process { ptrace }
allow frida_server zygote file { read write open }
allow frida_server app_process file { read write open }

注意: 17.6.0 对 SELinux 用户空间库进行了重构,基于上游新版代码,支持现代二进制策略格式(Android 14/15 使用),同时保持 Android M (6.0) 向下兼容。


2.3 Magisk/KernelSU 集成

作为 Magisk 模块自启动

创建模块目录结构:

/data/adb/modules/frida-server/
├── module.prop
├── service.sh          # 开机自启动
├── post-fs-data.sh     # 早期初始化(可选)
└── sepolicy.rule       # SELinux 权限

module.prop:

id=frida-server
name=Frida Server
version=17.9.11
versionCode=170911
author=frida.re
description=Auto-start frida-server on boot

service.sh:

#!/system/bin/sh
while [ "$(getprop sys.boot_completed)" != "1" ]; do
    sleep 1
done
/data/local/tmp/frida-server -D &

KernelSU 模块(Android 14/15 推荐)

KernelSU 模块结构与 Magisk 类似,放置于 /data/adb/modules/。KernelSU 对 SELinux 策略注入更友好,配合 17.6.0+ 的非侵入式 Zygote hooking,在 Android 14/15 上表现更稳定。

非默认端口运行(隐蔽)

# 使用非标准端口启动
adb shell "su -c '/data/local/tmp/frida-server -l 0.0.0.0:1337 &'"
 
# 客户端连接
frida -H 127.0.0.1:1337 -f com.target.app
# 需要先 adb forward:
adb forward tcp:1337 tcp:1337

使用 localabstract socket(17.9.0+ 推荐隐蔽方式)

# 使用 Unix domain socket,不暴露 TCP 端口
adb shell "su -c '/data/local/tmp/frida-server -l localabstract:frida-hidden &'"
 
# 客户端通过 USB 直接连接(frida 自动通过 adb 路由)
frida -U -f com.target.app

2.4 Frida Gadget(非 Root 方案)

Frida Gadget 是一个共享库 (.so),嵌入 APK 后无需 root 或 frida-server 即可使用 Frida。

APK 注入步骤

# 1. 反编译 APK
apktool d target.apk -o target_extracted
 
# 2. 下载 Gadget
wget https://github.com/frida/frida/releases/download/17.9.11/frida-gadget-17.9.11-android-arm64.so.xz
xz -d frida-gadget-17.9.11-android-arm64.so.xz
 
# 3. 放入 APK 的 lib 目录(必须 lib 前缀 + .so 后缀)
cp frida-gadget-17.9.11-android-arm64.so target_extracted/lib/arm64-v8a/libfrida-gadget.so
 
# 4. 在入口 Activity 的 smali 中注入 loadLibrary
# 在 <clinit> 或 onCreate 中添加:

Smali 注入代码:

const-string v0, "frida-gadget"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
# 5. 确保 AndroidManifest.xml 包含 INTERNET 权限
# <uses-permission android:name="android.permission.INTERNET" />
 
# 6. 重新打包
apktool b target_extracted -o target_patched.apk
 
# 7. 签名
keytool -genkey -v -keystore debug.keystore -alias debug -keyalg RSA \
    -keysize 2048 -validity 10000 -storepass password -keypass password \
    -dname "CN=Debug"
apksigner sign --ks debug.keystore --ks-pass pass:password target_patched.apk
 
# 8. 安装
adb install target_patched.apk

Gadget 配置文件

配置文件命名必须匹配: libfrida-gadget.config.so(与 .so 放在同一目录)

Listen 模式(默认)— 等待 Frida 客户端连接:

{
    "interaction": {
        "type": "listen",
        "address": "127.0.0.1",
        "port": 27042,
        "on_port_conflict": "pick-next",
        "on_load": "wait"
    }
}

Script 模式 — 无需外部客户端自动运行脚本:

{
    "interaction": {
        "type": "script",
        "path": "/data/local/tmp/hook.js",
        "on_change": "reload"
    }
}

连接 Gadget

# App 启动后暂停(on_load: "wait"),logcat 中会打印:
# Frida: Listening on TCP port 27042
 
# 使用 "Gadget" 作为进程名连接:
frida -U Gadget -l myscript.js
 
# 或使用 objection 自动化注入:
objection patchapk --source target.apk --gadget-version 17.9.11

2.5 frida-strace 系统调用追踪(17.8.0+)

17.8.0 新增 frida-strace 工具,可追踪目标进程的系统调用,用于识别检测机制和 RASP 检查:

# 追踪目标应用的系统调用
frida-strace -U -f com.target.app
 
# 过滤特定系统调用
frida-strace -U -i "open*" -f com.target.app
 
# 追踪已运行进程
frida-strace -U -p <pid>

该功能在 Android 上使用 eBPF 后端实现,可以帮助分析:

  • 应用的文件访问模式
  • Root/Frida 检测机制(检查 /proc/self/maps/data/local/tmp 等)
  • 网络调用和 IPC 通信

2.6 Android 14/15 部署要点

17.6.0+ 针对 Android 14/15 进行了重大架构调整:

轻量级 Zygote Hooking(17.6.0+)

  • 不再注入代码到 Zygote 和 system_server
  • 使用 920 字节的 arm64 “zymbiote” 载荷通过 /proc/$pid/mem 修补内存
  • 拦截 android.os.Process.setArgV0Native() 获取 spawn 信息
  • frida-core 不再依赖 frida-java-bridge

对 Android 14/15 的影响

  • 大幅减少系统不稳定(不再有 Zygote 崩溃重启)
  • 兼容 Google Play 完整性检查
  • 不会在子进程留下注入痕迹
  • 配合 KernelSU 效果最佳

推荐配置

# Android 14/15 推荐命令
adb push frida-server-17.9.11-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "su -c 'setenforce 0 && /data/local/tmp/frida-server -D &'"

2.7 使用 deploy_start_frida.py

项目中还包含 Python 版本的部署脚本:

cd /home/zbc/pangu/GeneralAndroid/main/hideapi/frida
python3 deploy_start_frida.py

该脚本提供更灵活的部署选项,支持选择 server 版本等。