反调试及应对
Android逆向-Frida反调试及应对
检测frida-server
文件名
检测有没有叫做frida-server
的文件或进程存在。比如:
1 | public boolean checkRunningProcesses() { |
绕过:改名字
1 | mv frida-server rf-server |
检查27042端口
检查Frida默认27042端口,比如:
1 | boolean is_frida_server_listening() { |
绕过:修改端口。
在adb shell里面执行:
1 | ./rf-server -l 0.0.0.0:11451 |
然后
1 | adb forward tcp:11451 tcp:11451 |
即可。
父子进程调试(双进程保护)
这个例子是子进程去Attach父进程。这里的解决方式比较简单:
1 | frida -U -f com.shark.tracerpidapp |
让Frida去spawn APP父进程,让子进程没法提前Attach。
然后就可以再附上Frida脚本,提前对进程进行patch,从而实现反反调试。
TracerPid反调试
原理
首先ps查看进程号
1 | frida-ps -U |
然后看status
1 | adb shell |
比如:
1 | redfin:/ $ cat /proc/25421/status |
TracerPid就是调试此进程的pid,在同一时刻只能有一个进程调试本进程
在使用IDA android_server对进程进行调试的时候,这个TracerPid
就会变成server的PID。
检测Demo
这是一个检测demo:
1 |
|
Frida fgets反反调试
通过Hook libc.so
的fgets
函数来检查。
1 | var anti_fgets = function () { |
检测D-Bus
frida-server
使用D-Bus协议通信,我们为每个开放的端口发送D-Bus的认证消息,哪个端口回复了哪个就是frida-server
。比如:
1 | /* |
这串代码通过遍历所有端口,向其中开放的端口发送DBus通信来检测是否有Frida存在,而其中最核心的判定点其实是strcmp(res, "REJECT");
,因此可以通过**Hook系统库strstr
,strcmp
**等字符串比对函数来进行绕过。
不过这种字符串比对函数确实没什么设计上的难度,因此如果遇到了自行实现字符串比对的代码的话,那就没戏了。
检测/proc/pid/maps
映射文件(未解决)
原理
首先手动测试一下,在没有Frida的APP上:
1 | adb shell |
然后打印:
1 | redfin:/ # cat /proc/17637/maps |
等很多很多的玩意出来,表明了进程中内存的分布。
然后再使用Frida的spawn模式去打开APP:
1 | frida -U -f com.baidu.naviauto |
然后用同样的方式拿到maps,经过搜索会发现有frida
相关的字符串。因此判断代码:
1 | char line[512]; |
还有一种改进版本,就是通过进一步进行内存字符串搜索,来检查Frida库特征,比如LIBFRIDA
:https://github.com/b-mueller/frida-detection-demo/blob/master/AntiFrida/app/src/main/cpp/native-lib.cpp
1 | static char keyword[] = "LIBFRIDA"; |
Android逆向 多种特征检测 Frida - 简书 (jianshu.com)
注意
my_openat()
等函数,它们并非平常的 libc 库函数,是自定义实现的,但是功能和 libc 中的一样,设置了系统调用的参数,执行了软中断。因为直接调用公共 API 并不可靠,这样不容易被 hook。完整的实现在 https://github.com/b-mueller/frida-detection-demo/blob/master/AntiFrida/app/src/main/cpp/syscall.S 。下面是 my_openat 的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include "bionic_asm.h"
.text
.globl my_openat
.type my_openat,function
my_openat:
.cfi_startproc
mov ip, r7
.cfi_register r7, ip
ldr r7, =__NR_openat
swi #0
mov r7, ip
.cfi_restore r7
cmn r0, #(4095 + 1)
bxls lr
neg r0, r0
b __set_errno_internal
.cfi_endproc
.size my_openat, .-my_openat;
同时也会有
/data/local/tmp
的这一串路径名存在。关于这个的解决方法放在另外一个章节。
方案一
直接使用Hluda Frida Server
是一种方案。
方案二
检测/proc/pid/task/tid/stat
或proc/pid/task/tid/status
(未解决)
方案一
直接使用Hluda Frida Server
是一种方案。
/data/local/tmp
检查
Hook open与read来绕过对maps中/data/local/tmp
的检查。
过某交友软件frida反调试_马到成功~的博客-CSDN博客
1 | function main() { |
其他
Frida-LR寄存器溯源
1 | var anti_antiDebug = function() { |
检测RPC调用
1 | looperclazz = (*env)->FindClass(env, &xmmword_39010);// android/os/Looper |
在 so 中调用android.os.Looper.myLooper()
, 如果是正常的调用, 则通过CallStaticObjectMethodV
调用的结果为非 0; 如果是通过 frida 的主动调用, 则返回结果为 0; 因为 frida 的主动调用不在主线程中; 可以作为一个主动调用的检测点。
检查.plt表
r2-pay: anti-debug, anti-root & anti-frida (part 1) | Romain Thomas
遍历.plt
表来检查libc有没有被Frida给Hook了。
检查后再去调用libc函数,比如pthread_create
函数。
Frida检测
muellerberndt/frida-detection: A couple of methods for detecting Frida on Android. (github.com)
xyxdaily/frida-detect-protect (github.com)
strongR-frida-android⭐
hzzheyang/strongR-frida-android: An anti detection version frida-server for android. (github.com)
Patchs/strongR-frida/frida-core at master · hluwa/Patchs (github.com)
这是一个将frida源码进行patch魔改,实现掩盖frida特征的一个项目。
可以偷懒直接下载它提供的release,但也最好自己试试魔改。
frida编译与魔改放在了另一个blog。
参考
分类: frida | 凡墙总是门 (kevinspider.github.io)
过某交友软件frida反调试_马到成功~的博客-CSDN博客
安卓逆向 - Frida反调试绕过_小馒头yy的博客-CSDN博客
一例简单的frida反调试绕过 - 知乎 (zhihu.com)
TracerPid反调试 - 简书 (jianshu.com)
Android逆向 多种特征检测 Frida - 简书 (jianshu.com)
- 本文作者: Taardis
- 本文链接: https://taardisaa.github.io/2023/09/12/Android逆向-Frida反调试及应对/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!