Skip to content

Commit d16f1d8

Browse files
committed
bdshemu_fuzz: Update build scripts
1 parent 3beaac8 commit d16f1d8

File tree

4 files changed

+107
-187
lines changed

4 files changed

+107
-187
lines changed

CMakeLists.txt

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16)
22

33
option(BDD_INCLUDE_TOOL "Include the disasmtool executable" ON)
44
option(BDD_INCLUDE_ISAGENERATOR "Include the isagenerator target (if a python interpreter is found)" ON)
5+
option(BDD_INCLUDE_FUZZERS "Include the bdshemu fuzzer" OFF)
56
option(BDD_USE_EXTERNAL_VSNPRINTF "Expect nd_vsnprintf_s implementation from the integrator" OFF)
67
option(BDD_USE_EXTERNAL_MEMSET "Expect nd_memset implementation from the integrator" OFF)
78

@@ -54,9 +55,7 @@ else ()
5455
-Wno-unused-function
5556
-Wno-multichar
5657
-Wno-incompatible-pointer-types
57-
-Wno-discarded-qualifiers
5858
-Wnull-dereference
59-
-Wduplicated-cond
6059
-Werror=format-security
6160
-Werror=implicit-function-declaration
6261
-pipe
@@ -70,6 +69,12 @@ else ()
7069
-gdwarf-4
7170
-grecord-gcc-switches
7271
-march=westmere)
72+
73+
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
74+
list(APPEND BDDISASM_COMMON_COMPILE_OPTIONS
75+
-Wduplicated-cond
76+
-Wno-discarded-qualifiers)
77+
endif ()
7378
endif ()
7479

7580
set(BDDISASM_PUBLIC_HEADERS
@@ -200,6 +205,11 @@ if ((${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) AND BDD_INCLUDE_ISAGENERATO
200205
add_subdirectory(isagenerator)
201206
endif ()
202207

208+
# If this is the master project (and if the user requested it) add the fuzzer.
209+
if ((${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) AND BDD_INCLUDE_FUZZERS)
210+
add_subdirectory(bdshemu_fuzz)
211+
endif ()
212+
203213
# If this is the master project add install and package targets.
204214
if (${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
205215
set(BDDISASM_INSTALL_CMAKEDIR

bdshemu_fuzz/CMakeLists.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
option(BDD_FUZZ_WITH_LOGS "Enable logging for the fuzzer" OFF)
4+
5+
project(bdshemu_fuzzer LANGUAGES C)
6+
7+
add_executable(shfuzzx86 bdshemu_fuzzer.c)
8+
target_link_libraries(shfuzzx86 PRIVATE bddisasm::bdshemu)
9+
target_compile_definitions(shfuzzx86 PRIVATE FUZZ_X86)
10+
11+
add_executable(shfuzzx64 bdshemu_fuzzer.c)
12+
target_link_libraries(shfuzzx64 PRIVATE bddisasm::bdshemu)
13+
target_compile_definitions(shfuzzx64 PRIVATE FUZZ_X64)
14+
15+
if (BDD_FUZZ_WITH_LOGS)
16+
target_compile_definitions(shfuzzx86 PRIVATE ENABLE_LOGGING)
17+
target_compile_definitions(shfuzzx64 PRIVATE ENABLE_LOGGING)
18+
endif (BDD_FUZZ_WITH_LOGS)
19+
20+
add_custom_target(shfuzz DEPENDS shfuzzx86 shfuzzx64)

bdshemu_fuzz/Makefile

-73
This file was deleted.

bdshemu_fuzz/bdshemu_fuzzer.c

+75-112
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,43 @@
22
* Copyright (c) 2020 Bitdefender
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5+
#ifdef _MSC_VER
56
#define _CRT_SECURE_NO_WARNINGS
7+
#endif
68

9+
#include <limits.h>
710
#include <stdarg.h>
11+
#include <stdbool.h>
812
#include <stdio.h>
13+
#include <stdint.h>
914
#include <stdlib.h>
1015
#include <string.h>
11-
#include <stdint.h>
12-
#include <stdbool.h>
1316
#include "bddisasm.h"
1417
#include "bdshemu.h"
1518

19+
#pragma clang optimize off
20+
#pragma GCC optimize("O0")
21+
1622
#ifdef ENABLE_LOGGING
1723
#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
1824
#else
1925
#define LOG(fmt, ...)
2026
#endif // ENABLE_LOGGING
2127

22-
#ifndef __AFL_LOOP
23-
#warning "Persistent mode will not work (you are probably not using afl-clang-fast)"
24-
#endif
25-
26-
int nd_vsnprintf_s(
27-
char *buffer,
28-
size_t sizeOfBuffer,
29-
size_t count,
30-
const char *format,
31-
va_list argptr
32-
)
33-
{
34-
return vsnprintf(buffer, sizeOfBuffer, format, argptr);
35-
}
36-
37-
void *nd_memset(void *s, int c, size_t n)
38-
{
39-
return memset(s, c, n);
40-
}
41-
42-
uint8_t *read_file(const char *fpath, size_t *size)
43-
{
44-
uint8_t *buffer;
45-
FILE *fd = fopen(fpath, "rb");
46-
if (fd == NULL)
47-
{
48-
LOG("[-] Failed to open \"%s\"\n", fpath);
49-
return NULL;
50-
}
51-
52-
fseek(fd, 0ull, SEEK_END);
53-
*size = ftell(fd);
54-
rewind(fd);
55-
56-
buffer = malloc(*size);
57-
if (buffer == NULL)
58-
{
59-
LOG("[-] Failed to allocate %zu bytes\n", *size);
60-
}
61-
else
62-
{
63-
fread(buffer, *size, 1, fd);
64-
}
65-
66-
fclose(fd);
67-
return buffer;
68-
}
69-
70-
static bool gUseLog;
71-
7228
void ShemuLog(char *data)
7329
{
74-
if (gUseLog)
75-
{
76-
LOG("%s", data);
77-
}
30+
LOG("%s", data);
7831
}
7932

80-
void run_shemu(uint8_t *Data, size_t Size, uint8_t Def)
33+
#ifdef FUZZ_X86
34+
#define DEF_CODE ND_CODE_32
35+
#define FUZZER_TYPE "x86"
36+
#else
37+
#define DEF_CODE ND_CODE_64
38+
#define FUZZER_TYPE "x64"
39+
#endif // FUZZ_X86
40+
41+
void run_shemu(uint8_t *Data, size_t Size)
8142
{
8243
// More or less copy pasted from disasmtool
8344

@@ -119,7 +80,7 @@ void run_shemu(uint8_t *Data, size_t Size, uint8_t Def)
11980
ctx.Segments.Gs.Selector = 0x30;
12081
ctx.Segments.Gs.Base = 0x7FFF0000;
12182

122-
ctx.Mode = Def;
83+
ctx.Mode = DEF_CODE;
12384
ctx.Ring = 3;
12485
ctx.TibBase = ctx.Mode == ND_CODE_32 ? ctx.Segments.Fs.Base : ctx.Segments.Gs.Base;
12586
ctx.MaxInstructionsCount = 4096;
@@ -134,85 +95,87 @@ void run_shemu(uint8_t *Data, size_t Size, uint8_t Def)
13495
free(ctx.Stack);
13596
}
13697

137-
void run_test(uint8_t *Data, size_t Size, uint8_t Def)
138-
{
139-
run_shemu(Data, Size, Def);
140-
}
98+
#if defined(__AFL_FUZZ_TESTCASE_LEN)
99+
#include <unistd.h>
100+
101+
// See https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md
102+
__AFL_FUZZ_INIT();
141103

142-
int8_t arch_to_def_code(const char *arch)
104+
int main()
143105
{
144-
uint32_t a = strtoul(arch, NULL, 0);
106+
__AFL_INIT();
145107

146-
switch (a)
108+
uint8_t *buffer = __AFL_FUZZ_TESTCASE_BUF;
109+
while (__AFL_LOOP(UINT_MAX))
147110
{
148-
case 16:
149-
return ND_CODE_16;
111+
size_t size = __AFL_FUZZ_TESTCASE_LEN;
112+
run_shemu(buffer, size);
113+
}
150114

151-
case 32:
152-
return ND_CODE_32;
115+
return 0;
116+
}
117+
#elif defined(__clang__)
118+
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
119+
{
120+
// Shemu will write into the shellcode buffer, so copy it to a new buffer first.
153121

154-
case 64:
155-
return ND_CODE_64;
122+
uint8_t *buffer = malloc(Size);
123+
if (!buffer) return 1;
156124

157-
default:
158-
LOG("[-] Unknown arch: \"%s\"\n", arch);
159-
return -1;
160-
}
161-
}
125+
memcpy(buffer, Data, Size);
126+
run_shemu(buffer, Size);
162127

163-
int main(int argc, char **argv)
128+
free(buffer);
129+
return 0;
130+
}
131+
#else
132+
uint8_t *read_file(const char *fpath, size_t *size)
164133
{
165-
size_t size = 0;
166134
uint8_t *buffer;
167-
int8_t defCode;
168-
169-
if (argc < 3)
135+
FILE *fd = fopen(fpath, "rb");
136+
if (fd == NULL)
170137
{
171-
LOG("[-] Missing arguments: <file path> <16|32|64> [activate shemu print]\n");
172-
abort();
138+
LOG("[-] Failed to open \"%s\"\n", fpath);
139+
return NULL;
173140
}
174141

175-
defCode = arch_to_def_code(argv[2]);
176-
if (defCode == -1)
177-
{
178-
abort();
179-
}
142+
fseek(fd, 0ull, SEEK_END);
143+
*size = ftell(fd);
144+
rewind(fd);
180145

181-
if (argc >= 4)
146+
buffer = malloc(*size);
147+
if (buffer == NULL)
182148
{
183-
LOG("[+] Will activate ShemuLog\n");
184-
gUseLog = true;
149+
LOG("[-] Failed to allocate %zu bytes\n", *size);
185150
}
186151
else
187152
{
188-
gUseLog = false;
153+
fread(buffer, *size, 1, fd);
189154
}
190155

191-
LOG("[+] Using def code/data = %d\n", defCode);
156+
fclose(fd);
157+
return buffer;
158+
}
192159

193-
// __AFL_LOOP is defined only when compiling with afl-clang-fast and allows us to use
194-
// AFL's persistent mode. We still want to be able to compile and run even if we are
195-
// using afl-gcc or afl-clang, but there is no reason to actually have a loop here
196-
// if we are not using persistent mode.
197-
#ifdef __AFL_LOOP
198-
while (__AFL_LOOP(1000))
199-
#endif // __AFL_LOOP
160+
int main(int argc, char **argv)
161+
{
162+
if (argc < 2)
200163
{
201-
LOG("[+] Reading data from \"%s\"\n", argv[1]);
202-
buffer = read_file(argv[1], &size);
203-
if (buffer == NULL)
204-
{
205-
abort();
206-
}
207-
208-
LOG("[+] Read %zu bytes at %p (range: [%p, %p))\n", size, buffer, buffer, buffer + size);
209-
210-
run_test(buffer, size, (uint8_t)defCode);
164+
LOG("Missing file argument\n");
165+
abort();
166+
}
211167

212-
free(buffer);
168+
size_t size;
169+
uint8_t *buffer = read_file(argv[1], &size);
170+
if (!buffer)
171+
{
172+
LOG("[-] read_file failed for \"%s\"\n", argv[1]);
173+
abort();
213174
}
214175

215-
LOG("[+] Done!\n");
176+
run_shemu(buffer, size);
177+
free(buffer);
216178

217179
return 0;
218180
}
181+
#endif // defined(__AFL_FUZZ_TESTCASE_LEN)

0 commit comments

Comments
 (0)