Skip to content

Instantly share code, notes, and snippets.

@phoeagon
Last active December 17, 2015 08:26
Show Gist options
  • Save phoeagon/6b1cadfa885da29a97fb to your computer and use it in GitHub Desktop.
Save phoeagon/6b1cadfa885da29a97fb to your computer and use it in GitHub Desktop.
Test whether memory can be accessed
#define _GNU_SOURCE
#include <stdio.h>
#include <udis86.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ucontext.h>
#include <execinfo.h>
#include <setjmp.h>
sighandler_t * _ptr = (sighandler_t*) NULL;
jmp_buf _buf;
void _fuckit_seghandle_userspace() {
longjmp(&_buf, 1);
}
void _fuckit_seghandle(int sig, siginfo_t* si, void* unused) {
ucontext_t* uc = (ucontext_t*) unused;
greg_t * gregs = uc->uc_mcontext.gregs;
gregs[REG_RIP] = &_fuckit_seghandle_userspace;
}
void _fuckcpp_setup_segfault_handler(int reset) {
struct sigaction sa, osa;
sa.sa_flags = SA_SIGINFO;
sigemptyset (&sa.sa_mask);
if (!reset)
sa.sa_sigaction = &_fuckit_seghandle;
else
sa.sa_sigaction = _ptr;
sigaction(SIGSEGV, &sa, &osa);
_ptr = osa.sa_sigaction;
}
int _real_check(char* addr, size_t size, int wr, void* buf) {
memcpy(buf, addr, size);
if (wr)
memcpy(addr, buf, size);
}
int can_access_mem(void* addr, size_t size, int wr) {
#define LIM (64)
char buf[size<=LIM ? size : LIM];
if (!setjmp(&_buf)) {
_fuckcpp_setup_segfault_handler(0);
volatile char * p = (char*)addr;
ssize_t remain = size;
while ( remain > 0 && ((int)addr & ~LIM) ) { // align first
_real_check(addr, 1, wr, buf);
remain --;
addr ++;
}
for (; remain > 0; remain -= LIM) {
_real_check(addr, rename<=LIM ? rename : LIM, wr, buf);
addr += LIM;
}
_fuckcpp_setup_segfault_handler(1);
return 1;
} else {
_fuckcpp_setup_segfault_handler(1);
return 0;
}
}
#define CAN_ACCESS_T(TYPE, x) (can_access_mem((x), sizeof(TYPE), 0))
#define CAN_WRITE_T(TYPE, x) (can_access_mem((x), sizeof(TYPE), 1))
#define CAN_ACCESS(x) (can_access_mem((x), sizeof(x), 0))
#define CAN_WRITE(x) (can_access_mem((x), sizeof(x),1))
int main()
{
int a;
printf("can read %p: %d\n", &main, can_access_mem(&main, 10, 0));
printf("can write %p: %d\n", &main, can_access_mem(&main, 10, 1));
printf("can write %p: %d\n", &a, CAN_WRITE(&a));
printf("can write %p: %d\n", a, CAN_WRITE(a));
printf("can write %p: %d\n", 543124, CAN_WRITE_T(void*, 543124));
printf("can write %p: %d\n", 0, can_access_mem(0, 4, 1));
printf("can read %p: %d\n", 18446744073699065856, can_access_mem(18446744073699065856, 4096, 0));
printf("can write %p: %d\n", 18446744073699065856, can_access_mem(18446744073699065856, 4096, 1));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment