绕过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
        • hluda
        • Florida
        • Froda ?

相关源码

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);
}

results matching ""

    No results matching ""