xref: /aosp_15_r20/external/capstone/suite/fuzz/fuzz_harness.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi #include <stdio.h>
2*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
3*9a0e4156SSadaf Ebrahimi #include <inttypes.h>
4*9a0e4156SSadaf Ebrahimi #include <capstone.h>
5*9a0e4156SSadaf Ebrahimi 
6*9a0e4156SSadaf Ebrahimi struct platform {
7*9a0e4156SSadaf Ebrahimi   cs_arch arch;
8*9a0e4156SSadaf Ebrahimi   cs_mode mode;
9*9a0e4156SSadaf Ebrahimi   char *comment;
10*9a0e4156SSadaf Ebrahimi };
11*9a0e4156SSadaf Ebrahimi 
main(int argc,char ** argv)12*9a0e4156SSadaf Ebrahimi int main(int argc, char **argv)
13*9a0e4156SSadaf Ebrahimi {
14*9a0e4156SSadaf Ebrahimi   if (argc != 2) {
15*9a0e4156SSadaf Ebrahimi     printf("Usage: %s <testcase>\n", argv[0]);
16*9a0e4156SSadaf Ebrahimi     return 1;
17*9a0e4156SSadaf Ebrahimi   }
18*9a0e4156SSadaf Ebrahimi 
19*9a0e4156SSadaf Ebrahimi   struct platform platforms[] = {
20*9a0e4156SSadaf Ebrahimi     {
21*9a0e4156SSadaf Ebrahimi       CS_ARCH_X86,
22*9a0e4156SSadaf Ebrahimi       CS_MODE_32,
23*9a0e4156SSadaf Ebrahimi       "X86 32 (Intel syntax)"
24*9a0e4156SSadaf Ebrahimi     },
25*9a0e4156SSadaf Ebrahimi     {
26*9a0e4156SSadaf Ebrahimi       CS_ARCH_X86,
27*9a0e4156SSadaf Ebrahimi       CS_MODE_64,
28*9a0e4156SSadaf Ebrahimi       "X86 64 (Intel syntax)"
29*9a0e4156SSadaf Ebrahimi     },
30*9a0e4156SSadaf Ebrahimi     {
31*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
32*9a0e4156SSadaf Ebrahimi       CS_MODE_ARM,
33*9a0e4156SSadaf Ebrahimi       "ARM"
34*9a0e4156SSadaf Ebrahimi     },
35*9a0e4156SSadaf Ebrahimi     {
36*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
37*9a0e4156SSadaf Ebrahimi       CS_MODE_THUMB,
38*9a0e4156SSadaf Ebrahimi       "THUMB-2"
39*9a0e4156SSadaf Ebrahimi     },
40*9a0e4156SSadaf Ebrahimi     {
41*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
42*9a0e4156SSadaf Ebrahimi       CS_MODE_ARM,
43*9a0e4156SSadaf Ebrahimi       "ARM: Cortex-A15 + NEON"
44*9a0e4156SSadaf Ebrahimi     },
45*9a0e4156SSadaf Ebrahimi     {
46*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
47*9a0e4156SSadaf Ebrahimi       CS_MODE_THUMB,
48*9a0e4156SSadaf Ebrahimi       "THUMB"
49*9a0e4156SSadaf Ebrahimi     },
50*9a0e4156SSadaf Ebrahimi     {
51*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
52*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_THUMB + CS_MODE_MCLASS),
53*9a0e4156SSadaf Ebrahimi       "Thumb-MClass"
54*9a0e4156SSadaf Ebrahimi     },
55*9a0e4156SSadaf Ebrahimi     {
56*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM,
57*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_ARM + CS_MODE_V8),
58*9a0e4156SSadaf Ebrahimi       "Arm-V8"
59*9a0e4156SSadaf Ebrahimi     },
60*9a0e4156SSadaf Ebrahimi     {
61*9a0e4156SSadaf Ebrahimi       CS_ARCH_MIPS,
62*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN),
63*9a0e4156SSadaf Ebrahimi       "MIPS-32 (Big-endian)"
64*9a0e4156SSadaf Ebrahimi     },
65*9a0e4156SSadaf Ebrahimi     {
66*9a0e4156SSadaf Ebrahimi       CS_ARCH_MIPS,
67*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN),
68*9a0e4156SSadaf Ebrahimi       "MIPS-64-EL (Little-endian)"
69*9a0e4156SSadaf Ebrahimi     },
70*9a0e4156SSadaf Ebrahimi     {
71*9a0e4156SSadaf Ebrahimi       CS_ARCH_MIPS,
72*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN),
73*9a0e4156SSadaf Ebrahimi       "MIPS-32R6 | Micro (Big-endian)"
74*9a0e4156SSadaf Ebrahimi     },
75*9a0e4156SSadaf Ebrahimi     {
76*9a0e4156SSadaf Ebrahimi       CS_ARCH_MIPS,
77*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN),
78*9a0e4156SSadaf Ebrahimi       "MIPS-32R6 (Big-endian)"
79*9a0e4156SSadaf Ebrahimi     },
80*9a0e4156SSadaf Ebrahimi     {
81*9a0e4156SSadaf Ebrahimi       CS_ARCH_ARM64,
82*9a0e4156SSadaf Ebrahimi       CS_MODE_ARM,
83*9a0e4156SSadaf Ebrahimi       "ARM-64"
84*9a0e4156SSadaf Ebrahimi     },
85*9a0e4156SSadaf Ebrahimi     {
86*9a0e4156SSadaf Ebrahimi       CS_ARCH_PPC,
87*9a0e4156SSadaf Ebrahimi       CS_MODE_BIG_ENDIAN,
88*9a0e4156SSadaf Ebrahimi       "PPC-64"
89*9a0e4156SSadaf Ebrahimi     },
90*9a0e4156SSadaf Ebrahimi     {
91*9a0e4156SSadaf Ebrahimi       CS_ARCH_SPARC,
92*9a0e4156SSadaf Ebrahimi       CS_MODE_BIG_ENDIAN,
93*9a0e4156SSadaf Ebrahimi       "Sparc"
94*9a0e4156SSadaf Ebrahimi     },
95*9a0e4156SSadaf Ebrahimi     {
96*9a0e4156SSadaf Ebrahimi       CS_ARCH_SPARC,
97*9a0e4156SSadaf Ebrahimi       (cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_V9),
98*9a0e4156SSadaf Ebrahimi       "SparcV9"
99*9a0e4156SSadaf Ebrahimi     },
100*9a0e4156SSadaf Ebrahimi     {
101*9a0e4156SSadaf Ebrahimi       CS_ARCH_SYSZ,
102*9a0e4156SSadaf Ebrahimi       (cs_mode)0,
103*9a0e4156SSadaf Ebrahimi       "SystemZ"
104*9a0e4156SSadaf Ebrahimi     },
105*9a0e4156SSadaf Ebrahimi     {
106*9a0e4156SSadaf Ebrahimi       CS_ARCH_XCORE,
107*9a0e4156SSadaf Ebrahimi       (cs_mode)0,
108*9a0e4156SSadaf Ebrahimi       "XCore"
109*9a0e4156SSadaf Ebrahimi     },
110*9a0e4156SSadaf Ebrahimi     {
111*9a0e4156SSadaf Ebrahimi       CS_ARCH_M68K,
112*9a0e4156SSadaf Ebrahimi       (cs_mode)0,
113*9a0e4156SSadaf Ebrahimi       "M68K"
114*9a0e4156SSadaf Ebrahimi     },
115*9a0e4156SSadaf Ebrahimi     {
116*9a0e4156SSadaf Ebrahimi       CS_ARCH_M680X,
117*9a0e4156SSadaf Ebrahimi       (cs_mode)CS_MODE_M680X_6809,
118*9a0e4156SSadaf Ebrahimi       "M680X_M6809"
119*9a0e4156SSadaf Ebrahimi     },
120*9a0e4156SSadaf Ebrahimi   };
121*9a0e4156SSadaf Ebrahimi 
122*9a0e4156SSadaf Ebrahimi   // Read input
123*9a0e4156SSadaf Ebrahimi   long bufsize = 0;
124*9a0e4156SSadaf Ebrahimi   unsigned char *buf = NULL;
125*9a0e4156SSadaf Ebrahimi   FILE *fp = fopen(argv[1], "r");
126*9a0e4156SSadaf Ebrahimi 
127*9a0e4156SSadaf Ebrahimi   if (fp == NULL) return 1;
128*9a0e4156SSadaf Ebrahimi 
129*9a0e4156SSadaf Ebrahimi   if (fseek(fp, 0L, SEEK_END) == 0) {
130*9a0e4156SSadaf Ebrahimi     bufsize = ftell(fp);
131*9a0e4156SSadaf Ebrahimi 
132*9a0e4156SSadaf Ebrahimi     if (bufsize == -1) return 1;
133*9a0e4156SSadaf Ebrahimi 
134*9a0e4156SSadaf Ebrahimi     buf = malloc(bufsize + 1);
135*9a0e4156SSadaf Ebrahimi 
136*9a0e4156SSadaf Ebrahimi     if (buf == NULL) return 1;
137*9a0e4156SSadaf Ebrahimi     if (fseek(fp, 0L, SEEK_SET) != 0) return 1;
138*9a0e4156SSadaf Ebrahimi 
139*9a0e4156SSadaf Ebrahimi     size_t len = fread(buf, sizeof(char), bufsize, fp);
140*9a0e4156SSadaf Ebrahimi 
141*9a0e4156SSadaf Ebrahimi     if (len == 0) return 2;
142*9a0e4156SSadaf Ebrahimi   }
143*9a0e4156SSadaf Ebrahimi   fclose(fp);
144*9a0e4156SSadaf Ebrahimi 
145*9a0e4156SSadaf Ebrahimi   // Disassemble
146*9a0e4156SSadaf Ebrahimi   csh handle;
147*9a0e4156SSadaf Ebrahimi   cs_insn *all_insn;
148*9a0e4156SSadaf Ebrahimi   cs_detail *detail;
149*9a0e4156SSadaf Ebrahimi   cs_err err;
150*9a0e4156SSadaf Ebrahimi 
151*9a0e4156SSadaf Ebrahimi   if (bufsize < 3) return 0;
152*9a0e4156SSadaf Ebrahimi 
153*9a0e4156SSadaf Ebrahimi   int platforms_len = sizeof(platforms)/sizeof(platforms[0]);
154*9a0e4156SSadaf Ebrahimi   int i = (int)buf[0] % platforms_len;
155*9a0e4156SSadaf Ebrahimi 
156*9a0e4156SSadaf Ebrahimi   unsigned char *buf_ptr = buf + 1;
157*9a0e4156SSadaf Ebrahimi   long buf_ptr_size = bufsize - 1;
158*9a0e4156SSadaf Ebrahimi 
159*9a0e4156SSadaf Ebrahimi   printf("Platform: %s (0x%.2x of 0x%.2x)\n", platforms[i].comment, i, platforms_len);
160*9a0e4156SSadaf Ebrahimi 
161*9a0e4156SSadaf Ebrahimi   err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
162*9a0e4156SSadaf Ebrahimi   if (err) {
163*9a0e4156SSadaf Ebrahimi     printf("Failed on cs_open() with error returned: %u\n", err);
164*9a0e4156SSadaf Ebrahimi     return 1;
165*9a0e4156SSadaf Ebrahimi   }
166*9a0e4156SSadaf Ebrahimi 
167*9a0e4156SSadaf Ebrahimi   cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
168*9a0e4156SSadaf Ebrahimi 
169*9a0e4156SSadaf Ebrahimi   uint64_t address = 0x1000;
170*9a0e4156SSadaf Ebrahimi   size_t count = cs_disasm(handle, buf_ptr, buf_ptr_size, address, 0, &all_insn);
171*9a0e4156SSadaf Ebrahimi 
172*9a0e4156SSadaf Ebrahimi   if (count) {
173*9a0e4156SSadaf Ebrahimi     size_t j;
174*9a0e4156SSadaf Ebrahimi     int n;
175*9a0e4156SSadaf Ebrahimi 
176*9a0e4156SSadaf Ebrahimi     printf("Disasm:\n");
177*9a0e4156SSadaf Ebrahimi 
178*9a0e4156SSadaf Ebrahimi     for (j = 0; j < count; j++) {
179*9a0e4156SSadaf Ebrahimi       cs_insn *i = &(all_insn[j]);
180*9a0e4156SSadaf Ebrahimi       printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n",
181*9a0e4156SSadaf Ebrahimi           i->address, i->mnemonic, i->op_str,
182*9a0e4156SSadaf Ebrahimi           i->id, cs_insn_name(handle, i->id));
183*9a0e4156SSadaf Ebrahimi 
184*9a0e4156SSadaf Ebrahimi       detail = i->detail;
185*9a0e4156SSadaf Ebrahimi 
186*9a0e4156SSadaf Ebrahimi       if (detail->regs_read_count > 0) {
187*9a0e4156SSadaf Ebrahimi         printf("\tImplicit registers read: ");
188*9a0e4156SSadaf Ebrahimi         for (n = 0; n < detail->regs_read_count; n++) {
189*9a0e4156SSadaf Ebrahimi           printf("%s ", cs_reg_name(handle, detail->regs_read[n]));
190*9a0e4156SSadaf Ebrahimi         }
191*9a0e4156SSadaf Ebrahimi         printf("\n");
192*9a0e4156SSadaf Ebrahimi       }
193*9a0e4156SSadaf Ebrahimi 
194*9a0e4156SSadaf Ebrahimi       if (detail->regs_write_count > 0) {
195*9a0e4156SSadaf Ebrahimi         printf("\tImplicit registers modified: ");
196*9a0e4156SSadaf Ebrahimi         for (n = 0; n < detail->regs_write_count; n++) {
197*9a0e4156SSadaf Ebrahimi           printf("%s ", cs_reg_name(handle, detail->regs_write[n]));
198*9a0e4156SSadaf Ebrahimi         }
199*9a0e4156SSadaf Ebrahimi         printf("\n");
200*9a0e4156SSadaf Ebrahimi       }
201*9a0e4156SSadaf Ebrahimi 
202*9a0e4156SSadaf Ebrahimi       if (detail->groups_count > 0) {
203*9a0e4156SSadaf Ebrahimi         printf("\tThis instruction belongs to groups: ");
204*9a0e4156SSadaf Ebrahimi         for (n = 0; n < detail->groups_count; n++) {
205*9a0e4156SSadaf Ebrahimi           printf("%s ", cs_group_name(handle, detail->groups[n]));
206*9a0e4156SSadaf Ebrahimi         }
207*9a0e4156SSadaf Ebrahimi         printf("\n");
208*9a0e4156SSadaf Ebrahimi       }
209*9a0e4156SSadaf Ebrahimi     }
210*9a0e4156SSadaf Ebrahimi     printf("0x%"PRIx64":\n", all_insn[j-1].address + all_insn[j-1].size);
211*9a0e4156SSadaf Ebrahimi     cs_free(all_insn, count);
212*9a0e4156SSadaf Ebrahimi   } else {
213*9a0e4156SSadaf Ebrahimi     printf("ERROR: Failed to disasm given code!\n");
214*9a0e4156SSadaf Ebrahimi   }
215*9a0e4156SSadaf Ebrahimi 
216*9a0e4156SSadaf Ebrahimi   printf("\n");
217*9a0e4156SSadaf Ebrahimi 
218*9a0e4156SSadaf Ebrahimi   free(buf);
219*9a0e4156SSadaf Ebrahimi   cs_close(&handle);
220*9a0e4156SSadaf Ebrahimi 
221*9a0e4156SSadaf Ebrahimi   return 0;
222*9a0e4156SSadaf Ebrahimi }
223