forked from cfanatic/vsomeip-fuzzing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuzzing.cpp
173 lines (148 loc) · 6.31 KB
/
fuzzing.cpp
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <thread>
#include <vsomeip/vsomeip.hpp>
#include <vsomeip/internal/logger.hpp>
#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_METHOD_ID 0x0421
#define SAMPLE_INSTANCE_ID 0x5678
std::shared_ptr<vsomeip::application> app_service;
std::shared_ptr<vsomeip::application> app_client;
std::mutex mutex;
std::condition_variable condition;
std::string afl_input;
// ---- Crash ------------------------------------------------------------------------------------------------
void crash_thread(std::string &payload)
{
std::vector<std::string> v = {"Hello", "hullo", "hell"};
if (std::find(v.begin(), v.end(), payload) != v.end())
{
*(int *)0 = 0; // crash: null pointers cannot be dereferenced to a value
}
}
// ---- Service ----------------------------------------------------------------------------------------------
void on_message_service(const std::shared_ptr<vsomeip::message> &_request)
{
std::string str_payload;
str_payload.append(reinterpret_cast<const char *>(_request->get_payload()->get_data()), 0, _request->get_payload()->get_length());
VSOMEIP_INFO << "--SERVICE-- Received message with Client/Session ["
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
<< str_payload;
#ifdef CRASH_SERVICE
crash_thread(str_payload);
#endif
VSOMEIP_INFO << "--SERVICE-- Sending message back to Client";
std::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()->create_response(_request);
std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()->create_payload();
std::vector<vsomeip::byte_t> its_payload_data(std::begin(str_payload), std::end(str_payload));
its_payload->set_data(its_payload_data);
its_response->set_payload(its_payload);
app_service->send(its_response);
#ifdef CRASH_LIBRARY
VSOMEIP_FATAL << str_payload; // trigger crash in instrumented vsomeip/implementation/logger/src/message.cpp
#endif
}
void start_service()
{
app_service = vsomeip::runtime::get()->create_application("!!SERVICE!!");
app_service->init();
app_service->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message_service);
app_service->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_service->start();
}
// ---- Client -----------------------------------------------------------------------------------------------
void send_message_client()
{
VSOMEIP_INFO << "--CLIENT-- Sending message to Service";
std::shared_ptr<vsomeip::message> request = vsomeip::runtime::get()->create_request();
request->set_service(SAMPLE_SERVICE_ID);
request->set_instance(SAMPLE_INSTANCE_ID);
request->set_method(SAMPLE_METHOD_ID);
VSOMEIP_FATAL << "AFL: " << afl_input; // VSOMEIP_FATAL is used as a workaround to reduce the log file size
std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()->create_payload();
std::vector<vsomeip::byte_t> its_payload_data(std::begin(afl_input), std::end(afl_input));
its_payload->set_data(its_payload_data);
request->set_payload(its_payload);
app_client->send(request);
}
void on_message_client(const std::shared_ptr<vsomeip::message> &_response)
{
std::string str_payload;
str_payload.append(reinterpret_cast<const char *>(_response->get_payload()->get_data()), 0, _response->get_payload()->get_length());
VSOMEIP_INFO << "--CLIENT-- Received message with Client/Session ["
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_session() << "] "
<< str_payload;
#ifdef CRASH_CLIENT
crash_thread(str_payload);
#endif
}
void on_availability_client(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available)
{
VSOMEIP_INFO << "--CLIENT-- Service ["
<< std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance
<< "] is "
<< (_is_available ? "available." : "NOT available.");
if (_is_available == true)
{
condition.notify_one();
}
}
void start_client()
{
app_client = vsomeip::runtime::get()->create_application("!!CLIENT!!");
app_client->init();
app_client->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability_client);
app_client->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_client->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message_client);
app_client->start();
}
// ---- Target for Fuzzing -----------------------------------------------------------------------------------
void fuzzing_target(std::string &input)
{
afl_input = input;
std::thread service(start_service);
std::thread client(start_client);
std::unique_lock<std::mutex> its_lock(mutex);
condition.wait(its_lock); // wait until the Service is available
std::thread sender(send_message_client);
sender.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait until the Client has received the response from the Service
app_client->clear_all_handler();
app_client->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_client->stop();
client.join();
app_service->clear_all_handler();
app_service->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_service->stop();
service.join();
}
// ---- Main -------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
char chr;
std::ifstream file;
std::string input;
std::stringstream buffer;
#ifndef COMPILE_WITH_GCC
while (__AFL_LOOP(1000)) // macro unknown for gcc compilers
{
#endif
file.open(argv[1]);
buffer.str("");
buffer << file.rdbuf();
input = buffer.str();
input.erase(std::remove(input.begin(), input.end(), '\n'), input.end());
fuzzing_target(input);
file.close();
#ifndef COMPILE_WITH_GCC
}
#endif
}