SIG_IGN不适用于PTRACE_TRACEME?

时间:2018-06-01 09:06:59

标签: linux signals ptrace

我正在使用ptrace方法

测试一个antidebug解决方案
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;
}

当我执行它时,我总是得到一个停止的错误,

# ./a.out
not being traced

[4]+  Stopped                 ./a.out

然后我尝试添加像这样的SIGSTOP处理程序

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

它还有一个停止的错误,任何想法?

1 个答案:

答案 0 :(得分:3)

以下是发生的事情:

  • handle = dlopen ("libc.so", RTLD_LAZY)handle分配NULL。 Dlopen失败是因为你的GNU / Linux发行版(以及大多数其他现代发行版)lib.so不是共享库 - 它是一个GNU ld脚本。
    dlopen ("libc.so.6", RTLD_LAZY)会成功。

  • go = dlsym(handle, "ptrace")成功(!)。使用glibc,可以将NULL指针作为句柄参数传递给dlsym,因为glibc碰巧使用((void *) 0)作为RTLD_DEFAULT
    这通常不适用于其他系统。 FreeBSD的dlsym使用((void *) -2)作为RTLD_DEFAULT,如果你用一个NULL句柄调用dlsym,它将在可执行文件或共享库中查找名为dlsym的符号。

  • go(PTRACE_TRACEME, 0)成功。

  • dlclose(handle)无法容忍NULL句柄,并且会导致段错误,因此会引发SIGSEGV信号。

  • 由于正在跟踪该过程,因此接收信号会导致其停止(暂停)。在shell中键入jobs将显示使进程停止的信号。

代码

signal(SIGSTOP, SIG_IGN);

不会真的做任何事情。 SIGSTOP是无法捕获,忽略或保留的信号之一。