daisy
daisy

Reputation: 23489

SIG_IGN does not work with PTRACE_TRACEME?

I'm testing an antidebug solution with ptrace method

int main(int argc, char **argv) {
    void *handle;
    long (*go)(enum __ptrace_request request, pid_t pid);

    // get a handle to the library that contains 'ptrace'
    handle = dlopen ("libc.so", RTLD_LAZY);

    // reference to the dynamically-resolved function 'ptrace'
    go = dlsym(handle, "ptrace");

    if (go(PTRACE_TRACEME, 0) < 0) {
        puts("being traced");
        exit(1);
    }

    puts("not being traced");

    // cleanup
    dlclose(handle);

    return 0;
}

When I execute it, I'm always getting a stopped error,

# ./a.out
not being traced

[4]+  Stopped                 ./a.out

Then I tried to add the SIGSTOP handler like this

int main(int argc, char **argv) {
    signal(SIGSTOP, SIG_IGN);

And it's still getting a stopped error, any ideas?

Upvotes: 0

Views: 226

Answers (1)

Mark Plotnick
Mark Plotnick

Reputation: 10251

Here's what's happening:

  • handle = dlopen ("libc.so", RTLD_LAZY) assigns NULL to handle. Dlopen fails because on your GNU/Linux distro (and most other modern distros) lib.so isn't a shared library - it's a GNU ld script.
    dlopen ("libc.so.6", RTLD_LAZY) would have succeeded.

  • go = dlsym(handle, "ptrace") succeeds(!). With glibc, it's OK to pass a NULL pointer as the handle argument to dlsym because glibc happens to use ((void *) 0) as RTLD_DEFAULT.
    This generally won't work on other systems. FreeBSD's dlsym uses ((void *) -2) as RTLD_DEFAULT, and if you call dlsym with a NULL handle, it will look for the symbol within the executable or shared library that called dlsym.

  • go(PTRACE_TRACEME, 0) succeeds.

  • dlclose(handle) can't tolerate a NULL handle, and it causes a segfault, so the SIGSEGV signal is raised.

  • since the process is being traced, receiving a signal results in it being stopped (suspended). Typing jobs to your shell will show the signal that made the process stop.


The code

signal(SIGSTOP, SIG_IGN);

won't really do anything. SIGSTOP is one of the signals that cannot be caught, ignored, or held.

Upvotes: 3

Related Questions