Skip to content

Instantly share code, notes, and snippets.

@mrdomino
Last active September 15, 2023 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrdomino/a1f4a6e8f8e8ecc36d6b to your computer and use it in GitHub Desktop.
Save mrdomino/a1f4a6e8f8e8ecc36d6b to your computer and use it in GitHub Desktop.
compile with -lsigsegv
#include <inttypes.h>
#include <setjmp.h>
#include <signal.h>
#include <sigsegv.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
struct bond {
uintptr_t dof;
uintptr_t mid;
uintptr_t top;
};
volatile enum {
GOING_DOWN,
FOUND_DOF,
GOING_UP,
FOUND_TOP
} dir;
void *progmem = &progmem;
void *page;
static sigjmp_buf seg_buf;
#ifndef SIGSTKSZ
# define SIGSTKSZ 16384
#endif
static uint8_t sig_stk[SIGSTKSZ];
static void
_cont(void* a1, void* a2, void* a3)
{
(void)a1;
(void)a2;
(void)a3;
siglongjmp(seg_buf, 1);
}
static int
_segv(void* addr, int serious)
{
(void)addr;
(void)serious;
++dir;
sigsegv_leave_handler(_cont, 0, 0, 0);
return 1;
}
static void
_over(int emergency, stackoverflow_context_t scp)
{
(void)emergency;
(void)scp;
++dir;
siglongjmp(seg_buf, 1);
}
struct bond
look(void* a)
{
volatile uintptr_t obs;
struct bond ret;
ret.mid = (uintptr_t)a;
dir = GOING_DOWN;
while (sigsetjmp(seg_buf, 1)) {}
for (;;) {
switch (dir) {
case GOING_DOWN:
obs = *(uintptr_t*)a;
a -= sizeof(a);
break;
case FOUND_DOF:
ret.dof = (uintptr_t)a + sizeof(a);
dir = GOING_UP;
a = (void*)ret.mid;
case GOING_UP:
obs = *(uintptr_t*)a;
a += sizeof(a);
break;
case FOUND_TOP:
ret.top = (uintptr_t)a;
return ret;
}
}
}
void
show(const char* nam, struct bond bod)
{
printf("%-8s"
" 0x%016" PRIxPTR
#ifdef SHOW_MID
" 0x%016" PRIxPTR
#endif
" 0x%016" PRIxPTR
"\n"
"%" PRIuPTR
#ifdef SHOW_MID
" (%" PRIuPTR
" %" PRIuPTR ")"
#endif
"\n"
, nam
, bod.dof
#ifdef SHOW_MID
, bod.mid
#endif
, bod.top
, bod.top - bod.dof
#ifdef SHOW_MID
, bod.top - bod.mid
, bod.mid - bod.dof
#endif
);
}
#define LOOK(X) do { \
bod = look(X); \
show(#X ":", bod); \
} while (0)
int
main(){
void *stack;
struct bond bod;
sigsegv_install_handler(&_segv);
stackoverflow_install_handler(&_over, (void*)sig_stk, SIGSTKSZ);
page = malloc(sizeof(page));
*(uintptr_t*)page = (uintptr_t)page;
stack = &stack;
LOOK(stack);
LOOK(progmem);
LOOK(page);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment