SIG_IGN не работает с PTRACE_TRACEME? - PullRequest
0 голосов
/ 01 июня 2018

Я тестирую решение для защиты от ошибок с помощью ptrace метода

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 голосов
/ 01 июня 2018

Вот что происходит:

  • handle = dlopen ("libc.so", RTLD_LAZY) присваивает NULL значение handle.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.
    Это обычно не работает на других системах.Dlsym во FreeBSD использует ((void *) -2) как RTLD_DEFAULT, и если вы вызываете dlsym с дескриптором NULL, он будет искать символ в исполняемой или общей библиотеке, которая вызвала dlsym.

  • go(PTRACE_TRACEME, 0) успешно.

  • dlclose(handle) не может допускать дескриптор NULL, и это вызывает segfault, поэтому сигнал SIGSEGV повышается.

  • поскольку процесс отслеживается, получение сигнала приводит к его остановке (приостановке).Ввод jobs в вашей оболочке покажет сигнал, который остановил процесс.


Код

signal(SIGSTOP, SIG_IGN);

ничего не даст.SIGSTOP - это один из сигналов, который нельзя поймать, проигнорировать или удержать.

...