blob: 84d4bbf3257fad9f4e65a9aa8e36d9fb18ad7947 (
plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <assert.h>
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using std::ofstream;
using std::ifstream;
using std::ios;
struct A {
A():value(123) {}
int value;
virtual int access() { return this->value; }
};
struct B {
B():value(456) {}
int value;
virtual int access() { return this->value; }
};
struct C : public A, public B {
C():better_value(789) {}
int better_value;
virtual int access() { return this->better_value; }
};
struct D: public C {
D():other_value(987) {}
int other_value;
virtual int access() { return this->other_value; }
};
volatile static int signal_count = 0;
sigjmp_buf before_segv;
static void
handler(int sig, siginfo_t *si, void *unused)
{
/*
printf("Got SIGSEGV at address: 0x%lx\n",
(long) si->si_addr);
*/
signal_count++;
/* You are not supposed to longjmp out of a signal handler but it seems
to work for this test case and it simplifies it */
siglongjmp(before_segv, 1);
/* exit(1); */
}
/* Access one of the vtable_map variables generated by this .o */
extern void * _ZN4_VTVI1BE12__vtable_mapE;
/* Access one of the vtable_map variables generated by libstdc++ */
extern void * _ZN4_VTVISt8ios_baseE12__vtable_mapE;
int use(B *b)
{
int ret;
ret = sigsetjmp(before_segv, 1);
if (ret == 0)
{
/* This should generate a segmentation violation. ie: at this point it should
be protected */
_ZN4_VTVI1BE12__vtable_mapE = 0;
}
assert(ret == 1 && signal_count == 1);
ret = sigsetjmp(before_segv, 1);
if (ret == 0)
{
/* Try to modify one of the vtable_map variables in the stdc++ library.
This should generate a segmentation violation. ie: at this point it
should be protected */
_ZN4_VTVISt8ios_baseE12__vtable_mapE = 0;
}
assert(ret == 1 && signal_count == 2);
return b->access();
}
void myread(std::istream * in)
{
char input_str[50] = "\0";
if (in->good())
(*in) >> input_str;
std::cout << input_str << std::endl;
delete in;
}
int main()
{
ifstream * infile = new ifstream("./thunk_vtable_map_attack.cpp");
myread(infile);
/* Set up handler for SIGSEGV. */
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
assert(0);
C c;
assert(use(&c) == 789);
return 0;
}
|