forked from AFLplusplus/AFLplusplus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example.c
141 lines (111 loc) · 5.23 KB
/
example.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
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <inttypes.h>
#include "nyx.h"
#define TRACE_BUFFER_SIZE (64)
#define PAGE_SIZE 0x1000
#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE - 1)) + PAGE_SIZE)
int main(int argc, char **argv) {
/* if you want to debug code running in Nyx, hprintf() is the way to go.
* Long story short -- it's just a guest-to-hypervisor printf. Hence the name
* "hprintf"
*/
hprintf("Agent test\n");
/* Request information on available (host) capabilites (optional) */
host_config_t host_config;
kAFL_hypercall(HYPERCALL_KAFL_GET_HOST_CONFIG, (uintptr_t)&host_config);
hprintf("[capablities] host_config.bitmap_size: 0x%" PRIx64 "\n",
host_config.bitmap_size);
hprintf("[capablities] host_config.ijon_bitmap_size: 0x%" PRIx64 "\n",
host_config.ijon_bitmap_size);
hprintf("[capablities] host_config.payload_buffer_size: 0x%" PRIx64 "x\n",
host_config.payload_buffer_size);
/* this is our "bitmap" that is later shared with the fuzzer (you can also
* pass the pointer of the bitmap used by compile-time instrumentations in
* your target) */
uint8_t *trace_buffer =
mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memset(trace_buffer, 0,
TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already
// mapped into the guest's memory (alternatively
// you can use mlock) */
/* Submit agent configuration */
agent_config_t agent_config = {0};
agent_config.agent_magic = NYX_AGENT_MAGIC;
agent_config.agent_version = NYX_AGENT_VERSION;
agent_config.agent_timeout_detection =
0; /* timeout detection is implemented by the agent (currently not used)
*/
agent_config.agent_tracing =
1; /* set this flag to propagade that instrumentation-based fuzzing is
availabe */
agent_config.agent_ijon_tracing = 0; /* set this flag to propagade that IJON
extension is implmented agent-wise */
agent_config.trace_buffer_vaddr =
(uintptr_t)trace_buffer; /* trace "bitmap" pointer - required for
instrumentation-only fuzzing */
agent_config.ijon_trace_buffer_vaddr =
(uintptr_t)NULL; /* "IJON" buffer pointer */
agent_config.agent_non_reload_mode =
1; /* non-reload mode is supported (usually because the agent implements a
fork-server; currently not used) */
agent_config.coverage_bitmap_size = TRACE_BUFFER_SIZE;
kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
/* Tell hypervisor the virtual address of the payload (input) buffer (call
* mlock to ensure that this buffer stays in the guest's memory)*/
kAFL_payload *payload_buffer =
mmap(NULL, host_config.payload_buffer_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
mlock(payload_buffer, (size_t)host_config.payload_buffer_size);
memset(payload_buffer, 0, host_config.payload_buffer_size);
kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
/* the main fuzzing loop */
while (1) {
/* Creates a root snapshot on first execution. Also we requested the next
* input with this hypercall */
kAFL_hypercall(HYPERCALL_KAFL_USER_FAST_ACQUIRE, 0); // root snapshot <--
#ifdef DEBUG
hprintf("Size: %ld Data: %x %x %x %x\n", payload_buffer->size,
payload_buffer->data[4], payload_buffer->data[5],
payload_buffer->data[6], payload_buffer->data[7]);
#endif
uint32_t len = payload_buffer->size;
/* set a byte to make AFL++ happy (otherwise the fuzzer might refuse to
* start fuzzing at all) */
((uint8_t *)trace_buffer)[0] = 0x1;
if (len >= 4) {
/* set a byte in the bitmap to guide your fuzzer */
((uint8_t *)trace_buffer)[0] = 0x1;
if (payload_buffer->data[0] == '!') {
((uint8_t *)trace_buffer)[1] = 0x1;
if (payload_buffer->data[1] == 'N') {
((uint8_t *)trace_buffer)[2] = 0x1;
if (payload_buffer->data[2] == 'Y') {
((uint8_t *)trace_buffer)[3] = 0x1;
if (payload_buffer->data[3] == 'X') {
((uint8_t *)trace_buffer)[4] = 0x1;
/* Notifiy the hypervisor and the fuzzer that a "crash" has
* occured. Also a string is passed by this hypercall (this is
* currently not supported by AFL++-Nyx) */
kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED,
(uintptr_t) "Something went wrong\n");
}
}
}
}
}
/* this hypercall is used to notify the hypervisor and the fuzzer that a
* single fuzzing "execution" has finished. If the reload-mode is enabled,
* we will jump back to our root snapshot. Otherwise, the hypervisor passes
* control back to the guest once the bitmap buffer has been "processed" by
* the fuzzer.
*/
kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
/* This shouldn't happen if you have enabled the reload mode */
hprintf("This should never happen :)\n");
}
return 0;
}