浅谈Frida 检测与绕过

目录

  1. ptrace 占位与进程名检测
  2. 端口检测与 D-Bus 协议通信
  3. 扫描 /proc 目录(maps、task、fd)
  4. 定位 so 中的 SVC syscall
  5. 内存动态释放代码

1. ptrace 占位与进程名检测

检测方式

  • 遍历运行进程列表,检查是否存在 frida-server 或相关进程名(如 fsarm64)。
  • 若未改名,直接检测进程名;若改名,可能通过字符串匹配(如 strcmp)检查特征。

绕过方法

  • 修改进程名:避免使用默认的 frida-server
  • Spawn 模式注入:在目标应用启动前注入,避免 ptrace 冲突。

检测进程名:

ps -A | grep fsarm64

2. 端口检测与 D-Bus 协议通信

检测方式

  • 默认端口:检查 27047 是否开放(Frida 默认端口)。
  • D-Bus 协议:向所有开放端口发送 D-Bus 认证消息,若返回 REJECT 则为 Frida。

绕过方法

  • 修改端口:启动时指定非默认端口(如 frida-server -l 127.0.0.1:8080)。
  • Hook 字符串比较函数:拦截 strcmp,避免返回 REJECT

检测端口:

netstat -tuln | grep 27047

3. 扫描 /proc 目录(maps、task、fd)

检测方式

  • /proc/pid/task:检查线程名是否为 gmaingdbus 等 Frida 特征。
  • /proc/pid/fd:检查是否打开 Frida 相关文件。

绕过方法

  • 重定向文件操作:拦截 openreadlink 等函数调用。
  • 动态加载 so:避免文件路径暴露。

示例代码(扫描线程):

ls /proc/<pid>/task

4. 定位 so 中的 SVC syscall

检测方式

  • ARM32:搜索机器码 00 00 00 EF
  • ARM64:搜索机器码 01 00 00 D4

绕过方法

  • 动态生成代码:通过 malloc 申请内存并写入机器码,避免静态特征。
  • 内核级 Hook:使用 eBPF 或定制内核拦截 svc 调用。

Frida 枚举模块:

Process.enumerateRanges("r-x").forEach(range => {
  console.log(JSON.stringify(range));
});

在内核中对SVC syscall 指令进行打印(保存pc寄存器),可以定制内核,也可以使用ebpf等,这对app的运行过程没有影响,因为原本进行Trace指令app会非常的卡,这也不会有frdia的特征,这是真实app执行过程中的指令,可能app中没有走的流程就定位不了


5. 内存动态释放代码

检测方式

  • 一般这种就是防止很快就找到svc,并且每次执行的地址不一样,并且通过遍历内存也很难找到对应的位置,检查是否存在动态申请的可执行内存(如 mprotect + malloc)。实现方式:使用malloc申请一块区域,并且往里面写入代码的机器码,比如openat来检测frida的一些代码对应的机器码,或者是含svc方式进行操作的,使用mprotect赋予可执行权限,然后转换为函数指针,进行调用

绕过方法

  • 延迟释放:在非关键逻辑段动态释放内存。
  • 混淆内存操作:混合正常内存操作与动态代码。
在这里插入代码片

动态执行:

unsigned char code[] = {0x48, 0x83, 0xEC, 0x28, ...};
// 分配内存来存放机器码    
size_t code_size = sizeof(code);
unsigned char* exec_mem = (unsigned char*)malloc(code_size);
// 将机器码复制到申请的内存中    
std::memcpy(exec_mem, code, code_size);
// 将内存地址转换为函数指针    
openat_func func = reinterpret_cast<openat_func>(exec_mem);
// 执行机器码,调用函数   
 const char* path = "/tmp/testfile"; 
 // 文件路径    
 int dirfd = AT_FDCWD; // AT_FDCWD 表示当前目录  
 int flags = O_RDONLY; // 只读模式   
 mode_t mode = 0;
 int result = func(dirfd, path, flags, mode); // 调用机器码

总结

本文详细分析了 Frida 的常见检测方式及绕过技术,涵盖进程、端口、文件、系统调用等多维度对抗。实际应用中需根据场景灵活组合方案。

注意:欢迎交流,本文仅用于技术研究,请勿用于非法用途。

你可能感兴趣的:(linux)