Skip to content

Instantly share code, notes, and snippets.

@MawKKe
Last active July 7, 2024 11:01
Show Gist options
  • Save MawKKe/aab031708929108d1796a2a46ad4450b to your computer and use it in GitHub Desktop.
Save MawKKe/aab031708929108d1796a2a46ad4450b to your computer and use it in GitHub Desktop.
Got a segmentation fault due to null pointer dereferencing? No worry, just skip over it #yolo
// build and run with:
// $ gcc nullptr-shenanigans.c -Wall -Wextra -pedantic -std=c99 -O0 -o lol
// $ ./lol
// expected output:
// Got SIGSEGV at address: 0x0 (REG_RIP = 93937079497465)
// This should not print: p = (nil)?
// Allright then, we are done!
#define _GNU_SOURCE 1 /* To pick up REG_RIP */
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
static void handler(int signo, siginfo_t *info, void *context)
{
(void)signo;
ucontext_t * ctx = (ucontext_t *)context;
printf("Got SIGSEGV at address: 0x%lx (REG_RIP = %lld)\n",
(long) info->si_addr,
ctx->uc_mcontext.gregs[REG_RIP]);
// Let's just adjust the instruction pointer and skip over the offending instructions *shrug*
// You may need to adjust the offset based on your architecture ('6' works on x86_64).
// Also, using any other optimization beyond -O0 level will break this
ctx->uc_mcontext.gregs[REG_RIP] += 6;
}
int main(){
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1){
perror("sigaction");
abort();
}
int * p = NULL;
*p = 11; // HUH??
printf("This should not print: p = %p?\n", (void*)p);
printf("Allright then, we are done!\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment