Skip to content

Instantly share code, notes, and snippets.

@scottt
Last active May 10, 2017 15:57
Show Gist options
  • Save scottt/c568b5cacdff8f2e9b46c16204620074 to your computer and use it in GitHub Desktop.
Save scottt/c568b5cacdff8f2e9b46c16204620074 to your computer and use it in GitHub Desktop.
#ifndef __x86_64__
#error "This code only works on x86-64."
#endif
#define _GNU_SOURCE
#include <unistd.h>
#include <assert.h>
#ifndef __x86_64__
#error "This code only works on x86-64."
#endif
#define _GNU_SOURCE
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ucontext.h>
/* Define 'c' as a global register variable
https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html */
register char *c __asm__("r12");
void sighandler(int signumber, siginfo_t *sinfo, void *ucontext) {
ucontext_t *context = ucontext;
printf("got a signal %d(%s)'\n", signumber,
sys_siglist[signumber]);
/* NOTE: assigning to 'c' instead of 'REG_R12' likely won't work on most systems
due to register content restoration after a signal handler returns */
context->uc_mcontext.gregs[REG_R12] = (long)malloc(sizeof(char));
}
__attribute__((optimize("Os")))
int main(int argc, char **argv) {
int r;
struct sigaction sa = { {0} };
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = sighandler;
r = sigaction(SIGSEGV, &sa, NULL);
assert(r == 0);
*c = '0'; /*segmentation fault*/
printf("my pid is %d\n", getpid());
printf("press any key to resume\n");
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment