Created
February 8, 2017 06:54
-
-
Save lazear/309c92e5e3ddbb271e6bc31d07057663 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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