2
2
* Copyright (c) 2020 Bitdefender
3
3
* SPDX-License-Identifier: Apache-2.0
4
4
*/
5
+ #ifdef _MSC_VER
5
6
#define _CRT_SECURE_NO_WARNINGS
7
+ #endif
6
8
9
+ #include <limits.h>
7
10
#include <stdarg.h>
11
+ #include <stdbool.h>
8
12
#include <stdio.h>
13
+ #include <stdint.h>
9
14
#include <stdlib.h>
10
15
#include <string.h>
11
- #include <stdint.h>
12
- #include <stdbool.h>
13
16
#include "bddisasm.h"
14
17
#include "bdshemu.h"
15
18
19
+ #pragma clang optimize off
20
+ #pragma GCC optimize("O0")
21
+
16
22
#ifdef ENABLE_LOGGING
17
23
#define LOG (fmt , ...) printf(fmt, ##__VA_ARGS__)
18
24
#else
19
25
#define LOG (fmt , ...)
20
26
#endif // ENABLE_LOGGING
21
27
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
-
72
28
void ShemuLog (char * data )
73
29
{
74
- if (gUseLog )
75
- {
76
- LOG ("%s" , data );
77
- }
30
+ LOG ("%s" , data );
78
31
}
79
32
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 )
81
42
{
82
43
// More or less copy pasted from disasmtool
83
44
@@ -119,7 +80,7 @@ void run_shemu(uint8_t *Data, size_t Size, uint8_t Def)
119
80
ctx .Segments .Gs .Selector = 0x30 ;
120
81
ctx .Segments .Gs .Base = 0x7FFF0000 ;
121
82
122
- ctx .Mode = Def ;
83
+ ctx .Mode = DEF_CODE ;
123
84
ctx .Ring = 3 ;
124
85
ctx .TibBase = ctx .Mode == ND_CODE_32 ? ctx .Segments .Fs .Base : ctx .Segments .Gs .Base ;
125
86
ctx .MaxInstructionsCount = 4096 ;
@@ -134,85 +95,87 @@ void run_shemu(uint8_t *Data, size_t Size, uint8_t Def)
134
95
free (ctx .Stack );
135
96
}
136
97
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 ();
141
103
142
- int8_t arch_to_def_code ( const char * arch )
104
+ int main ( )
143
105
{
144
- uint32_t a = strtoul ( arch , NULL , 0 );
106
+ __AFL_INIT ( );
145
107
146
- switch (a )
108
+ uint8_t * buffer = __AFL_FUZZ_TESTCASE_BUF ;
109
+ while (__AFL_LOOP (UINT_MAX ))
147
110
{
148
- case 16 :
149
- return ND_CODE_16 ;
111
+ size_t size = __AFL_FUZZ_TESTCASE_LEN ;
112
+ run_shemu (buffer , size );
113
+ }
150
114
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.
153
121
154
- case 64 :
155
- return ND_CODE_64 ;
122
+ uint8_t * buffer = malloc ( Size );
123
+ if (! buffer ) return 1 ;
156
124
157
- default :
158
- LOG ("[-] Unknown arch: \"%s\"\n" , arch );
159
- return -1 ;
160
- }
161
- }
125
+ memcpy (buffer , Data , Size );
126
+ run_shemu (buffer , Size );
162
127
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 )
164
133
{
165
- size_t size = 0 ;
166
134
uint8_t * buffer ;
167
- int8_t defCode ;
168
-
169
- if (argc < 3 )
135
+ FILE * fd = fopen (fpath , "rb" );
136
+ if (fd == NULL )
170
137
{
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 ;
173
140
}
174
141
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 );
180
145
181
- if (argc >= 4 )
146
+ buffer = malloc (* size );
147
+ if (buffer == NULL )
182
148
{
183
- LOG ("[+] Will activate ShemuLog\n" );
184
- gUseLog = true;
149
+ LOG ("[-] Failed to allocate %zu bytes\n" , * size );
185
150
}
186
151
else
187
152
{
188
- gUseLog = false ;
153
+ fread ( buffer , * size , 1 , fd ) ;
189
154
}
190
155
191
- LOG ("[+] Using def code/data = %d\n" , defCode );
156
+ fclose (fd );
157
+ return buffer ;
158
+ }
192
159
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 )
200
163
{
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
+ }
211
167
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 ();
213
174
}
214
175
215
- LOG ("[+] Done!\n" );
176
+ run_shemu (buffer , size );
177
+ free (buffer );
216
178
217
179
return 0 ;
218
180
}
181
+ #endif // defined(__AFL_FUZZ_TESTCASE_LEN)
0 commit comments