百趣云 百趣云的博客

反 Frida 手段汇总:检测点清单与逐一绕过

检测方的完整武器库

把商业 App/安全 SDK 的反 Frida 手段按层汇总,这是一份"对手视角"的清单。逆向时对照排查,比盲目试错高效得多。

应用层检测(Java/Kotlin)

1. 端口扫描

// 连接本机 27042 端口,通了就说明 frida-server 在跑
Socket socket = new Socket("127.0.0.1", 27042);

绕过:换端口(-l 127.0.0.1:8888)。

2. 进程枚举

// 读 /proc 下所有 cmdline 找 frida-server
// 或 Runtime.exec("ps") 解析输出

绕过:frida-server 改名。

3. maps 扫描

// 读 /proc/self/maps 找 frida-agent / frida-gadget 字样

绕过:hook 文件读取过滤,或自定义编译改特征字符串。

4. 已安装包检测

// 查 com.saurik.substrate、frida 相关包
pm.getInstalledPackages()

绕过:Xposed hook 包查询接口。

native 层检测(SO)

5. 线程名扫描

// 遍历 /proc/self/task/*/comm
// 找 "gum-js-loop", "pool-frida", "gmain" 等

绕过:自定义编译 frida 改线程名,或 hook readdir/read 伪造。

6. 内存特征扫描

// 扫描自身地址空间找 frida agent 的特征字节
// (agent 的字符串常量、代码 pattern)

绕过:自定义 gadget 编译,特征字符串全部自定义。

7. inline hook 检测

// 校验关键函数的开头字节是否被改成跳转指令
// (frida 的 Interceptor 就是 inline hook)
check_prologue(native_func);

绕过:这是最难缠的检测。方案:换 hook 点(hook 检测函数没校验的函数)、用 Stalker(不修改函数开头)、或先 hook 校验函数让它永远报"未被 hook"。

8. 调试器/跟踪检测

// TracerPid、ptrace 自附加、断点指令扫描

绕过:见"SO 反调试对抗"篇,TracerPid 伪造 + Interceptor.replace。

行为/时序检测

9. 执行时序异常

frida 的 JS 引擎执行会拖慢被 hook 函数——检测代码测量关键函数的耗时,异常变慢即报警。

绕过:hook 逻辑尽量轻(别在 onEnter 里做重活),日志异步发送;或用 CModule(编译型 hook)替代 JS。

10. 调用栈校验

检测代码检查调用栈里有没有 frida 的栈帧。

绕过:少见但存在,用 Stalker 或 CModule 规避 JS 栈帧。

绕过的优先级策略

面对一个未知 App,按这个顺序处理:

1. 改名 + 换端口(解决 1/2/3 的大部分)
   ↓ 还闪退?
2. hook 文件读取(maps/task/comm 过滤)(解决 3/5)
   ↓ 还闪退?
3. 逆向找检测函数,Interceptor.replace 反制(解决 7/8 及未知检测)
   ↓ 还闪退?
4. 换注入方式:gadget 嵌入 / CModule / Stalker(解决 6/9/10)

精髓:三个认知

  1. 检测代码也是代码,也能被 hook。反 Frida 的本质是"检测函数 vs hook 检测函数"的套娃——谁在最底层谁赢。Frida 的 native hook 足够底层,理论上应用层和 SO 层的检测都能反制
  2. 静默检测比闪退危险。闪退型检测告诉你"被发现了",静默型检测(标记上报)让你以为成功了。绕过验证必须对比请求/响应差异
  3. 自定义编译是终极方案。改名换端口能过的都是弱检测;强检测(内存扫描、inline hook 检测)的终极解是自己编译 frida,把所有特征字符串换成随机值——一次编译,长期受用

总结

  1. 反 Frida 检测十项:端口、进程、maps、包名、线程名、内存、inline hook、TracerPid、时序、调用栈
  2. 绕过按优先级:改名换端口 → 文件读取过滤 → 反制检测函数 → 自定义编译
  3. 检测函数本身可被 hook,套娃游戏里 frida 在更底层
  4. 静默检测最危险,验证靠对比法

交流微信:run1255

By 百趣云 阅读量:4 On