1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 
6 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
7 
8 #define MAX_INSTR_SIZE 64
9 #define MAX_LINE_SIZE 128
10 
11 int main(int argc, char** argv)
12 {
13     FILE * fp;
14     uint8_t Data[MAX_INSTR_SIZE];
15     char line[MAX_LINE_SIZE];
16     size_t Size;
17     char arch[MAX_LINE_SIZE];
18     char mode[MAX_LINE_SIZE];
19     unsigned int value;
20     int i;
21 
22     if (argc < 2) {
23         return 1;
24     }
25     for (i = 1; i < argc; i++) {
26         //opens the file, get its size, and reads it into a buffer
27         fp = fopen(argv[i], "rb");
28         if (fp == NULL) {
29             return 2;
30         }
31         printf("Trying %s\n", argv[i]);
32         if (fgets(line, MAX_LINE_SIZE, fp) == NULL) {
33             break;
34         }
35         if (line[0] == '#') {
36             if (sscanf(line, "# %[^,], %[^,]", arch, mode) != 2) {
37                 printf("Wrong mode %s\n", line);
38                 return 1;
39             }
40             if (strcmp(arch, "CS_ARCH_X86") == 0 && strcmp(mode, "CS_MODE_32") == 0) {
41                 Data[0] = 0;
42             } else if (strcmp(arch, "CS_ARCH_X86") == 0 && strcmp(mode, "CS_MODE_64") == 0) {
43                 Data[0] = 1;
44             } else if (strcmp(arch, "CS_ARCH_ARM") == 0 && strcmp(mode, "CS_MODE_ARM") == 0) {
45                 Data[0] = 2;
46             } else if (strcmp(arch, "CS_ARCH_ARM") == 0 && strcmp(mode, "CS_MODE_THUMB") == 0) {
47                 Data[0] = 3;
48             } else if (strcmp(arch, "CS_ARCH_ARM") == 0 && strcmp(mode, "CS_MODE_ARM+CS_MODE_V8") == 0) {
49                 Data[0] = 4;
50             } else if (strcmp(arch, "CS_ARCH_ARM") == 0 && strcmp(mode, "CS_MODE_THUMB+CS_MODE_V8") == 0) {
51                 Data[0] = 5;
52             } else if (strcmp(arch, "CS_ARCH_ARM") == 0 && strcmp(mode, "CS_MODE_THUMB+CS_MODE_MCLASS") == 0) {
53                 Data[0] = 6;
54             } else if (strcmp(arch, "CS_ARCH_ARM64") == 0 && strcmp(mode, "0") == 0) {
55                 Data[0] = 7;
56             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32+CS_MODE_BIG_ENDIAN") == 0) {
57                 Data[0] = 8;
58             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32+CS_MODE_MICRO") == 0) {
59                 Data[0] = 9;
60             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS64") == 0) {
61                 Data[0] = 10;
62             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32") == 0) {
63                 Data[0] = 11;
64             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS64+CS_MODE_BIG_ENDIAN") == 0) {
65                 Data[0] = 12;
66             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32+CS_MODE_MICRO+CS_MODE_BIG_ENDIAN") == 0) {
67                 Data[0] = 13;
68             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32+CS_MODE_BIG_ENDIAN+CS_MODE_MICRO") == 0) {
69                 Data[0] = 13;
70             } else if (strcmp(arch, "CS_ARCH_PPC") == 0 && strcmp(mode, "CS_MODE_BIG_ENDIAN") == 0) {
71                 Data[0] = 14;
72             } else if (strcmp(arch, "CS_ARCH_SPARC") == 0 && strcmp(mode, "CS_MODE_BIG_ENDIAN") == 0) {
73                 Data[0] = 15;
74             } else if (strcmp(arch, "CS_ARCH_SPARC") == 0 && strcmp(mode, "CS_MODE_BIG_ENDIAN + CS_MODE_V9") == 0) {
75                 Data[0] = 16;
76             } else if (strcmp(arch, "CS_ARCH_SYSZ") == 0 && strcmp(mode, "0") == 0) {
77                 Data[0] = 17;
78             } else if (strcmp(arch, "CS_ARCH_XCORE") == 0 && strcmp(mode, "0") == 0) {
79                 Data[0] = 18;
80             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32R6+CS_MODE_BIG_ENDIAN") == 0) {
81                 Data[0] = 19;
82             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32R6+CS_MODE_MICRO+CS_MODE_BIG_ENDIAN") == 0) {
83                 Data[0] = 20;
84             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32R6") == 0) {
85                 Data[0] = 21;
86             } else if (strcmp(arch, "CS_ARCH_MIPS") == 0 && strcmp(mode, "CS_MODE_MIPS32R6+CS_MODE_MICRO") == 0) {
87                 Data[0] = 22;
88             } else if (strcmp(arch, "CS_ARCH_M68K") == 0 && strcmp(mode, "0") == 0) {
89                 Data[0] = 23;
90             } else if (strcmp(arch, "CS_ARCH_M680X") == 0 && strcmp(mode, "CS_MODE_M680X_6809") == 0) {
91                 Data[0] = 24;
92             } else if (strcmp(arch, "CS_ARCH_EVM") == 0 && strcmp(mode, "0") == 0) {
93                 Data[0] = 25;
94 	    } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_CLASSIC") != NULL) {
95                 Data[0] = 29;
96             } else if (strcmp(arch, "CS_ARCH_BPF") == 0 && strstr(mode, "CS_MODE_BPF_EXTENDED") != NULL) {
97                 Data[0] = 30;
98             } else if (strcmp(arch, "CS_ARCH_RISCV") == 0 && strcmp(mode, "CS_MODE_RISCV32") == 0) {
99                 Data[0] = 44;
100             } else if (strcmp(arch, "CS_ARCH_RISCV") == 0 && strcmp(mode, "CS_MODE_RISCV64") == 0) {
101                 Data[0] = 45;
102             } else {
103                 printf("Unknown mode\n");
104                 //fail instead of continue
105                 return 1;
106             }
107         } else {
108             printf("No mode\n");
109             //fail instead of continue
110             return 1;
111         }
112 
113         while(1) {
114             if (fgets(line, MAX_LINE_SIZE, fp) == NULL) {
115                 break;
116             }
117             Size = 1;
118             // we start line at offset 0 and Data buffer at offset 1
119             // since Data[0] is option : arch + mode
120             while (sscanf(line+(Size-1)*5, "0x%02x", &value) == 1) {
121                 Data[Size] = value;
122                 Size++;
123                 if (line[(Size-1)*5-1] != ',') {
124                     //end of pattern
125                     break;
126                 } else if (MAX_LINE_SIZE < (Size-1)*5) {
127                     printf("Line overflow\n");
128                     return 1;
129                 }
130             }
131             //lauch fuzzer
132             LLVMFuzzerTestOneInput(Data, Size);
133         }
134         fclose(fp);
135     }
136     return 0;
137 }
138 
139