绕过Frida检测
- 绕过frida检测 = 反调试
- 核心思路=核心的点
- 把
frida-server
的文件名改掉- 举例
frida-server-12.8.9-android-arm64
->fs1289amd64
- 举例
- 改变端口号
- 举例
frida-server
的默认端口是27042
,改为别的端口号
- 举例
- 通过Frida内存特征对maps中elf文件进行扫描匹配特征
- 其他反调试思路
- 想过这种反调试,得找到反调试在哪个so的哪里,nop掉创建
check_loop
线程的地方,或者nop
掉kill自己进程的地方,都可以。也可以直接kill掉反调试进程- 举例
- 别人就曾经遇到过这种情况,frida命令注入后,app调不起来,这时候用
ps -e
命令查看多一个反调试进程,直接kill掉那个进程后,app就起来了,这个app是使用的一个大厂的加固服务,这个进程就是壳的一部分
- 别人就曾经遇到过这种情况,frida命令注入后,app调不起来,这时候用
- 举例
- 想过这种反调试,得找到反调试在哪个so的哪里,nop掉创建
- 把
- 常用方案
- 使用魔改去特征的版本的frida
- hluda
- Florida
- Froda ?
- 使用魔改去特征的版本的frida
- 核心思路=核心的点
相关源码
AntiFrida
https://github.com/qtfreet00/AntiFrida
核心代码:
void *check_loop(void *) {
int fd;
char path[256];
char perm[5];
unsigned long offset;
unsigned int base;
long end;
char buffer[BUFFER_LEN];
int loop = 0;
unsigned int length = 11;
//"frida:rpc"的内存布局特征
unsigned char frida_rpc[] =
{
0xfe, 0xba, 0xfb, 0x4a, 0x9a, 0xca, 0x7f, 0xfb,
0xdb, 0xea, 0xfe, 0xdc
};
for (unsigned char &m : frida_rpc) {
unsigned char c = m;
c = ~c;
c ^= 0xb1;
c = (c >> 0x6) | (c << 0x2);
c ^= 0x4a;
c = (c >> 0x6) | (c << 0x2);
m = c;
}
//开始检测frida反调试循环
LOGI("start check frida loop");
while (loop < 10) {
fd = wrap_openat(AT_FDCWD, "/proc/self/maps", O_RDONLY, 0);
if (fd > 0) {
while ((read_line(fd, buffer, BUFFER_LEN)) > 0) {
// 匹配frida-server和frida-gadget的内存特征
if (sscanf(buffer, "%x-%lx %4s %lx %*s %*s %s", &base, &end, perm, &offset, path) !=
5) {
continue;
}
if (perm[0] != 'r') continue;
if (perm[3] != 'p') continue;
if (0 != offset) continue;
if (strlen(path) == 0) continue;
if ('[' == path[0]) continue;
if (end - base <= 1000000) continue;
if (wrap_endsWith(path, ".oat")) continue;
if (elf_check_header(base) != 1) continue;
if (find_mem_string(base, end, frida_rpc, length) == 1) {
//发现其内存特征
LOGI("frida found in memory!");
#ifndef DEBUG
//杀掉自己的进程
wrap_kill(wrap_getpid(),SIGKILL);
#endif
//退出
break;
}
}
} else {
LOGI("open maps error");
}
wrap_close(fd);
//休息三秒,进入下一个检查循环,也就是这个反调试一共会运作30秒,30秒后结束
loop++;
sleep(3);
}
return nullptr;
}
void anti_frida_loop() {
pthread_t t;
//创建一个线程,执行反调试工作
if (pthread_create(&t, nullptr, check_loop, (void *) nullptr) != 0) {
exit(-1);
};
pthread_detach(t);
}