forked from capablevms/cheri-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stackscan.c
148 lines (126 loc) · 2.51 KB
/
stackscan.c
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "include/common.h"
#include <setjmp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
void *csp;
void *stack_top;
void inspect_stack(void *stack)
{
printf("offset: %lu\n", cheri_length_get(stack) - cheri_offset_get(stack));
}
bool is_stack_pointer(void *ptr)
{
if (cheri_is_valid(ptr))
{
uint64_t base = cheri_base_get(stack_top);
uint64_t length = cheri_length_get(stack_top);
uint64_t address = cheri_address_get(ptr);
if (address >= base && address <= (base + length))
{
return true;
}
}
return false;
}
bool is_pointer(void *ptr)
{
if (cheri_is_valid(ptr))
{
return true;
}
return false;
}
bool is_exec(void *ptr)
{
if (((cheri_perms_get(ptr) & 0b10) >> 1) == 1)
{
return true;
}
return false;
}
void scan_range(void *start, void *end)
{
void **location = (void **)start;
puts("Scanning range: ");
inspect_pointer(start);
inspect_pointer(end);
puts("\n");
while (location > end)
{
if (is_pointer(*location))
{
if (is_stack_pointer(*location))
{
printf("[Stack Pointer] ");
}
if (is_exec(*location))
{
printf("[Executable] ");
}
inspect_pointer(*location);
}
location -= 1;
}
}
void scan_frames()
{
// We dont's scan the part of the stack taken by the current function
// I promise the collect function doesn't allocate
void *stack_bot = __builtin_frame_address(0);
void *previous_frame = *(void **)stack_bot;
inspect_stack(stack_bot);
inspect_stack(previous_frame);
while (previous_frame < stack_top)
{
void **next_frame = (void **)previous_frame;
if (!is_stack_pointer(*next_frame))
{
printf("Couldn't find a stack pointer at: %p, looking up the stack", next_frame);
}
while (!is_stack_pointer(*next_frame))
{
printf("doesn't contain a stack pointer: ");
inspect_stack(next_frame);
next_frame -= 1;
}
scan_range(*next_frame, previous_frame);
previous_frame = *next_frame;
printf(" ======= ");
inspect_stack(previous_frame);
}
}
void scan_all()
{
void *stack_bot = __builtin_frame_address(0);
scan_range(stack_top, stack_bot);
}
int test_2()
{
scan_all();
return 99;
}
int test_3()
{
return test_2();
}
uint32_t *test()
{
uint32_t *values = (uint32_t *)malloc((size_t)test_3());
values[0] = 42;
values[1] = 42;
return values;
}
int main()
{
stack_top = __builtin_frame_address(0);
uint64_t base = cheri_base_get(csp);
uint64_t length = cheri_length_get(csp);
uint32_t *values = test();
for (int idx = 0; idx <= 1; idx++)
{
printf("Value: %d\n", values[idx]);
}
scan_all();
return 0;
}