How to resume main thread/process while tracing syscalls and cloned process with ptrace()

154 Views Asked by At

I developed a small utility/tool with ptrace() to trace and hook syscalls.

Here is the following code snippet (some parts are deliberately removed for brevity):

if(0 != ptrace(PTRACE_ATTACH, target_pid, nullptr, nullptr)){
        printf("attach to %d failed.\n", target_pid);
        fflush(stdout);
        return -1;
    } else {

        std::string traceeProcMemPath = "/proc/" + std::to_string(target_pid) + "/mem";
        int real_traceeProcMemFd = openat(AT_FDCWD, traceeProcMemPath.c_str(), O_RDONLY | O_CLOEXEC, 0);
        if (real_traceeProcMemFd < 0) {
            printf("Could not obtain target process /proc/mem.");
            fflush(stdout);
            kill(getpid(), SIGKILL);
            return -1;
        }

        traceePid = target_pid;
        traceeProcMemFd = real_traceeProcMemFd;

        printf("Attach success.\n");

        // essential vars.
        int status;
        pid_t pid;

        fflush(stdout);

        wait(NULL); // PTRACE_SETOPTIONS may work only after this
        long ptraceOption = PTRACE_O_TRACECLONE | PTRACE_O_TRACESYSGOOD;
        ptrace(PTRACE_SETOPTIONS, traceePid, NULL, ptraceOption);
        ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL); // same as PTRACE_CONT, but stops on the next syscall.

        while (pid = wait(&status), pid > 0)
        {
            if (WIFEXITED(status) || WIFSIGNALED(status))
            {
                if (pid == traceePid) {
                    // we are in the parent, do nothing.
                    break;
                }
                // we are in child -- either thread or process.
                printf("Child process/thread %d exited\n", pid);
                continue;
            }

            if(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
            {
                printf("received SIGTRAP\n");
                printf("received ptrace event: %d\n", ((status >> 16) & 0xffff));

                pid_t new_child;
                if(((status >> 16) & 0xffff) == PTRACE_EVENT_CLONE)
                {
                    if(ptrace(PTRACE_GETEVENTMSG, traceePid, 0, &new_child) != -1)
                    {
                        printf("child %d created\n", new_child);
                        if (0 != ptrace(PTRACE_ATTACH, new_child, nullptr, nullptr)) {}
                        printf("attached to child %d\n", new_child);
                        ptrace(PTRACE_CONT, new_child, NULL, NULL);
                        ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
                        continue;
                    }
                    // --- THIS IS WHERE THE HANG HAPPENS ---
                    // Main thread is staying at futex (98) syscall, using PTRACE_SYSCALL / PTRACE_CONT didn't work.
                    // Using kill -18 did not work as well.
                    printf("no new child process/thread is created\n");
                    ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
                    continue;
                }
                ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
                continue;
            }
            enterSysCall(traceePid);
            ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
            leaveSysCall(traceePid);
            ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
        }
    }

The code above seems to work for tracing syscalls and tracking created childs, however, after few moments, it's stuck at the following code:

// --- THIS IS WHERE THE HANG HAPPENS ---
                    // Main thread is staying at futex (98) syscall, using PTRACE_SYSCALL / PTRACE_CONT didn't work.
                    // Using kill -18 did not work as well.
                    printf("no new child process/thread is created\n");
                    ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);
                    continue;

Here are the logs from the console:

[PID: 24300] Entering syscall: 63
[PID: 24300] Leaving syscall: 63
[PID: 24300] Entering syscall: 63
[PID: 24300] Leaving syscall: 63
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 63
[PID: 24300] Leaving syscall: 63
[PID: 24300] Entering syscall: 63
[PID: 24300] Leaving syscall: 63
[PID: 24300] Entering syscall: 209
[PID: 24300] Leaving syscall: 209
[PID: 24300] Entering syscall: 209
[PID: 24300] Leaving syscall: 209
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 174
[PID: 24300] Leaving syscall: 174
[PID: 24300] Entering syscall: 174
[PID: 24300] Leaving syscall: 174
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 29
[PID: 24300] Leaving syscall: 29
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 233
[PID: 24300] Leaving syscall: 233
[PID: 24300] Entering syscall: 233
[PID: 24300] Leaving syscall: 233
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 56
[PID: 24300] Leaving syscall: 56
[PID: 24300] Entering syscall: 56
[PID: 24300] Leaving syscall: 56
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 56
[PID: 24300] Leaving syscall: 56
[PID: 24300] Entering syscall: 56
[PID: 24300] Leaving syscall: 56
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 61
[PID: 24300] Leaving syscall: 61
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 57
[PID: 24300] Leaving syscall: 57
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26666 created
attached to child 26666
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26667 created
attached to child 26667
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26668 created
attached to child 26668
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26669 created
attached to child 26669
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26670 created
attached to child 26670
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26671 created
attached to child 26671
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26672 created
attached to child 26672
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 222
[PID: 24300] Leaving syscall: 222
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 226
[PID: 24300] Leaving syscall: 226
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
received SIGTRAP
received ptrace event: 3
child 26673 created
attached to child 26673
[PID: 24300] Entering syscall: 220
[PID: 24300] Leaving syscall: 220
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 135
[PID: 24300] Leaving syscall: 135
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 113
[PID: 24300] Leaving syscall: 113
[PID: 24300] Entering syscall: 278
[PID: 24300] Leaving syscall: 278
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
[PID: 24300] Entering syscall: 98
[PID: 24300] Leaving syscall: 98
received SIGTRAP
received ptrace event: 3
no new child process/thread is created

Could anyone please help pinpoint the issue or provide some guidance where the above code should be improved? Thank you very much!

I expected the main process/thread to continue following a call to ptrace(PTRACE_SYSCALL, traceePid, NULL, NULL);, however, it didn't work.

0

There are 0 best solutions below