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