Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <sys/types.h>
- #include <ucontext.h>
- #include <pthread.h>
- #include <signal.h>
- #include <stdio.h>
- static void hello(void)
- {
- printf("hello, signal\n");
- }
- static void trampoline(void)
- {
- printf("trampoline\n");
- }
- static void sigsegv_handler(int sig, siginfo_t *si, void *ctx)
- {
- ucontext_t *uc = ctx;
- unsigned long prev_rip;
- unsigned long *rsp;
- prev_rip = uc->uc_mcontext.gregs[REG_RIP];
- rsp = (void *) uc->uc_mcontext.gregs[REG_RSP];
- *(--rsp) = (unsigned long) hello;
- printf("rsp=%p, ctx=%p\n", rsp, ctx);
- uc->uc_mcontext.gregs[REG_RSP] = (unsigned long) rsp;
- uc->uc_mcontext.gregs[REG_RIP] = (unsigned long) trampoline;
- }
- void touch_stack(void)
- {
- char array[4096];
- int i;
- for (i = 0; i < sizeof(array); i++) {
- array[i] = 0xff;
- }
- printf("%p\n", array+i);
- }
- static void make_kill(void)
- {
- char use_some_stack[8];
- use_some_stack[0] = 0xff;
- if (kill(0, SIGSEGV) < 0)
- perror("kill");
- }
- void setup(void)
- {
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART | SA_SIGINFO;
- sa.sa_sigaction = sigsegv_handler;
- sigaction(SIGSEGV, &sa, NULL);
- }
- static void *start_thread(void *arg)
- {
- for (;;) {
- make_kill();
- printf("main\n");
- touch_stack();
- }
- return NULL;
- }
- int main(int argc, char *argv[])
- {
- pthread_t id;
- setup();
- if (pthread_create(&id, NULL, start_thread, NULL) != 0)
- perror("pthread_create");
- if (pthread_join(id, NULL) != 0)
- perror("pthread_join");
- return 0;
- }
Add Comment
Please, Sign In to add comment