这是最基础也是最常见的检测手段。由于绝大多数 Frida 教程都指导用户将服务端文件命名为 frida-server 并放置在 /data/local/tmp/ 目录下,App 的防护机制会针对这些“标准特征”进行扫描。防护代码通常会在 App 启动时执行以下检查:App 会尝试访问 Android 系统中的常见临时目录,查找是否存在包含 frida 关键字的文件。代码示例 (伪代码) :App 可以通过 Shell 命令或读取系统文件来获取当前运行的所有进程列表,并匹配黑名单。扫描方式:执行 ps -A 查看进程状态。敏感关键字:frida-server, frida-helper, frida-launcher代码示例 (伪代码) :针对上述特征检测,最直接有效的方法就是 “改名” 。这是最简单的一步。将 frida-server 重命名为类似系统进程的名字,既能避开文件扫描,启动后的进程名也会随之改变,从而避开进程扫描。操作步骤:有些深度检测不仅仅匹配文件名,还会扫描二进制文件内部的字符串特征(如 frida:rpc 字符串)。
此时,单纯重命名文件无效。你需要使用 HLuda(魔改版 Frida)。Frida 在运行时需要开启 TCP 端口与电脑端进行数据传输。如果不加配置,Frida 会默认绑定特定的特征端口,这成为了 App 检测的重要依据。Frida 服务端启动后,默认会监听以下两个端口:防护代码通常采用以下方式进行探测:App 可以执行 netstat 命令,查看当前系统是否有名为 0.0.0.0:27042 或 127.0.0.1:27042 的监听状态。绕过的核心思想是 “避开默认” 。只要我们不使用 27042 端口,上述针对固定端口的扫描就会失效。在手机端启动 frida-server 时,使用 -l (listen) 参数指定一个随机的非标准端口(例如 8888 或 6666)。修改端口后,电脑端的 Frida 客户端不会自动识别,必须手动进行端口转发或指定连接地址。方式 A:通过 USB 转发 (推荐)
我们需要将电脑的 8888 端口转发到手机的 8888 端口。方式 B:通过 WiFi 连接
如果手机和电脑在同一局域网,可以直接指定手机 IP。这是 Android Native 层反调试最经典的手段之一。Linux/Android 内核规定:同一个进程同时只能被一个调试器(Tracer)附加。Frida 的工作原理:Frida 本质上也是一个调试器,它需要通过 ptrace 系统调用附加(Attach)到目标 App 进程上才能进行 Hook。App 的防御手段:App 在启动的极早期(通常在 .init_array 或 JNI_OnLoad 中),主动调用 ptrace(PTRACE_TRACEME, 0, 0, 0) 自己附加自己。冲突结果:代码示例 (C/C++) :针对 ptrace 占坑,单纯的“Attach 模式”是必死的。我们需要利用 Frida 的 Spawn 模式 抢在 App 运行代码前介入,并修改 App 的检测逻辑。Spawn 模式 (-f) 会由 Zygote 进程 fork 出目标 App,并在 App 执行任何自己的代码(包括反调试代码)之前将 Frida 的 Gadget/Agent 注入进去。这给了我们一个“时间差”:Frida 先进去了,现在轮到 Frida 掌控局面。仅仅进入是不够的。如果 Frida 保持附加状态,App 随后的 ptrace 调用会失败,App 依然会发现并退出。
根本的解决办法是:Hook libc.so 中的 ptrace 函数,拦截 App 的调用,直接返回 0(假装成功),并且不要执行真正的 ptrace 系统调用。示例脚本:Frida 的客户端与服务端通信基于 D-Bus 协议(一种进程间通信/RPC 机制)。即使我们将 Frida 服务端改名并迁移目录,其通信协议的特征(尤其是握手阶段)依然是固定的。App 可以遍历本地所有开放的 TCP 端口,并尝试建立 Socket 连接。一旦连接成功,App 会发送 D-Bus 协议特定的握手消息。如果服务端响应了特定的 D-Bus 关键字(如 REJECT),则可认定该端口运行着 Frida。检测代码示例 (伪代码) :这是您提到的方法。原理是拦截 App 在处理网络响应时的比较逻辑。当 App 拿收到的数据去匹配 "REJECT" 时,我们欺骗它说“没匹配上”。注意:strcmp 和 strstr 是系统底层极其高频调用的函数。直接 Hook 会导致 App 巨卡无比甚至崩溃,必须加严格的过滤条件。相比于在运行时 Hook 极不稳定的 strstr,最彻底的办法是从源码层面消除特征。HLuda(或其他去特征版本)在编译 Frida 时做了如下修改:使用此类版本后,App 发送探测包收到的将不再是标准的 REJECT,从而直接绕过检测机制,无需编写任何 Hook 脚本。在 Linux/Android 系统中,一切皆文件。/proc/pid/fd/ 目录包含了当前进程打开的所有文件描述符(File Descriptors)。App 通过遍历该目录,可以获知进程加载了哪些文件、建立了哪些 Socket 连接。App 遍历 /proc/self/fd 目录下的所有文件,并使用 readlink 读取符号链接指向的真实路径。相关命令:ls -l /proc/self/fd 或 readlink -f /proc/self/fd/<id>检测代码示例 (伪代码) :如果 Frida 注入成功,该目录下可能会出现指向以下路径的链接:传统特征 (旧版 Frida) :在 高版本 Frida (>=16) 时:检查 FD 已经基本无法检测 Frida。在 Android 10+ 中,Google 对 memfd 的名称做了更严格的匿名化,Frida 使用的 memfd 不再暴露名称。无论特征如何变化,检测的核心动作都是调用 readlink 或 readlinkat 系统函数。
核心思路:Hook 这两个函数,当 App 试图读取的文件描述符指向包含 frida、gum 或 memfd 的路径时,将其替换为合法的系统路径(如 /dev/null 或 libc.so)。在 Android (Linux) 系统中,进程的每一个线程在 /proc/pid/task/ 目录下都有一个对应的子目录(目录名为线程 ID)。App 可以遍历该目录,读取每个线程的 status 或 comm 文件,获取线程名称。由于 Frida 依赖 GLib 库,运行时会创建特定的辅助线程,这些线程的默认名称具有极高的辨识度。如果 Frida 注入成功,进程中通常会出现以下命名的线程:核心思路是拦截对 /proc 目录下 comm 或 status 文件的读取操作。当发现 App 试图读取特定线程的信息时,检查读取到的内容,如果是 gmain 等敏感名称,将其替换为
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-289358.htm
[原创]Frida 常见检测与绕过
242 浏览
10 回复
过来瞧瞧
过来瞧瞧
收藏学习
感谢分享
tql
感谢分享
感谢分享
感谢分享
看看
学习了,谢谢