about summary refs log tree commit diff stats
path: root/tests/test21.c
blob: 09bae72ace3adaddd707b660d3aec1ec2c05e7d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#define __USE_GNU
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

static jmp_buf context_buf;

static void segv_handler(int sig)
{
	printf("sig = %d\n", sig);
	siglongjmp(context_buf, 1);
}

void test()
{
	if(!setjmp(context_buf)) {
		int *bad_ptr = (int*)0xffffffffdeadbeef;
		printf("*bad_ptr = %d\n", *bad_ptr);
	} else {
		printf("got bad_ptr\n");
	}
}

void* exec_p = NULL;
typedef void(*vFv_t)(void);
#define X_IP		16
#define X_TRAPNO 	20
#define X_ERR		19
static void segv_action(int sig, siginfo_t* info, ucontext_t* ucntx)
{
	printf("sig = %d\n", sig);
	printf("si_addr: %zx, si_code: %d, si_errno: %d, RIP offset: %zd, TRAPERR=%d TRAPNO=%d\n", 
		info->si_addr,
		info->si_code,
		info->si_errno,
		((intptr_t)ucntx->uc_mcontext.gregs[X_IP])-((intptr_t)exec_p),
		ucntx->uc_mcontext.gregs[X_ERR],
		ucntx->uc_mcontext.gregs[X_TRAPNO]
	);
	siglongjmp(context_buf, 1);
}

static unsigned char buff_cc[] = { 0xcc, 0xc3 };
static unsigned char buff_cd03[] = { 0xcd, 0x03, 0xc3 };
static unsigned char buff_cd2d[] = { 0xcd, 0x2d, 0xc3 };
void test_cc()
{
	memcpy(exec_p, buff_cc, sizeof(buff_cc));
	if(!setjmp(context_buf)) {
		vFv_t f = (vFv_t)exec_p;
		f();
	}
	memcpy(exec_p, buff_cd03, sizeof(buff_cd03));
	if(!setjmp(context_buf)) {
		vFv_t f = (vFv_t)exec_p;
		f();
	}
	/*memcpy(exec_p, buff_cd2d, sizeof(buff_cd2d));
	if(!setjmp(context_buf)) {
		vFv_t f = (vFv_t)exec_p;
		f();
	}*/
}

int main()
{
	if(signal(SIGSEGV, segv_handler) == SIG_ERR) {
		printf("signal: Err = %d\n", errno);
		return -1;
	}
	//printf("handler = %p\n", segv_handler);
	test();
    struct sigaction action = {0};
    action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
    action.sa_sigaction = segv_action;
    if(sigaction(SIGSEGV, &action, NULL)) {
		printf("sigaction: Err = %d\n", errno);
		return -2;
	}
    if(sigaction(SIGTRAP, &action, NULL)) {
		printf("sigaction 2: Err = %d\n", errno);
		return -2;
	}
	exec_p = mmap(NULL, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
	if(exec_p==MAP_FAILED) {
		printf("mmap: Err = %d\n", errno);
		return -3;
	}
	test_cc();
	return 0;
}