Frida反调试

2020-12-21  本文已影响0人  Sharkchilli

前言

逆向某app时,想用frida进行hook分析其执行流程,遇到了frida的反调试。这里记录一下出现问题的情况和反调试的实现.

环境

Android8
frida12.11.18
windows10

frida 注入

使用frida -U注入app

frida -U com.shark.tracerpidapp

结果如下

     ____
    / _  |   Frida 12.11.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
Failed to spawn: ambiguous name; it matches: com.shark.tracerpidapp (pid: 9802), com.shark.tracerpidapp (pid: 9847)

这里有两个com.shark.tracerpidapp名称的进程

我们直接进入adb查看进程

sailfish:/ # ps -A | grep com.shark
u0_a129       9802   671 2251940  73376 SyS_epoll_wait 72493ca5d0 S com.shark.tracerpidapp
u0_a129       9847  9802 2231280  34092 hrtimer_nanosleep 72493cafd8 S com.shark.tracerpidapp

可以看到确实有两个进程,frida分不清你要注入哪个进程所以报出如上错误。

我们选择父进程进行注入

(venv) D:\FridaTest>frida -U 9802
     ____
    / _  |   Frida 12.11.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
Failed to attach: unable to access process with pid 9802 due to system restrictions; try `sudo sysctl kernel.yama.ptrace_scope=0`, or run Frida as root

叫我们用root去执行,这里是没有用的。我们到adb看看这个父进程的TracerPid信息就知道了

至于为什么看TracerPid请移步文章TracerPid反调试

sailfish:/ # cat /proc/9802/status | grep TracerPid
TracerPid:      9847

可以看到父进程已经被子进程ATTACH,而frida也依赖于ptrace所以这里肯定注入不进去

解决方案

我们不要让frida注入,而是使用frida启动app,使用-f选项,我们告诉Frida注入Zygote并开始启动应用程序

(venv) D:\FridaTest>frida -U -f com.shark.tracerpidapp
     ____
    / _  |   Frida 12.11.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://www.frida.re/docs/home/
Spawned `com.shark.tracerpidapp`. Use %resume to let the main thread start executing!
[Pixel::com.shark.tracerpidapp]-> %resume

还有一种打补丁的方式,在下面参考中有。这里就不再赘述。

反调试实现原理

这个反调试其实就是用了TracerPid反调试的原理,但是在这里有一些不一样。
1:这里是子进程ATTACH父进程
2:在Android8中ptrace(PTRACE_TRACEME, 0, 0, 0); 虽然返回的不是-1但是无法成功

PTRACE_ATTACH

所以我们这里要使用ptrace(PTRACE_ATTACH, parent, 0, 0)来实现。
PTRACE_ATTACH参数
ptrace(PTRACE_ATTACH,pid)
跟踪指定pid 进程。pid表示被跟踪进程。被跟踪进程将成为当前进程的子进程,并进入中止状态
PTRACE_CONT参数
ptrace(PTRACE_CONT, pid, 0, signal)
继续执行。pid表示被跟踪的子进程,signal为0则忽略引起调试进程中止的信号,若不为0则继续处理信号signal
先使用PTRACE_ATTACH进行附加,这时候被附加进程会阻塞。再使用PTRACE_CONT继续执行被附加的进程。为了确保PTRACE_CONT能被执行我们在PTRACE_ATTACH完后要马上wait阻塞当前线程。当附加成功后wait阻塞解除就能执行到PTRACE_CONT了

代码

void readStatus() {
    FILE *fd;
    char filename[128];
    char line[128];
    pid_t pid = syscall(__NR_getpid);
    LOGI("PID : %d", pid);
    sprintf(filename, "/proc/%d/status", pid);//读取/proc/pid/status中的TracerPid
    pid_t ppid = fork();
    if (ppid == 0) {
        pid_t parent = getppid();
        //parent是被跟踪的进程 异步操作
        int pt = ptrace(PTRACE_ATTACH, parent, 0, 0);
        int status = 0;
        // ATTACH成功前停下 为了保证下面的PTRACE_CONT操作能够执行到 这样被ATTACH的进程就不会一直进入中止状态
        wait(NULL);
        //让被调试的进程重新恢复运行
        if (ptrace(PTRACE_CONT, parent, NULL, 0) < 0) {
            perror("ptrace_cont");
            return;
        }
        if (pt == -1)
            exit(0);
        while (1) {
            sleep(CHECK_TIME);
        }
    } else {
        LOGE("fork error");
    }
}

参考

Android APP破解利器Frida之反调试对抗
ptrace使用简介

上一篇 下一篇

猜你喜欢

热点阅读