Last active
December 17, 2015 08:26
-
-
Save phoeagon/6b1cadfa885da29a97fb to your computer and use it in GitHub Desktop.
Test whether memory can be accessed
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
#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