frida hook 检测简介

背景

最近分析了一个 app,有 frida 检测,一旦 attach 之后,app 就退出了。过去分析的一些 app,通常都有 frida 的检测,但不会这么暴力的退出。 于是我就分析了一下这个 app 的检测逻辑。基于此,我把市面上常见的一些 frida 检测逻辑都整理了一下。

检测方法

frida 的检测可以分为两种, 一种检测frida-server 是否运行, 一种检测frida 是否已经注入到程序中。

检测frida-server 是否运行的方法有:

  • 检测端口
  • 检测 D-Bus 协议
  • 检测文件路径

注入检测的方法有:

  • 检测 /proc/xx/maps
  • 内存中检索特殊字符串
  • 检测 /proc/xx/task/xx/stat 或 /proc/xx/task/xx/status
  • 检测 /proc/xx/fd
  • 检测 inline hook

下面展开介绍一下每个检测方法的细节。

检测端口

frida-server 启动的时候会监听 27042 端口, 所以检测这个端口可以认为存在 frida。

检测D-Bus 协议

frida 通过 D-Bus 协议通信, 所以向所有端口发送 AUTH 消息, 如果收到了返回,那么就可以确认 frida-server 存在.

检测文件路径

frida-server 启动之后, 会在本地生成一个 re.frida.server 的目录,可以检测这个路径来判断 fridaserver 是否启动过

检测/proc/xx/maps

在maps 文件中,会发现存在:

1
7327731000-7328057000 r--p 00000000 08:0d 917564                         /data/local/tmp/re.frida.server/frida-agent-64.so

因此,可以判断 frida 是否注入到内存中。

此外,还可以先从 maps 中过滤出包含 /data/local/tmp/ 的路径, 通过解析elf 文件的导出表,查看是否含有frida 的特征。
内存中检索特殊字符串

这是一个不太高效的方法,原理就是根据 maps 中的信息,访问内存,确认内存中是否存在带有 frida 特征的字符串,比如LIBFRIDA, 这个方法比较低效,所以不推荐。

检测 /proc/xx/task/xx/status

frida 在注入的时候会启动一个线程,通过分析,可以发现,线程存在一定的特征,即 gum-js-loop 或者 gmain,如果扫描 status 文件发现这些特征,就可以认为是 frida 注入了。

检测 /proc/xx/fd

frida 在注入的时候,会打开一个FIFO文件用于通信,通过 readlink 可以找到原始的文件名, 如果文件名中linjector则说明已经注入了。

1
2
:/proc/26047/fd # ls -al | grep /data/local/
l-wx------ 1 u0_a111 u0_a111 64 2023-05-25 19:24 386 -> /data/local/tmp/re.frida.server/linjector-4

检测 inline hook

frida 使用 inline hook 技术 hook 目标函数, 可以对常规的 libc 函数进行 hook, 一旦发现函数开头前几个字节符合特征,就可以认为是被 hook了。 另外在分析一些app的过程中,我发现有的厂商会检测_ZN3art12PrettyMethodEPNS_6mirror9ArtMethodEb 方法是否会被hook。这个方法的主要作用是将 ArtMethod 对象的信息转换为易于阅读的格式, 可能可以做一些辅助分析。