1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <inttypes.h>
5 #include <assert.h>
6
7 #include <capstone/capstone.h>
8
9
10 struct platform {
11 cs_arch arch;
12 cs_mode mode;
13 char *comment;
14 };
15
16 FILE * outfile = NULL;
17
18 struct platform platforms[] = {
19 {
20 // item 0
21 CS_ARCH_X86,
22 CS_MODE_32,
23 "X86 32 (Intel syntax)"
24 },
25 {
26 // item 1
27 CS_ARCH_X86,
28 CS_MODE_64,
29 "X86 64 (Intel syntax)"
30 },
31 {
32 // item 2
33 CS_ARCH_ARM,
34 CS_MODE_ARM,
35 "ARM"
36 },
37 {
38 // item 3
39 CS_ARCH_ARM,
40 CS_MODE_THUMB,
41 "THUMB"
42 },
43 {
44 // item 4
45 CS_ARCH_ARM,
46 (cs_mode)(CS_MODE_ARM + CS_MODE_V8),
47 "Arm-V8"
48 },
49 {
50 // item 5
51 CS_ARCH_ARM,
52 (cs_mode)(CS_MODE_THUMB+CS_MODE_V8),
53 "THUMB+V8"
54 },
55 {
56 // item 6
57 CS_ARCH_ARM,
58 (cs_mode)(CS_MODE_THUMB + CS_MODE_MCLASS),
59 "Thumb-MClass"
60 },
61 {
62 // item 7
63 CS_ARCH_ARM64,
64 (cs_mode)0,
65 "ARM-64"
66 },
67 {
68 // item 8
69 CS_ARCH_MIPS,
70 (cs_mode)(CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN),
71 "MIPS-32 (Big-endian)"
72 },
73 {
74 // item 9
75 CS_ARCH_MIPS,
76 (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO),
77 "MIPS-32 (micro)"
78 },
79 {
80 //item 10
81 CS_ARCH_MIPS,
82 CS_MODE_MIPS64,
83 "MIPS-64-EL (Little-endian)"
84 },
85 {
86 //item 11
87 CS_ARCH_MIPS,
88 CS_MODE_MIPS32,
89 "MIPS-32-EL (Little-endian)"
90 },
91 {
92 //item 12
93 CS_ARCH_MIPS,
94 (cs_mode)(CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN),
95 "MIPS-64 (Big-endian)"
96 },
97 {
98 //item 13
99 CS_ARCH_MIPS,
100 (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
101 "MIPS-32 | Micro (Big-endian)"
102 },
103 {
104 //item 14
105 CS_ARCH_PPC,
106 CS_MODE_BIG_ENDIAN,
107 "PPC-64"
108 },
109 {
110 //item 15
111 CS_ARCH_SPARC,
112 CS_MODE_BIG_ENDIAN,
113 "Sparc"
114 },
115 {
116 //item 16
117 CS_ARCH_SPARC,
118 (cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_V9),
119 "SparcV9"
120 },
121 {
122 //item 17
123 CS_ARCH_SYSZ,
124 (cs_mode)0,
125 "SystemZ"
126 },
127 {
128 //item 18
129 CS_ARCH_XCORE,
130 (cs_mode)0,
131 "XCore"
132 },
133 {
134 //item 19
135 CS_ARCH_MIPS,
136 (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN),
137 "MIPS-32R6 (Big-endian)"
138 },
139 {
140 //item 20
141 CS_ARCH_MIPS,
142 (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
143 "MIPS-32R6 (Micro+Big-endian)"
144 },
145 {
146 //item 21
147 CS_ARCH_MIPS,
148 CS_MODE_MIPS32R6,
149 "MIPS-32R6 (Little-endian)"
150 },
151 {
152 //item 22
153 CS_ARCH_MIPS,
154 (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO),
155 "MIPS-32R6 (Micro+Little-endian)"
156 },
157 {
158 //item 23
159 CS_ARCH_M68K,
160 (cs_mode)0,
161 "M68K"
162 },
163 {
164 //item 24
165 CS_ARCH_M680X,
166 (cs_mode)CS_MODE_M680X_6809,
167 "M680X_M6809"
168 },
169 {
170 //item 25
171 CS_ARCH_EVM,
172 (cs_mode)0,
173 "EVM"
174 },
175 };
176
177 void LLVMFuzzerInit();
178 int LLVMFuzzerReturnOneInput(const uint8_t *Data, size_t Size, char * AssemblyText);
179
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)180 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
181 csh handle;
182 cs_insn *insn;
183 cs_err err;
184 const uint8_t **Datap = &Data;
185 size_t * Sizep = &Size;
186 uint64_t address = 0x1000;
187 char LLVMAssemblyText[80];
188 char CapstoneAssemblyText[80];
189
190 if (Size < 1) {
191 // 1 byte for arch choice
192 return 0;
193 } else if (Size > 0x1000) {
194 //limit input to 4kb
195 Size = 0x1000;
196 }
197 if (outfile == NULL) {
198 // we compute the output
199 outfile = fopen("/dev/null", "w");
200 if (outfile == NULL) {
201 return 0;
202 }
203 LLVMFuzzerInit();
204 }
205
206 if (Data[0] >= sizeof(platforms)/sizeof(platforms[0])) {
207 return 0;
208 }
209
210 if (LLVMFuzzerReturnOneInput(Data, Size, LLVMAssemblyText) == 1) {
211 return 0;
212 }
213
214 err = cs_open(platforms[Data[0]].arch, platforms[Data[0]].mode, &handle);
215 if (err) {
216 return 0;
217 }
218
219 insn = cs_malloc(handle);
220 Data++;
221 Size--;
222 assert(insn);
223 if (cs_disasm_iter(handle, Datap, Sizep, &address, insn)) {
224 snprintf(CapstoneAssemblyText, 80, "\t%s\t%s", insn->mnemonic, insn->op_str);
225 if (strcmp(CapstoneAssemblyText, LLVMAssemblyText) != 0) {
226 printf("capstone %s != llvm %s", CapstoneAssemblyText, LLVMAssemblyText);
227 abort();
228 }
229 } else {
230 printf("capstone failed with llvm %s", LLVMAssemblyText);
231 abort();
232 }
233 cs_free(insn, 1);
234 cs_close(&handle);
235
236 return 0;
237 }
238