Frida 之反检测与对抗:突破 App 的"雷达"
📌 前置知识:Frida 基础用法、了解 Android 安全机制🎯 目标:绕过 App 的 Frida 检测,实现稳定注入
一、为什么会被检测?
Frida 如此强大,App 安全团队自然不会坐视不管。检测 Frida 成了很多 App 的必修课。
┌─────────────────────────────────────────────────────────────────┐│ App 防御体系 │├─────────────────────────────────────────────────────────────────┤│ ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ││ │ 反调试 │ │ 反注入 │ │ 环境检测 │ ││ │ (ptrace) │ │ (Frida) │ │ (Root/模拟器)│ ││ └──────────────┘ └──────────────┘ └──────────────┘ ││ │ │ │ ││ └───────────────────┴───────────────────┘ ││ │ ││ ▼ ││ ┌──────────────┐ ││ │ 检测到就 │ ││ │ 闪退/终止 │ ││ └──────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘
二、检测方法全景图
安全团队检测 Frida 的手段五花八门,分为六大类:
| 类别 | 检测目标 | 难度 |
|---|---|---|
| 进程环境检测 | frida-server 端口、线程名、文件 | ⭐⭐ |
| 内存特征检测 | Frida 字符串、代码模式 | ⭐⭐⭐ |
| 行为性能检测 | Hook 延迟、D-Bus 通信 | ⭐⭐ |
| 端口交互检测 | 27047 端口探测 | ⭐ |
| Java 层检测 | 已加载的类/库 | ⭐⭐ |
| 综合高阶检测 | ptrace、信号处理 | ⭐⭐⭐⭐ |
三、检测与对抗详解
3.1 第一类:进程环境检测
App 会扫描:
-
/proc/self/maps— 查找frida、gadget字符串 -
/proc/net/tcp— 查找 27047 端口 -
线程名 — 查找
gmain、gdbus、frida-*
对抗方案:
// 1. 隐藏端口:启动 frida-server 时指定新端口adbshell/data/local/tmp/frida-server-l0.0.0.0:12345// 2. Hook 线程名检测Java.perform(function() {varpthread=Java.use("java.lang.Thread");// 监控线程创建});// 3. 使用 strongR-frida(推荐)// 自动随机化端口、线程名、库文件名
3.2 第二类:内存特征检测
App 会在内存中扫描特征字符串:
-
"frida:rpc" -
"LIBFRIDA" -
"frida-agent"
对抗方案:
// 内存抹除:加载后立即擦除特征字符串setTimeout(function() {// 扫描并覆盖内存中的 Frida 字符串// 使其无法被检测}, 100);
3.3 第三类:行为与性能检测
App 通过”副作用”检测:
-
计时检测 — Hook 导致函数执行变慢
-
D-Bus 通信检测 — Frida 使用 D-Bus 协议
-
断点检测 — int3 指令
对抗方案:
// 1. Hook 时间函数,抹平时间差Java.perform(function() {varSystem=Java.use("java.lang.System");System.currentTimeMillis.implementation=function() {returnthis.currentTimeMillis(); };});// 2. 使用 strongR-frida --daemonize 模式// 避免 D-Bus 通信
3.4 第四类:端口交互检测(最常见)
这是最经典的检测方式:
// App 尝试连接 127.0.0.1:27047varsocket=newSocket();socket.connect("127.0.0.1", 27047);// 如果返回 "REJECT",说明 Frida 在运行
对抗方案:
# 方案1:修改端口adb shell /data/local/tmp/frida-server -l0.0.0.0:8080# 方案2:使用 strongR-frida 的 anti-anti-fridaadb shell /data/local/tmp/fs --anti-anti-frida-l0.0.0.0:12345
3.5 第五类:Java 层检测
App 会检查:
-
已加载的类名(包含
frida、agent) -
Native 库列表(
Debug.getNativeLibrarys())
对抗方案:
Java.perform(function() {// Hook getNativeLibrarys,过滤掉 Frida 库varDebug=Java.use("android.os.Debug");Debug.getNativeLibrarys.implementation=function() {varlibs=this.getNativeLibrarys();// 过滤掉包含 frida 的库名returnlibs.filter(function(name) {return!name.toLowerCase().includes("frida"); }); };});
3.6 第六类:综合高阶检测
| 检测方法 | 说明 | 对抗 |
|---|---|---|
| ptrace 检测 | 防止被附加 | 使用 Embedded 模式 |
| 双进程保护 | 父子进程相互监控 | 同时注入两个进程 |
| 信号处理检测 | 检查信号处理器 | 注入后恢复原始处理器 |
四、最强方案:strongR-frida
strongR-frida-android 是修改版的 Frida,从根源上解决检测问题:
功能特性
| 功能 | 作用 |
|---|---|
randomize_port |
随机化端口,每次不同 |
randomize_name |
重命名线程和库文件 |
anti_anti_frida |
对端口探测返回空白 |
daemonize |
避免 D-Bus 通信 |
使用方法
# 1. 下载 strongR-frida# https://github.com/hzzheyang/strongR-frida-android/releases# 2. 推送到设备adb push frida-server /data/local/tmp/fsadb shell chmod777 /data/local/tmp/fs# 3. 启动(带参数)adb shell /data/local/tmp/fs -l0.0.0.0:12345 --anti-anti-frida--daemonize# 4. 连接frida -H127.0.0.1:12345 -f com.example.app --no-pause
五、绕过思路:定位并删除检测 so
许多大型 App 把检测逻辑放在 Native 层(.so 文件):
核心原理
App 安全检测 so 文件:┌─────────────────────────────────┐│ libsecurity.so │ ← 安全防护模块│ libprotect.so │ ← 检测到异常就 exit()│ libmsaoaidsec.so │ ← 各种检测逻辑└─────────────────────────────────┘ ↓ 删除这些 so 不影响业务功能┌─────────────────────────────────┐│ 只保留业务逻辑 so │└─────────────────────────────────┘
操作步骤
# 1. 解压 APKunzip app.apk -d app_extract/cd app_extract/lib/# 2. 查找可疑的 so 文件# 关键字:security, safe, protect, shield, detect, monitorls-la | grep-E"(security|protect|detect|shield)"# 3. 删除检测 sorm-f libsecurity.so libprotect.so# 4. 重新打包签名# (使用 jadx 分析确认后再删)
六、常见检测与对抗对照表
| App 检测方式 | 检测原理 | 对抗方案 |
|---|---|---|
| 端口 27047 检测 | 连接 localhost:27047 | 修改端口 / strongR-frida |
| maps 文件检测 | 扫描 frida/gadget 字符串 | 内存抹除 / 重命名库 |
| 线程名检测 | 检查 gmain/frida-* | strongR-frida randomize_name |
| 内存特征扫描 | 搜索 “frida:rpc” | 加载后擦除特征字符串 |
| 时间差检测 | Hook 引入延迟 | Hook 时间函数 |
| getNativeLibrarys | Java 层检查库名 | Hook 过滤返回值 |
| ptrace 检测 | 防止附加 | Embedded 模式 |
| 双进程保护 | 父子相互监控 | 同时注入父子进程 |
七、总结
反检测核心思路:
1️⃣ strongR-frida ──▶ 首选方案,根源解决2️⃣ 内存特征擦除 ──▶ 主动防御,抹除痕迹3️⃣ Hook API 伪装 ──▶ 欺骗上层检测4️⃣ 删除检测 so ──▶ 直接移除检测模块5️⃣ 组合拳 ──▶ 多层防护最稳妥
推荐流程:
第一次尝试:strongR-frida(90%成功率)失败后:strongR-frida + 自定义对抗脚本再失败:分析 APK,删除检测 so 文件
🔗 关联阅读:《Frida 环境搭建》《SSL Pinning 绕过》《抓包全流程》⚠️ 注意:仅供安全测试使用,请勿用于非法目的!
本文仅供学习与安全研究使用,请勿用于非法目的。
夜雨聆风