how to intercept linux signals ? (in C)

2019-01-20 02:37发布

I need to intercept and trace signals from any binaries, like strace does it under linux. I don't need a so verbose output like the real one strace. I just want to know how it works, how can I intercept signal and how can I trace them. Thanks in advance :)

3条回答
我想做一个坏孩纸
2楼-- · 2019-01-20 03:05

Intercepting signals to other processes is something you should not do for any reason other than debugging them. This is what strace is intended for. Processes should be capable of handling their own signals.

Needless to say, if you are writing a debugger, understand ptrace().

查看更多
Viruses.
3楼-- · 2019-01-20 03:22

This is a simple implementation:

Put somewhere in your int main() several calls to signal(), one for each signal you want to catch. The first argument is the signal name; the second is the signal handler function (more on that below):

    signal(SIGFPE, SignalHandler);
    signal(SIGILL, SignalHandler);
    signal(SIGINT, SignalHandler);
    signal(SIGSEGV, SignalHandler);
    signal(SIGTERM, SignalHandler);
#ifndef WIN32
    signal(SIGHUP, SignalHandler);
    signal(SIGQUIT, SignalHandler);
    signal(SIGKILL, SignalHandler);
    signal(SIGPIPE, SignalHandler);
    signal(SIGCHLD, SignalHandler);
#endif

Now, write a signal function. It must return void and accept an int: void SignalHandler(int signal_number):

void SignalHandler(int signal_number)
{
    printf("Received signal: %s\n", strsignal(signal_number);
    // Do something
}

That's it! You can also test it by sending a signal to yourself with the function raise(SIGNAL_NAME); for example, try raise(SIGTERM);!

查看更多
戒情不戒烟
4楼-- · 2019-01-20 03:23

strace uses the ptrace() system call for tracing, which also allows you to intercept (and possibly manipulate) signals sent to the process.

Here's a tiny example:

#include <sys/ptrace.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    /* simple example, child is traced, uses alarm which causes a signal to be
     * set up */
    pid_t child;

    child = fork();
    if (child == 0)
    {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        alarm(3);
        while(1)
        {
        }
        exit(0);
    }

    /* parent */
    while(1)
    {
        int wstatus;
        int signum;

        wait(&wstatus);
        if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus))
            break;

        signum = WSTOPSIG(wstatus);
        printf("child stopped with signal %d\n", signum);
        /* resume execution */
        ptrace(PTRACE_CONT, child, NULL, signum);
    }

    return 0;
}
查看更多
登录 后发表回答