android反调试之父子调试

普通进程
android反调试之父子调试
反调试进程
android反调试之父子调试
源码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>

#define eprintf(...) fprintf(stderr, ##__VA_ARGS__)

void loop()
{
    while(true) 
    {
        sleep(60);
    }
}

bool may_cause_group_stop(int signo)
{
    switch(signo) 
    {
        case SIGSTOP:
        case SIGTSTP:
        case SIGTTIN:
        case SIGTTOU:
            return true;
            break;
        default:
            break;
    }

    return false;
}

void handle_events()
{
    int status = 0;
    pid_t pid = 0;

    do 
    {
        pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, __WALL));
        if (pid < 0) 
        {
            perror("waitpid");
            exit(EXIT_FAILURE);
        }

        if (WIFEXITED(status)) 
        {
            eprintf("%d exited, status=%d\n", pid,  WEXITSTATUS(status));
        } 
        else if (WIFSIGNALED(status)) 
        {
            eprintf("%d killed by signal %d\n", pid, WTERMSIG(status));
        } 
        else if (WIFSTOPPED(status)) 
        {
            int signo = WSTOPSIG(status);
            eprintf("%d stopped by signal %d\n", pid, signo);

            if (may_cause_group_stop(signo)) 
            {
                signo = 0;
            }

            long err = ptrace(PTRACE_CONT, pid, NULL, signo);
            if (err < 0) 
            {
                perror("PTRACE_CONT");
                exit(EXIT_FAILURE);
            }
        }

    } while (!WIFEXITED(status) && !WIFSIGNALED(status));

}

void safe_attach(pid_t pid)
{
    long err = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
    if (err < 0) 
    {
        perror("PTRACE_ATTACH");
        exit(EXIT_FAILURE);
    }

    int status = 0;
    err = TEMP_FAILURE_RETRY(waitpid(pid, &status, __WALL));
    if (err < 0) 
    {
        perror("waitpid");
        exit(EXIT_FAILURE);
    }

    if (WIFEXITED(status)) 
    {
        eprintf("%d exited, status=%d\n", pid,  WEXITSTATUS(status));
        exit(EXIT_SUCCESS);
    } 
    else if (WIFSIGNALED(status)) 
    {
        eprintf("%d killed by signal %d\n", pid, WTERMSIG(status));
        exit(EXIT_SUCCESS);
    } 
    else if (WIFSTOPPED(status)) 
    {
        int signo = WSTOPSIG(status);
        eprintf("%d stopped by signal %d\n", pid, signo);

        if (may_cause_group_stop(signo)) 
        {
            signo = 0;
        }

        err = ptrace(PTRACE_CONT, pid, NULL, signo);
        if (err < 0) 
        {
            perror("PTRACE_CONT");
            exit(EXIT_FAILURE);
        }
    } 

}

void protect_father()
{
    pid_t ppid =  getppid();

    safe_attach(ppid);
    handle_events();
}

int main()
{
    eprintf("main process pid: %d\n", getpid());

    // 设置可ptrac
    prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);

    pid_t pid = fork();
    if (pid < 0) 
    {
        perror("fork");
    } 
    else if (pid == 0) 
    {
        eprintf("child process pid: %d\n", getpid());

        protect_father();
        exit(EXIT_SUCCESS);
    }

    eprintf("main process start loop...\n");
    loop();

    return 0;
}

可以通过hook fork或者调试子进程过反调试
查看子进程
android反调试之父子调试

猜你喜欢

转载自blog.51cto.com/haidragon/2388665
今日推荐