Skip to content

Instantly share code, notes, and snippets.

@lazear
Created February 8, 2017 06:54
Show Gist options
  • Save lazear/309c92e5e3ddbb271e6bc31d07057663 to your computer and use it in GitHub Desktop.
Save lazear/309c92e5e3ddbb271e6bc31d07057663 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/mman.h>
/**
* Stack layout as proposed in http://www.cs.indiana.edu/~dyb/pubs/stack.pdf
* [rbp + ...] = pointer to base of stack segment?
* [rbp + ...] = pointer to next stack record?
* [rbp + ...] = stack parameters
* [rbp + 16] = size of stack segment
* [rbp + 8] = return address for upper frame
* [rbp + 0] = RBP (from push rbp \n mov rbp, rsp)
*
In our model,
the frame pointer is adjusted just prior to a procedure
call to point to the new frame, and is adjusted after the
called routine returns to point back to the old frame. In
order for this to work, the frame pointer must still (or
again) point to the called routine’s frame on return. The
compiler generating code for the calling procedure must
keep track of the displacement between the start of the
calling procedure’s frame and the start of the called procedure’s
frame in order to adjust the frame pointer both
before and after the call. In both cases, the adjustment
is performed by a single instruction to add (subtract)
the displacement to (from) the frame pointer.
*/
void segfault(int signal, siginfo_t* si, void* arg)
{
/* This is POSIX non-compliant... but whatever */
printf("caught segfault %p\n", si->si_addr);
exit(0);
}
int main(int argc, char** argv)
{
/* Install segmentation fault handler */
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = segfault;
sa.sa_flags = SA_SIGINFO;
if(sigaction(SIGSEGV, &sa, NULL)) {
fprintf(stderr, "Fatal error - could not install signal handler\n");
exit(0);
}
/* Request mapping for a stack, RW privileges */
void* addr = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if (addr == MAP_FAILED) {
fprintf(stderr, "Fatal error - memory mapping failed\n");
exit(0);
}
printf("mmap gave up %p\n", addr);
int* ptr =addr;
*(ptr-1) = 12;
munmap(addr, 0x10000);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment