1 /* Capstone testing regression */
2 /* By Do Minh Tuan <tuanit96@gmail.com>, 02-2019 */
3
4
5 #include "capstone_test.h"
6
7 single_dict arches[] = {
8 {"CS_ARCH_ARM", CS_ARCH_ARM},
9 {"CS_ARCH_ARM64", CS_ARCH_ARM64},
10 {"CS_ARCH_MIPS", CS_ARCH_MIPS},
11 {"CS_ARCH_PPC", CS_ARCH_PPC},
12 {"CS_ARCH_SPARC", CS_ARCH_SPARC},
13 {"CS_ARCH_SYSZ", CS_ARCH_SYSZ},
14 {"CS_ARCH_X86", CS_ARCH_X86},
15 {"CS_ARCH_XCORE", CS_ARCH_XCORE},
16 {"CS_ARCH_M68K", CS_ARCH_M68K}
17 };
18
19 single_dict modes[] = {
20 {"CS_MODE_LITTLE_ENDIAN", CS_MODE_LITTLE_ENDIAN},
21 {"CS_MODE_ARM", CS_MODE_ARM},
22 {"CS_MODE_16", CS_MODE_16},
23 {"CS_MODE_32", CS_MODE_32},
24 {"CS_MODE_64", CS_MODE_64},
25 {"CS_MODE_THUMB", CS_MODE_THUMB},
26 {"CS_MODE_MCLASS", CS_MODE_MCLASS},
27 {"CS_MODE_V8", CS_MODE_V8},
28 {"CS_MODE_MICRO", CS_MODE_MICRO},
29 {"CS_MODE_MIPS3", CS_MODE_MIPS3},
30 {"CS_MODE_MIPS32R6", CS_MODE_MIPS32R6},
31 {"CS_MODE_MIPS2", CS_MODE_MIPS2},
32 {"CS_MODE_V9", CS_MODE_V9},
33 {"CS_MODE_QPX", CS_MODE_QPX},
34 {"CS_MODE_M68K_000", CS_MODE_M68K_000},
35 {"CS_MODE_M68K_010", CS_MODE_M68K_010},
36 {"CS_MODE_M68K_020", CS_MODE_M68K_020},
37 {"CS_MODE_M68K_030", CS_MODE_M68K_030},
38 {"CS_MODE_M68K_040", CS_MODE_M68K_040},
39 {"CS_MODE_M68K_060", CS_MODE_M68K_060},
40 {"CS_MODE_BIG_ENDIAN", CS_MODE_BIG_ENDIAN},
41 {"CS_MODE_MIPS32", CS_MODE_MIPS32},
42 {"CS_MODE_MIPS64", CS_MODE_MIPS64},
43 {"CS_MODE_M680X_6301", CS_MODE_M680X_6301},
44 {"CS_MODE_M680X_6309", CS_MODE_M680X_6309},
45 {"CS_MODE_M680X_6800", CS_MODE_M680X_6800},
46 {"CS_MODE_M680X_6801", CS_MODE_M680X_6801},
47 {"CS_MODE_M680X_6805", CS_MODE_M680X_6805},
48 {"CS_MODE_M680X_6808", CS_MODE_M680X_6808},
49 {"CS_MODE_M680X_6809", CS_MODE_M680X_6809},
50 {"CS_MODE_M680X_6811", CS_MODE_M680X_6811},
51 {"CS_MODE_M680X_CPU12", CS_MODE_M680X_CPU12},
52 {"CS_MODE_M680X_HCS08", CS_MODE_M680X_HCS08}
53 };
54
55 double_dict options[] = {
56 {"CS_OPT_DETAIL", CS_OPT_DETAIL, CS_OPT_ON},
57 {"CS_OPT_SKIPDATA", CS_OPT_SKIPDATA, CS_OPT_ON},
58 {"CS_OPT_SYNTAX_DEFAULT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT},
59 {"CS_OPT_SYNTAX_INTEL", CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL},
60 {"CS_OPT_SYNTAX_ATT", CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT},
61 {"CS_OPT_SYNTAX_NOREGNAME", CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME},
62 {"CS_OPT_SYNTAX_MASM", CS_OPT_SYNTAX, CS_OPT_SYNTAX_MASM},
63 {"CS_MODE_LITTLE_ENDIAN", CS_OPT_MODE, CS_MODE_LITTLE_ENDIAN},
64 {"CS_MODE_ARM", CS_OPT_MODE, CS_MODE_ARM},
65 {"CS_MODE_16", CS_OPT_MODE, CS_MODE_16},
66 {"CS_MODE_32", CS_OPT_MODE, CS_MODE_32},
67 {"CS_MODE_64", CS_OPT_MODE, CS_MODE_64},
68 {"CS_MODE_THUMB", CS_OPT_MODE, CS_MODE_THUMB},
69 {"CS_MODE_MCLASS", CS_OPT_MODE, CS_MODE_MCLASS},
70 {"CS_MODE_V8", CS_OPT_MODE, CS_MODE_V8},
71 {"CS_MODE_MICRO", CS_OPT_MODE, CS_MODE_MICRO},
72 {"CS_MODE_MIPS3", CS_OPT_MODE, CS_MODE_MIPS3},
73 {"CS_MODE_MIPS32R6", CS_OPT_MODE, CS_MODE_MIPS32R6},
74 {"CS_MODE_MIPS2", CS_OPT_MODE, CS_MODE_MIPS2},
75 {"CS_MODE_V9", CS_OPT_MODE, CS_MODE_V9},
76 {"CS_MODE_QPX", CS_OPT_MODE, CS_MODE_QPX},
77 {"CS_MODE_M68K_000", CS_OPT_MODE, CS_MODE_M68K_000},
78 {"CS_MODE_M68K_010", CS_OPT_MODE, CS_MODE_M68K_010},
79 {"CS_MODE_M68K_020", CS_OPT_MODE, CS_MODE_M68K_020},
80 {"CS_MODE_M68K_030", CS_OPT_MODE, CS_MODE_M68K_030},
81 {"CS_MODE_M68K_040", CS_OPT_MODE, CS_MODE_M68K_040},
82 {"CS_MODE_M68K_060", CS_OPT_MODE, CS_MODE_M68K_060},
83 {"CS_MODE_BIG_ENDIAN", CS_OPT_MODE, CS_MODE_BIG_ENDIAN},
84 {"CS_MODE_MIPS32", CS_OPT_MODE, CS_MODE_MIPS32},
85 {"CS_MODE_MIPS64", CS_OPT_MODE, CS_MODE_MIPS64},
86 {"CS_MODE_M680X_6301", CS_OPT_MODE, CS_MODE_M680X_6301},
87 {"CS_MODE_M680X_6309", CS_OPT_MODE, CS_MODE_M680X_6309},
88 {"CS_MODE_M680X_6800", CS_OPT_MODE, CS_MODE_M680X_6800},
89 {"CS_MODE_M680X_6801", CS_OPT_MODE, CS_MODE_M680X_6801},
90 {"CS_MODE_M680X_6805", CS_OPT_MODE, CS_MODE_M680X_6805},
91 {"CS_MODE_M680X_6808", CS_OPT_MODE, CS_MODE_M680X_6808},
92 {"CS_MODE_M680X_6809", CS_OPT_MODE, CS_MODE_M680X_6809},
93 {"CS_MODE_M680X_6811", CS_OPT_MODE, CS_MODE_M680X_6811},
94 {"CS_MODE_M680X_CPU12", CS_OPT_MODE, CS_MODE_M680X_CPU12},
95 {"CS_MODE_M680X_HCS08", CS_OPT_MODE, CS_MODE_M680X_HCS08},
96 {"CS_OPT_UNSIGNED", CS_OPT_UNSIGNED, CS_OPT_ON}
97 };
98
99 char *(*function)(csh *, cs_mode, cs_insn*) = NULL;
100
test_single_MC(csh * handle,int mc_mode,char * line)101 void test_single_MC(csh *handle, int mc_mode, char *line)
102 {
103 char **list_part, **list_byte;
104 int size_part, size_byte, size_data, size_insn;
105 int i, count, count_noreg;
106 unsigned char *code;
107 cs_insn *insn;
108 char tmp[MAXMEM], tmp_mc[MAXMEM], origin[MAXMEM], tmp_noreg[MAXMEM];
109 char **offset_opcode;
110 int size_offset_opcode;
111 unsigned long offset;
112 char *p;
113
114 list_part = split(line, " = ", &size_part);
115 offset_opcode = split(list_part[0], ": ", &size_offset_opcode);
116 if (size_offset_opcode > 1) {
117 offset = (unsigned int)strtol(offset_opcode[0], NULL, 16);
118 list_byte = split(offset_opcode[1], ",", &size_byte);
119 } else {
120 offset = 0;
121 list_byte = split(offset_opcode[0], ",", &size_byte);
122 }
123
124 code = (unsigned char *)malloc(size_byte * sizeof(char));
125 for (i = 0; i < size_byte; ++i) {
126 code[i] = (unsigned char)strtol(list_byte[i], NULL, 16);
127 }
128
129 count = cs_disasm(*handle, code, size_byte, offset, 0, &insn);
130 if (count == 0) {
131 fprintf(stderr, "[ ERROR ] --- %s --- Failed to disassemble given code!\n", list_part[0]);
132 free_strs(list_part, size_part);
133 free_strs(offset_opcode, size_offset_opcode);
134 free_strs(list_byte, size_byte);
135 free(code);
136 _fail(__FILE__, __LINE__);
137 }
138 if (count > 1) {
139 fprintf(stderr, "[ ERROR ] --- %s --- Multiple instructions(%d) disassembling doesn't support!\n", list_part[0], count);
140 free_strs(list_part, size_part);
141 free_strs(offset_opcode, size_offset_opcode);
142 free_strs(list_byte, size_byte);
143 free(code);
144 _fail(__FILE__, __LINE__);
145 }
146
147 for (p = list_part[1]; *p; ++p) *p = tolower(*p);
148 for (p = list_part[1]; *p; ++p)
149 if (*p == '\t') *p = ' ';
150 trim_str(list_part[1]);
151 strcpy(tmp_mc, list_part[1]);
152 replace_hex(tmp_mc);
153 replace_negative(tmp_mc, mc_mode);
154
155 strcpy(tmp, insn[0].mnemonic);
156 if (strlen(insn[0].op_str) > 0) {
157 tmp[strlen(insn[0].mnemonic)] = ' ';
158 strcpy(tmp + strlen(insn[0].mnemonic) + 1, insn[0].op_str);
159 }
160
161 trim_str(tmp);
162 strcpy(origin, tmp);
163 replace_hex(tmp);
164 replace_negative(tmp, mc_mode);
165
166 if (cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME) == CS_ERR_OK) {
167 count_noreg = cs_disasm(*handle, code, size_byte, offset, 0, &insn);
168 strcpy(tmp_noreg, insn[0].mnemonic);
169 if (strlen(insn[0].op_str) > 0) {
170 tmp_noreg[strlen(insn[0].mnemonic)] = ' ';
171 strcpy(tmp_noreg + strlen(insn[0].mnemonic) + 1, insn[0].op_str);
172 }
173
174 trim_str(tmp_noreg);
175 replace_hex(tmp_noreg);
176 replace_negative(tmp_noreg, mc_mode);
177
178 if (strcmp(tmp, tmp_mc) && strcmp(tmp_noreg, tmp_mc)) {
179 fprintf(stderr, "[ ERROR ] --- %s --- \"%s\" != \"%s\" ( \"%s\" != \"%s\" and \"%s\" != \"%s\" )\n", list_part[0], origin, list_part[1], tmp, tmp_mc, tmp_noreg, tmp_mc);
180 free_strs(list_part, size_part);
181 free_strs(offset_opcode, size_offset_opcode);
182 free_strs(list_byte, size_byte);
183 free(code);
184 cs_free(insn, count);
185 _fail(__FILE__, __LINE__);
186 }
187
188 cs_option(*handle, CS_OPT_SYNTAX, 0);
189
190 } else if (strcmp(tmp, tmp_mc)) {
191 fprintf(stderr, "[ ERROR ] --- %s --- \"%s\" != \"%s\" ( \"%s\" != \"%s\" )\n", list_part[0], origin, list_part[1], tmp, tmp_mc);
192 free_strs(list_part, size_part);
193 free_strs(offset_opcode, size_offset_opcode);
194 free_strs(list_byte, size_byte);
195 free(code);
196 cs_free(insn, count);
197 _fail(__FILE__, __LINE__);
198 }
199
200 free_strs(list_part, size_part);
201 free_strs(offset_opcode, size_offset_opcode);
202 free_strs(list_byte, size_byte);
203 free(code);
204 cs_free(insn, count);
205 }
206
get_value(single_dict d[],unsigned int size,const char * str)207 int get_value(single_dict d[], unsigned int size, const char *str)
208 {
209 int i;
210
211 for (i = 0; i < size; ++i)
212 if (!strcmp(d[i].str, str))
213 return d[i].value;
214 return -1;
215 }
216
get_index(double_dict d[],unsigned int size,const char * s)217 int get_index(double_dict d[], unsigned int size, const char *s)
218 {
219 int i;
220
221 for (i = 0; i < size; ++i) {
222 if (!strcmp(s, d[i].str))
223 return i;
224 }
225 return -1;
226 }
227
set_function(int arch)228 int set_function(int arch)
229 {
230 switch(arch) {
231 case CS_ARCH_ARM:
232 function = get_detail_arm;
233 break;
234 case CS_ARCH_ARM64:
235 function = get_detail_arm64;
236 break;
237 case CS_ARCH_MIPS:
238 function = get_detail_mips;
239 break;
240 case CS_ARCH_PPC:
241 function = get_detail_ppc;
242 break;
243 case CS_ARCH_SPARC:
244 function = get_detail_sparc;
245 break;
246 case CS_ARCH_SYSZ:
247 function = get_detail_sysz;
248 break;
249 case CS_ARCH_X86:
250 function = get_detail_x86;
251 break;
252 case CS_ARCH_XCORE:
253 function = get_detail_xcore;
254 break;
255 case CS_ARCH_M68K:
256 function = get_detail_m68k;
257 break;
258 case CS_ARCH_M680X:
259 function = get_detail_m680x;
260 break;
261 case CS_ARCH_EVM:
262 function = get_detail_evm;
263 break;
264 case CS_ARCH_MOS65XX:
265 function = get_detail_mos65xx;
266 break;
267 case CS_ARCH_TMS320C64X:
268 function = get_detail_tms320c64x;
269 break;
270 default:
271 return -1;
272 }
273 return 0;
274 }
275
test_single_issue(csh * handle,cs_mode mode,char * line,int detail)276 void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
277 {
278 char **list_part, **list_byte, **list_part_cs_result, **list_part_issue_result;
279 int size_part, size_byte, size_part_cs_result, size_part_issue_result;
280 char *tmptmp;
281 int i, count, j;
282 unsigned char *code;
283 cs_insn *insn;
284 char *cs_result, *tmp, *p;
285 char **offset_opcode;
286 int size_offset_opcode;
287 unsigned long offset;
288
289 cs_result = (char *)malloc(sizeof(char));
290 cs_result[0] = '\0';
291
292 list_part = split(line, " == ", &size_part);
293
294 offset_opcode = split(list_part[0], ": ", &size_offset_opcode);
295 if (size_offset_opcode > 1) {
296 offset = (unsigned int)strtol(offset_opcode[0], NULL, 16);
297 list_byte = split(offset_opcode[1], ",", &size_byte);
298 } else {
299 offset = 0;
300 list_byte = split(offset_opcode[0], ",", &size_byte);
301 }
302
303 code = (unsigned char *)malloc(sizeof(char) * size_byte);
304 for (i = 0; i < size_byte; ++i) {
305 code[i] = (unsigned char)strtol(list_byte[i], NULL, 16);
306 }
307
308 count = cs_disasm(*handle, code, size_byte, offset, 0, &insn);
309 for (i = 0; i < count; ++i) {
310 tmp = (char *)malloc(strlen(insn[i].mnemonic) + strlen(insn[i].op_str) + 100);
311 strcpy(tmp, insn[i].mnemonic);
312 if (strlen(insn[i].op_str) > 0) {
313 tmp[strlen(insn[i].mnemonic)] = ' ';
314 strcpy(tmp + strlen(insn[i].mnemonic) + 1, insn[i].op_str);
315 }
316 add_str(&cs_result, "%s", tmp);
317 free(tmp);
318 }
319
320 if (detail == 1) {
321 tmp = (*function)(handle, mode, insn);
322 add_str(&cs_result, "%s", tmp);
323 free(tmp);
324
325 if (insn->detail->groups_count) {
326 add_str(&cs_result, " ; Groups: ");
327 for (j = 0; j < insn->detail->groups_count; j++) {
328 add_str(&cs_result, "%s ", cs_group_name(*handle, insn->detail->groups[j]));
329 }
330 }
331 }
332
333 trim_str(cs_result);
334 add_str(&cs_result, " ;");
335 // list_part_cs_result = split(cs_result, " ; ", &size_part_cs_result);
336 for (p = list_part[1]; *p; ++p) if (*p == '\t') *p = ' ';
337 list_part_issue_result = split(list_part[1], " ; ", &size_part_issue_result);
338
339 for (i = 0; i < size_part_issue_result; ++i) {
340 trim_str(list_part_issue_result[i]);
341 memset(tmptmp, MAXMEM, 0);
342
343 tmptmp = (char *)malloc(sizeof(char));
344 tmptmp[0] = '\0';
345 add_str(&tmptmp, "%s", list_part_issue_result[i]);
346 add_str(&tmptmp, " ;");
347
348 if ((strstr(cs_result, tmptmp)) == NULL) {
349 fprintf(stderr, "[ ERROR ] --- %s --- \"%s\" not in \"%s\"\n", list_part[0], list_part_issue_result[i], cs_result);
350 cs_free(insn, count);
351 free_strs(list_part, size_part);
352 free_strs(list_byte, size_byte);
353 free(cs_result);
354 // free_strs(list_part_cs_result, size_part_cs_result);
355 free_strs(list_part_issue_result, size_part_issue_result);
356 free(tmptmp);
357 _fail(__FILE__, __LINE__);
358 }
359 }
360
361 cs_free(insn, count);
362 free_strs(list_part, size_part);
363 free_strs(list_byte, size_byte);
364 free(cs_result);
365 // free_strs(list_part_cs_result, size_part_cs_result);
366 free_strs(list_part_issue_result, size_part_issue_result);
367 }
368