xref: /aosp_15_r20/external/capstone/suite/fuzz/fuzz_disasm.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi // the following must precede stdio (woo, thanks msft)
2*9a0e4156SSadaf Ebrahimi #if defined(_MSC_VER) && _MSC_VER < 1900
3*9a0e4156SSadaf Ebrahimi #define _CRT_SECURE_NO_WARNINGS
4*9a0e4156SSadaf Ebrahimi #endif
5*9a0e4156SSadaf Ebrahimi 
6*9a0e4156SSadaf Ebrahimi #include <stdio.h>
7*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
8*9a0e4156SSadaf Ebrahimi #include <inttypes.h>
9*9a0e4156SSadaf Ebrahimi 
10*9a0e4156SSadaf Ebrahimi #include <capstone/capstone.h>
11*9a0e4156SSadaf Ebrahimi 
12*9a0e4156SSadaf Ebrahimi int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
13*9a0e4156SSadaf Ebrahimi 
14*9a0e4156SSadaf Ebrahimi 
15*9a0e4156SSadaf Ebrahimi struct platform {
16*9a0e4156SSadaf Ebrahimi     cs_arch arch;
17*9a0e4156SSadaf Ebrahimi     cs_mode mode;
18*9a0e4156SSadaf Ebrahimi     const char *comment;
19*9a0e4156SSadaf Ebrahimi };
20*9a0e4156SSadaf Ebrahimi 
21*9a0e4156SSadaf Ebrahimi static FILE *outfile = NULL;
22*9a0e4156SSadaf Ebrahimi 
23*9a0e4156SSadaf Ebrahimi static struct platform platforms[] = {
24*9a0e4156SSadaf Ebrahimi     {
25*9a0e4156SSadaf Ebrahimi         // item 0
26*9a0e4156SSadaf Ebrahimi         CS_ARCH_X86,
27*9a0e4156SSadaf Ebrahimi         CS_MODE_32,
28*9a0e4156SSadaf Ebrahimi         "X86 32 (Intel syntax)"
29*9a0e4156SSadaf Ebrahimi     },
30*9a0e4156SSadaf Ebrahimi     {
31*9a0e4156SSadaf Ebrahimi         // item 1
32*9a0e4156SSadaf Ebrahimi         CS_ARCH_X86,
33*9a0e4156SSadaf Ebrahimi         CS_MODE_64,
34*9a0e4156SSadaf Ebrahimi         "X86 64 (Intel syntax)"
35*9a0e4156SSadaf Ebrahimi     },
36*9a0e4156SSadaf Ebrahimi     {
37*9a0e4156SSadaf Ebrahimi         // item 2
38*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM,
39*9a0e4156SSadaf Ebrahimi         CS_MODE_ARM,
40*9a0e4156SSadaf Ebrahimi         "ARM"
41*9a0e4156SSadaf Ebrahimi     },
42*9a0e4156SSadaf Ebrahimi     {
43*9a0e4156SSadaf Ebrahimi         // item 3
44*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM,
45*9a0e4156SSadaf Ebrahimi         CS_MODE_THUMB,
46*9a0e4156SSadaf Ebrahimi         "THUMB"
47*9a0e4156SSadaf Ebrahimi     },
48*9a0e4156SSadaf Ebrahimi     {
49*9a0e4156SSadaf Ebrahimi         // item 4
50*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM,
51*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_ARM + CS_MODE_V8),
52*9a0e4156SSadaf Ebrahimi         "Arm-V8"
53*9a0e4156SSadaf Ebrahimi     },
54*9a0e4156SSadaf Ebrahimi     {
55*9a0e4156SSadaf Ebrahimi         // item 5
56*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM,
57*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_THUMB+CS_MODE_V8),
58*9a0e4156SSadaf Ebrahimi         "THUMB+V8"
59*9a0e4156SSadaf Ebrahimi     },
60*9a0e4156SSadaf Ebrahimi     {
61*9a0e4156SSadaf Ebrahimi         // item 6
62*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM,
63*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_THUMB + CS_MODE_MCLASS),
64*9a0e4156SSadaf Ebrahimi         "Thumb-MClass"
65*9a0e4156SSadaf Ebrahimi     },
66*9a0e4156SSadaf Ebrahimi     {
67*9a0e4156SSadaf Ebrahimi         // item 7
68*9a0e4156SSadaf Ebrahimi         CS_ARCH_ARM64,
69*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
70*9a0e4156SSadaf Ebrahimi         "ARM-64"
71*9a0e4156SSadaf Ebrahimi     },
72*9a0e4156SSadaf Ebrahimi     {
73*9a0e4156SSadaf Ebrahimi         // item 8
74*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
75*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN),
76*9a0e4156SSadaf Ebrahimi         "MIPS-32 (Big-endian)"
77*9a0e4156SSadaf Ebrahimi     },
78*9a0e4156SSadaf Ebrahimi     {
79*9a0e4156SSadaf Ebrahimi         // item 9
80*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
81*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO),
82*9a0e4156SSadaf Ebrahimi         "MIPS-32 (micro)"
83*9a0e4156SSadaf Ebrahimi     },
84*9a0e4156SSadaf Ebrahimi     {
85*9a0e4156SSadaf Ebrahimi         //item 10
86*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
87*9a0e4156SSadaf Ebrahimi         CS_MODE_MIPS64,
88*9a0e4156SSadaf Ebrahimi         "MIPS-64-EL (Little-endian)"
89*9a0e4156SSadaf Ebrahimi     },
90*9a0e4156SSadaf Ebrahimi     {
91*9a0e4156SSadaf Ebrahimi         //item 11
92*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
93*9a0e4156SSadaf Ebrahimi         CS_MODE_MIPS32,
94*9a0e4156SSadaf Ebrahimi         "MIPS-32-EL (Little-endian)"
95*9a0e4156SSadaf Ebrahimi     },
96*9a0e4156SSadaf Ebrahimi     {
97*9a0e4156SSadaf Ebrahimi         //item 12
98*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
99*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN),
100*9a0e4156SSadaf Ebrahimi         "MIPS-64 (Big-endian)"
101*9a0e4156SSadaf Ebrahimi     },
102*9a0e4156SSadaf Ebrahimi     {
103*9a0e4156SSadaf Ebrahimi         //item 13
104*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
105*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
106*9a0e4156SSadaf Ebrahimi         "MIPS-32 | Micro (Big-endian)"
107*9a0e4156SSadaf Ebrahimi     },
108*9a0e4156SSadaf Ebrahimi     {
109*9a0e4156SSadaf Ebrahimi         //item 14
110*9a0e4156SSadaf Ebrahimi         CS_ARCH_PPC,
111*9a0e4156SSadaf Ebrahimi         CS_MODE_BIG_ENDIAN,
112*9a0e4156SSadaf Ebrahimi         "PPC-64"
113*9a0e4156SSadaf Ebrahimi     },
114*9a0e4156SSadaf Ebrahimi     {
115*9a0e4156SSadaf Ebrahimi         //item 15
116*9a0e4156SSadaf Ebrahimi         CS_ARCH_SPARC,
117*9a0e4156SSadaf Ebrahimi         CS_MODE_BIG_ENDIAN,
118*9a0e4156SSadaf Ebrahimi         "Sparc"
119*9a0e4156SSadaf Ebrahimi     },
120*9a0e4156SSadaf Ebrahimi     {
121*9a0e4156SSadaf Ebrahimi         //item 16
122*9a0e4156SSadaf Ebrahimi         CS_ARCH_SPARC,
123*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_V9),
124*9a0e4156SSadaf Ebrahimi         "SparcV9"
125*9a0e4156SSadaf Ebrahimi     },
126*9a0e4156SSadaf Ebrahimi     {
127*9a0e4156SSadaf Ebrahimi         //item 17
128*9a0e4156SSadaf Ebrahimi         CS_ARCH_SYSZ,
129*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
130*9a0e4156SSadaf Ebrahimi         "SystemZ"
131*9a0e4156SSadaf Ebrahimi     },
132*9a0e4156SSadaf Ebrahimi     {
133*9a0e4156SSadaf Ebrahimi         //item 18
134*9a0e4156SSadaf Ebrahimi         CS_ARCH_XCORE,
135*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
136*9a0e4156SSadaf Ebrahimi         "XCore"
137*9a0e4156SSadaf Ebrahimi     },
138*9a0e4156SSadaf Ebrahimi     {
139*9a0e4156SSadaf Ebrahimi         //item 19
140*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
141*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN),
142*9a0e4156SSadaf Ebrahimi         "MIPS-32R6 (Big-endian)"
143*9a0e4156SSadaf Ebrahimi     },
144*9a0e4156SSadaf Ebrahimi     {
145*9a0e4156SSadaf Ebrahimi         //item 20
146*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
147*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
148*9a0e4156SSadaf Ebrahimi         "MIPS-32R6 (Micro+Big-endian)"
149*9a0e4156SSadaf Ebrahimi     },
150*9a0e4156SSadaf Ebrahimi     {
151*9a0e4156SSadaf Ebrahimi         //item 21
152*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
153*9a0e4156SSadaf Ebrahimi         CS_MODE_MIPS32R6,
154*9a0e4156SSadaf Ebrahimi         "MIPS-32R6 (Little-endian)"
155*9a0e4156SSadaf Ebrahimi     },
156*9a0e4156SSadaf Ebrahimi     {
157*9a0e4156SSadaf Ebrahimi         //item 22
158*9a0e4156SSadaf Ebrahimi         CS_ARCH_MIPS,
159*9a0e4156SSadaf Ebrahimi         (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO),
160*9a0e4156SSadaf Ebrahimi         "MIPS-32R6 (Micro+Little-endian)"
161*9a0e4156SSadaf Ebrahimi     },
162*9a0e4156SSadaf Ebrahimi     {
163*9a0e4156SSadaf Ebrahimi         //item 23
164*9a0e4156SSadaf Ebrahimi         CS_ARCH_M68K,
165*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
166*9a0e4156SSadaf Ebrahimi         "M68K"
167*9a0e4156SSadaf Ebrahimi     },
168*9a0e4156SSadaf Ebrahimi     {
169*9a0e4156SSadaf Ebrahimi         //item 24
170*9a0e4156SSadaf Ebrahimi         CS_ARCH_M680X,
171*9a0e4156SSadaf Ebrahimi         (cs_mode)CS_MODE_M680X_6809,
172*9a0e4156SSadaf Ebrahimi         "M680X_M6809"
173*9a0e4156SSadaf Ebrahimi     },
174*9a0e4156SSadaf Ebrahimi     {
175*9a0e4156SSadaf Ebrahimi         //item 25
176*9a0e4156SSadaf Ebrahimi         CS_ARCH_EVM,
177*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
178*9a0e4156SSadaf Ebrahimi         "EVM"
179*9a0e4156SSadaf Ebrahimi     },
180*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_HAS_MOS65XX
181*9a0e4156SSadaf Ebrahimi     {
182*9a0e4156SSadaf Ebrahimi         //item 26
183*9a0e4156SSadaf Ebrahimi         CS_ARCH_MOS65XX,
184*9a0e4156SSadaf Ebrahimi         (cs_mode)0,
185*9a0e4156SSadaf Ebrahimi         "MOS65XX"
186*9a0e4156SSadaf Ebrahimi     },
187*9a0e4156SSadaf Ebrahimi #endif
188*9a0e4156SSadaf Ebrahimi };
189*9a0e4156SSadaf Ebrahimi 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)190*9a0e4156SSadaf Ebrahimi int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
191*9a0e4156SSadaf Ebrahimi     csh handle;
192*9a0e4156SSadaf Ebrahimi     cs_insn *all_insn;
193*9a0e4156SSadaf Ebrahimi     cs_detail *detail;
194*9a0e4156SSadaf Ebrahimi     cs_err err;
195*9a0e4156SSadaf Ebrahimi 
196*9a0e4156SSadaf Ebrahimi     if (Size < 1) {
197*9a0e4156SSadaf Ebrahimi         // 1 byte for arch choice
198*9a0e4156SSadaf Ebrahimi         return 0;
199*9a0e4156SSadaf Ebrahimi     } else if (Size > 0x1000) {
200*9a0e4156SSadaf Ebrahimi         //limit input to 4kb
201*9a0e4156SSadaf Ebrahimi         Size = 0x1000;
202*9a0e4156SSadaf Ebrahimi     }
203*9a0e4156SSadaf Ebrahimi 
204*9a0e4156SSadaf Ebrahimi     if (outfile == NULL) {
205*9a0e4156SSadaf Ebrahimi         // we compute the output
206*9a0e4156SSadaf Ebrahimi         outfile = fopen("/dev/null", "w");
207*9a0e4156SSadaf Ebrahimi         if (outfile == NULL) {
208*9a0e4156SSadaf Ebrahimi             return 0;
209*9a0e4156SSadaf Ebrahimi         }
210*9a0e4156SSadaf Ebrahimi     }
211*9a0e4156SSadaf Ebrahimi 
212*9a0e4156SSadaf Ebrahimi     int platforms_len = sizeof(platforms)/sizeof(platforms[0]);
213*9a0e4156SSadaf Ebrahimi     int i = (int)Data[0] % platforms_len;
214*9a0e4156SSadaf Ebrahimi 
215*9a0e4156SSadaf Ebrahimi     err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
216*9a0e4156SSadaf Ebrahimi     if (err) {
217*9a0e4156SSadaf Ebrahimi         return 0;
218*9a0e4156SSadaf Ebrahimi     }
219*9a0e4156SSadaf Ebrahimi 
220*9a0e4156SSadaf Ebrahimi     cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
221*9a0e4156SSadaf Ebrahimi 
222*9a0e4156SSadaf Ebrahimi     uint64_t address = 0x1000;
223*9a0e4156SSadaf Ebrahimi     size_t count = cs_disasm(handle, Data+1, Size-1, address, 0, &all_insn);
224*9a0e4156SSadaf Ebrahimi 
225*9a0e4156SSadaf Ebrahimi     if (count) {
226*9a0e4156SSadaf Ebrahimi         size_t j;
227*9a0e4156SSadaf Ebrahimi         unsigned int n;
228*9a0e4156SSadaf Ebrahimi 
229*9a0e4156SSadaf Ebrahimi         for (j = 0; j < count; j++) {
230*9a0e4156SSadaf Ebrahimi             cs_insn *i = &(all_insn[j]);
231*9a0e4156SSadaf Ebrahimi             fprintf(outfile, "0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n",
232*9a0e4156SSadaf Ebrahimi                    i->address, i->mnemonic, i->op_str,
233*9a0e4156SSadaf Ebrahimi                    i->id, cs_insn_name(handle, i->id));
234*9a0e4156SSadaf Ebrahimi 
235*9a0e4156SSadaf Ebrahimi             detail = i->detail;
236*9a0e4156SSadaf Ebrahimi 
237*9a0e4156SSadaf Ebrahimi             if (detail->regs_read_count > 0) {
238*9a0e4156SSadaf Ebrahimi                 fprintf(outfile, "\tImplicit registers read: ");
239*9a0e4156SSadaf Ebrahimi                 for (n = 0; n < detail->regs_read_count; n++) {
240*9a0e4156SSadaf Ebrahimi                     fprintf(outfile, "%s ", cs_reg_name(handle, detail->regs_read[n]));
241*9a0e4156SSadaf Ebrahimi                 }
242*9a0e4156SSadaf Ebrahimi             }
243*9a0e4156SSadaf Ebrahimi 
244*9a0e4156SSadaf Ebrahimi             if (detail->regs_write_count > 0) {
245*9a0e4156SSadaf Ebrahimi                 fprintf(outfile, "\tImplicit registers modified: ");
246*9a0e4156SSadaf Ebrahimi                 for (n = 0; n < detail->regs_write_count; n++) {
247*9a0e4156SSadaf Ebrahimi                     fprintf(outfile, "%s ", cs_reg_name(handle, detail->regs_write[n]));
248*9a0e4156SSadaf Ebrahimi                 }
249*9a0e4156SSadaf Ebrahimi             }
250*9a0e4156SSadaf Ebrahimi 
251*9a0e4156SSadaf Ebrahimi             if (detail->groups_count > 0) {
252*9a0e4156SSadaf Ebrahimi                 fprintf(outfile, "\tThis instruction belongs to groups: ");
253*9a0e4156SSadaf Ebrahimi                 for (n = 0; n < detail->groups_count; n++) {
254*9a0e4156SSadaf Ebrahimi                     fprintf(outfile, "%s ", cs_group_name(handle, detail->groups[n]));
255*9a0e4156SSadaf Ebrahimi                 }
256*9a0e4156SSadaf Ebrahimi             }
257*9a0e4156SSadaf Ebrahimi         }
258*9a0e4156SSadaf Ebrahimi 
259*9a0e4156SSadaf Ebrahimi         fprintf(outfile, "0x%"PRIx64":\n", all_insn[j-1].address + all_insn[j-1].size);
260*9a0e4156SSadaf Ebrahimi         cs_free(all_insn, count);
261*9a0e4156SSadaf Ebrahimi     }
262*9a0e4156SSadaf Ebrahimi 
263*9a0e4156SSadaf Ebrahimi     cs_close(&handle);
264*9a0e4156SSadaf Ebrahimi 
265*9a0e4156SSadaf Ebrahimi     return 0;
266*9a0e4156SSadaf Ebrahimi }
267