訊號

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
 
// /usr/include/sys/ucontext.h
void segv_handler(int sig, siginfo_t *si, void *context)
{
    printf("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
    abort();
}
 
int main() {
    struct sigaction act;
 
    /* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
    act.sa_flags = SA_SIGINFO;
 
    /* Use the sa_sigaction field because the handles has two additional parameters */
    act.sa_sigaction = segv_handler;
 
    sigemptyset(&act.sa_mask);
 
    /* Register our signal handler. */
    sigaction(SIGSEGV, &act, NULL);
 
    /* Trigger segfault */
    *(char *) 0 = 0;
}
    • arch/x86/include/asm/sigcontext.h
    • /usr/include/sys/ucontext.h
      /* Context to describe whole processor state.  */
      typedef struct
        {
          gregset_t gregs;
          /* Note that fpregs is a pointer.  */
          fpregset_t fpregs;
          unsigned long __reserved1 [8];
      } mcontext_t;
       
      /* Userlevel context.  */
      typedef struct ucontext
        {
          unsigned long int uc_flags;
          struct ucontext *uc_link;
          stack_t uc_stack;
          mcontext_t uc_mcontext;
          __sigset_t uc_sigmask;
          struct _libc_fpstate __fpregs_mem;
        } ucontext_t;
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
void segv_handler(int sig, siginfo_t *si, void *context)
{
    fprintf(stderr, "Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
 
    if (si->si_code == SEGV_MAPERR)
        fprintf(stderr, "Address not mapped to object\n");
    else if (si->si_code == SEGV_ACCERR)
        fprintf(stderr, "Invalid permissions for mapped object\n");
    else
        fprintf(stderr, "No such code\n");
 
    exit(1);
}
 
static void map_readonly(void *addr, long size)
{
    unsigned long start, end, page_size;
 
    page_size = getpagesize();
    start = (unsigned long)addr;
    start &= ~(page_size - 1);
 
    end = (unsigned long)addr + size;
    end += page_size - 1;
    end &= ~(page_size - 1);
 
    mprotect((void *)start, end - start,
             PROT_READ);
}
 
int main()
{
    sigset_t set;
    struct sigaction sigact;
    char *vaddr = 0;
 
    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_flags = SA_SIGINFO;
    sigact.sa_sigaction = segv_handler;
    sigaction(SIGSEGV, &sigact, NULL);
    sigemptyset(&set);
    sigaddset(&set, SIGSEGV);
 
    //*vaddr = 'a'; // SEGV_MAPERR
 
    char *vaddr2 = (char *)malloc(4);
 
    map_readonly(vaddr2, 4);
 
    *vaddr2 = 'a'; // SEGV_ACCERR
}

其它

外部連結

登录