blob: 303c553cbadcf0b2ba2a7657c40a7e1d3992f72a [file] [log] [blame]
YUHANG TANGa7b48522016-10-19 22:28:05 +08001/* Tang Yuhang <tyh000011112222@gmail.com> 2016 */
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +02002/* pancake <pancake@nopcode.org> 2017 */
3
echotyh51c8c502016-10-10 15:16:56 +08004#include <string.h>
5#include <ctype.h>
6#include <errno.h>
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +02007#include "getopt.h"
echotyh51c8c502016-10-10 15:16:56 +08008
Nguyen Anh Quynh56649982016-10-11 00:04:46 +08009#include <capstone/capstone.h>
echotyh51c8c502016-10-10 15:16:56 +080010
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +020011static struct {
12 const char *name;
13 cs_arch arch;
14 cs_mode mode;
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +080015} all_archs[] = {
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +020016 { "arm", CS_ARCH_ARM, CS_MODE_ARM },
17 { "armb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
18 { "armbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
19 { "arml", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
20 { "armle", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
Priit Laes3a6ccaf2018-03-20 00:52:33 +000021 { "cortexm", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_MCLASS },
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +020022 { "thumb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB },
23 { "thumbbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN },
24 { "thumble", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN },
25 { "arm64", CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN },
26 { "arm64be", CS_ARCH_ARM64, CS_MODE_BIG_ENDIAN },
27 { "mips", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN },
28 { "mipsbe", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_BIG_ENDIAN },
29 { "mips64", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN },
30 { "mips64be", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN },
31 { "x16", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16
32 { "x16att", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16 , CS_OPT_SYNTAX_ATT
33 { "x32", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32
34 { "x32att", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32, CS_OPT_SYNTAX_ATT
35 { "x64", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64
36 { "x64att", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64, CS_OPT_SYNTAX_ATT
37 { "ppc64", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_LITTLE_ENDIAN },
38 { "ppc64be", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN },
39 { "sparc", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN },
40 { "systemz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
41 { "sysz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
42 { "s390x", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
43 { "xcore", CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN },
44 { "m68k", CS_ARCH_M68K, CS_MODE_BIG_ENDIAN },
45 { "m68k40", CS_ARCH_M68K, CS_MODE_M68K_040 },
46 { "tms320c64x", CS_ARCH_TMS320C64X, CS_MODE_BIG_ENDIAN },
47 { "tms320c64x", CS_ARCH_TMS320C64X, CS_MODE_BIG_ENDIAN },
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +020048 { "m6800", CS_ARCH_M680X, CS_MODE_M680X_6800 },
49 { "m6801", CS_ARCH_M680X, CS_MODE_M680X_6801 },
50 { "m6805", CS_ARCH_M680X, CS_MODE_M680X_6805 },
51 { "m6808", CS_ARCH_M680X, CS_MODE_M680X_6808 },
52 { "m6809", CS_ARCH_M680X, CS_MODE_M680X_6809 },
53 { "m6811", CS_ARCH_M680X, CS_MODE_M680X_6811 },
54 { "cpu12", CS_ARCH_M680X, CS_MODE_M680X_CPU12 },
55 { "hd6301", CS_ARCH_M680X, CS_MODE_M680X_6301 },
56 { "hd6309", CS_ARCH_M680X, CS_MODE_M680X_6309 },
57 { "hcs08", CS_ARCH_M680X, CS_MODE_M680X_HCS08 },
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +080058 { "evm", CS_ARCH_EVM, 0 },
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +020059 { NULL }
60};
61
YUHANG TANG9354e5e2016-10-14 17:29:56 +080062void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins);
YUHANG TANG08da0c02016-10-14 20:47:29 +080063void print_insn_detail_arm(csh handle, cs_insn *ins);
64void print_insn_detail_arm64(csh handle, cs_insn *ins);
65void print_insn_detail_mips(csh handle, cs_insn *ins);
66void print_insn_detail_ppc(csh handle, cs_insn *ins);
67void print_insn_detail_sparc(csh handle, cs_insn *ins);
68void print_insn_detail_sysz(csh handle, cs_insn *ins);
69void print_insn_detail_xcore(csh handle, cs_insn *ins);
YUHANG TANG9bc14c12016-10-28 15:32:50 +080070void print_insn_detail_m68k(csh handle, cs_insn *ins);
Fotis Loukos44ca0e32017-04-17 11:58:29 +030071void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +020072void print_insn_detail_m680x(csh handle, cs_insn *ins);
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +080073void print_insn_detail_evm(csh handle, cs_insn *ins);
74
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +020075static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins);
YUHANG TANG9354e5e2016-10-14 17:29:56 +080076
Nguyen Anh Quynh2fc852d2018-07-24 01:41:59 +080077void print_string_hex(const char *comment, unsigned char *str, size_t len)
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +080078{
79 unsigned char *c;
80
81 printf("%s", comment);
82 for (c = str; c < str + len; c++) {
83 printf("0x%02x ", *c & 0xff);
84 }
85
86 printf("\n");
87}
88
echotyh51c8c502016-10-10 15:16:56 +080089// convert hexchar to hexnum
90static uint8_t char_to_hexnum(char c)
91{
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +080092 if (c >= '0' && c <= '9') {
YUHANG TANGbde12ae2016-10-21 16:03:35 +080093 return (uint8_t)(c - '0');
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +080094 }
95
96 if (c >= 'a' && c <= 'f') {
97 return (uint8_t)(10 + c - 'a');
98 }
99
100 // c >= 'A' && c <= 'F'
101 return (uint8_t)(10 + c - 'A');
echotyh51c8c502016-10-10 15:16:56 +0800102}
103
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800104// convert user input (char[]) to uint8_t[], each element of which is
105// valid hexadecimal, and return actual length of uint8_t[] in @size.
echotyh51c8c502016-10-10 15:16:56 +0800106static uint8_t *preprocess(char *code, size_t *size)
107{
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800108 size_t i = 0, j = 0;
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800109 uint8_t high, low;
110 uint8_t *result;
echotyh51c8c502016-10-10 15:16:56 +0800111
Nguyen Anh Quynhfef1c292017-07-26 23:22:46 +0800112 if (strlen(code) == 0)
113 return NULL;
114
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800115 result = (uint8_t *)malloc(strlen(code));
116 if (result != NULL) {
117 while (code[i] != '\0') {
118 if (isxdigit(code[i]) && isxdigit(code[i+1])) {
119 high = 16 * char_to_hexnum(code[i]);
120 low = char_to_hexnum(code[i+1]);
121 result[j] = high + low;
122 i++;
123 j++;
124 }
125 i++;
126 }
127 *size = j;
128 }
129
130 return result;
echotyh51c8c502016-10-10 15:16:56 +0800131}
132
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800133static void usage(char *prog)
echotyh51c8c502016-10-10 15:16:56 +0800134{
Nguyen Anh Quynh7532fc72016-11-04 23:57:52 +0800135 printf("Cstool for Capstone Disassembler Engine v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
radare9af97422017-06-15 20:13:28 +0200136 printf("Syntax: %s [-u|-d] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800137 printf("\nThe following <arch+mode> options are supported:\n");
138
139 if (cs_support(CS_ARCH_X86)) {
140 printf(" x16: 16-bit mode (X86)\n");
141 printf(" x32: 32-bit mode (X86)\n");
142 printf(" x64: 64-bit mode (X86)\n");
143 printf(" x16att: 16-bit mode (X86) syntax-att\n");
144 printf(" x32att: 32-bit mode (X86) syntax-att\n");
145 printf(" x64att: 64-bit mode (X86) syntax-att\n");
146 }
147
148 if (cs_support(CS_ARCH_ARM)) {
149 printf(" arm: arm\n");
Nguyen Anh Quynh996db1f2017-03-10 20:30:55 +0800150 printf(" armbe: arm + big endian\n");
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800151 printf(" thumb: thumb mode\n");
152 printf(" thumbbe: thumb + big endian\n");
Priit Laes3a6ccaf2018-03-20 00:52:33 +0000153 printf(" cortexm: thumb + cortex-m extensions\n");
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800154 }
155
156 if (cs_support(CS_ARCH_ARM64)) {
157 printf(" arm64: aarch64 mode\n");
Nguyen Anh Quynh6d609eb2017-04-25 21:33:26 +0800158 printf(" arm64be: aarch64 + big endian\n");
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800159 }
160
161 if (cs_support(CS_ARCH_MIPS)) {
162 printf(" mips: mips32 + little endian\n");
163 printf(" mipsbe: mips32 + big endian\n");
164 printf(" mips64: mips64 + little endian\n");
165 printf(" mips64be: mips64 + big endian\n");
166 }
167
168 if (cs_support(CS_ARCH_PPC)) {
169 printf(" ppc64: ppc64 + little endian\n");
170 printf(" ppc64be: ppc64 + big endian\n");
171 }
172
173 if (cs_support(CS_ARCH_SPARC)) {
174 printf(" sparc: sparc\n");
175 }
176
177 if (cs_support(CS_ARCH_SYSZ)) {
178 printf(" systemz: systemz (s390x)\n");
179 }
180
181 if (cs_support(CS_ARCH_XCORE)) {
182 printf(" xcore: xcore\n");
183 }
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +0800184
YUHANG TANGbe3f8672016-10-27 12:12:59 +0800185 if (cs_support(CS_ARCH_M68K)) {
Nguyen Anh Quynhdf6f9cc2016-10-28 16:12:05 +0800186 printf(" m68k: m68k + big endian\n");
YUHANG TANGbe3f8672016-10-27 12:12:59 +0800187 printf(" m68k40: m68k_040\n");
YUHANG TANGbe3f8672016-10-27 12:12:59 +0800188 }
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800189
Fotis Loukos44ca0e32017-04-17 11:58:29 +0300190 if (cs_support(CS_ARCH_TMS320C64X)) {
191 printf(" tms320c64x:TMS320C64x\n");
192 }
193
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +0800194 if (cs_support(CS_ARCH_M680X)) {
195 printf(" m6800: M6800/2\n");
196 printf(" m6801: M6801/3\n");
197 printf(" m6805: M6805\n");
198 printf(" m6808: M68HC08\n");
199 printf(" m6809: M6809\n");
200 printf(" m6811: M68HC11\n");
201 printf(" cpu12: M68HC12/HCS12\n");
202 printf(" hd6301: HD6301/3\n");
203 printf(" hd6309: HD6309\n");
204 printf(" hcs08: HCS08\n");
205 }
206
207 if (cs_support(CS_ARCH_EVM)) {
208 printf(" evm: Ethereum Virtual Machine\n");
209 }
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +0200210
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800211 printf("\nExtra options:\n");
212 printf(" -d show detailed information of the instructions\n");
213 printf(" -u show immediates as unsigned\n\n");
echotyh51c8c502016-10-10 15:16:56 +0800214}
215
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200216static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
217{
218 switch(arch) {
219 case CS_ARCH_X86:
220 print_insn_detail_x86(handle, md, ins);
221 break;
222 case CS_ARCH_ARM:
223 print_insn_detail_arm(handle, ins);
224 break;
225 case CS_ARCH_ARM64:
226 print_insn_detail_arm64(handle, ins);
227 break;
228 case CS_ARCH_MIPS:
229 print_insn_detail_mips(handle, ins);
230 break;
231 case CS_ARCH_PPC:
232 print_insn_detail_ppc(handle, ins);
233 break;
234 case CS_ARCH_SPARC:
235 print_insn_detail_sparc(handle, ins);
236 break;
237 case CS_ARCH_SYSZ:
238 print_insn_detail_sysz(handle, ins);
239 break;
240 case CS_ARCH_XCORE:
241 print_insn_detail_xcore(handle, ins);
242 break;
243 case CS_ARCH_M68K:
244 print_insn_detail_m68k(handle, ins);
245 break;
246 case CS_ARCH_TMS320C64X:
247 print_insn_detail_tms320c64x(handle, ins);
248 break;
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +0800249 case CS_ARCH_M680X:
250 print_insn_detail_m680x(handle, ins);
251 break;
252 case CS_ARCH_EVM:
253 print_insn_detail_evm(handle, ins);
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +0200254 break;
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200255 default: break;
256 }
257
258 if (ins->detail->groups_count) {
259 int j;
260
261 printf("\tGroups: ");
262 for(j = 0; j < ins->detail->groups_count; j++) {
263 printf("%s ", cs_group_name(handle, ins->detail->groups[j]));
264 }
265 printf("\n");
266 }
267
268 printf("\n");
269}
270
echotyh51c8c502016-10-10 15:16:56 +0800271int main(int argc, char **argv)
272{
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200273 int i, c;
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800274 csh handle;
275 char *mode;
276 uint8_t *assembly;
277 size_t count, size;
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200278 uint64_t address = 0LL;
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800279 cs_insn *insn;
280 cs_err err;
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800281 cs_mode md;
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +0200282 cs_arch arch = CS_ARCH_ALL;
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800283 bool detail_flag = false;
radare9af97422017-06-15 20:13:28 +0200284 bool unsigned_flag = false;
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800285 int args_left;
echotyh51c8c502016-10-10 15:16:56 +0800286
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200287 while ((c = getopt (argc, argv, "udhv")) != -1) {
288 switch (c) {
Nguyen Anh Quynhed1246d2018-03-31 17:29:22 +0800289 case 'u':
290 unsigned_flag = true;
291 break;
292 case 'd':
293 detail_flag = true;
294 break;
295 case 'v':
296 printf("%u.%u.%u\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
297 return 0;
298 case 'h':
299 usage(argv[0]);
300 return 0;
301 default:
302 usage(argv[0]);
303 return -1;
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200304 }
305 }
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800306
307 args_left = argc - optind;
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200308 if (args_left < 2 || args_left > 3) {
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800309 usage(argv[0]);
310 return -1;
311 }
echotyh51c8c502016-10-10 15:16:56 +0800312
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200313 mode = argv[optind];
314 assembly = preprocess(argv[optind + 1], &size);
Nguyen Anh Quynhfef1c292017-07-26 23:22:46 +0800315 if (!assembly) {
316 usage(argv[0]);
317 return -1;
318 }
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800319
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200320 if (args_left == 3) {
321 char *temp, *src = argv[optind + 2];
322 address = strtoull(src, &temp, 16);
323 if (temp == src || *temp != '\0' || errno == ERANGE) {
324 printf("ERROR: invalid address argument, quit!\n");
325 return -2;
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800326 }
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200327 }
328
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800329 for (i = 0; all_archs[i].name; i++) {
330 if (!strcmp(all_archs[i].name, mode)) {
331 arch = all_archs[i].arch;
332 err = cs_open(all_archs[i].arch, all_archs[i].mode, &handle);
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200333 if (!err) {
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800334 md = all_archs[i].mode;
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200335 if (strstr (mode, "att")) {
336 cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
337 }
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800338 }
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200339 break;
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800340 }
Fotis Loukos44ca0e32017-04-17 11:58:29 +0300341 }
342
Wolfgang Schwotzer22b4d0e2017-10-21 15:44:36 +0200343 if (arch == CS_ARCH_ALL) {
344 printf("ERROR: Invalid <arch+mode>: \"%s\", quit!\n", mode);
345 usage(argv[0]);
346 return -1;
347 }
348
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800349 if (err) {
350 printf("ERROR: Failed on cs_open(), quit!\n");
351 usage(argv[0]);
352 return -1;
353 }
354
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800355 if (detail_flag) {
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800356 cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
357 }
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800358
radare9af97422017-06-15 20:13:28 +0200359 if (unsigned_flag) {
360 cs_option(handle, CS_OPT_UNSIGNED, CS_OPT_ON);
361 }
YUHANG TANG9354e5e2016-10-14 17:29:56 +0800362
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800363 count = cs_disasm(handle, assembly, size, address, 0, &insn);
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800364 if (count > 0) {
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800365 size_t i;
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800366
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800367 for (i = 0; i < count; i++) {
368 int j;
Nguyen Anh Quynh13e06982017-07-04 16:04:53 +0800369
Nguyen Anh Quynhe965a582017-10-25 01:03:24 +0800370 printf("%2"PRIx64" ", insn[i].address);
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800371 for (j = 0; j < insn[i].size; j++) {
Ruslan Kabatsayev4aec4de2017-09-06 17:35:19 +0400372 if (j > 0)
373 putchar(' ');
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800374 printf("%02x", insn[i].bytes[j]);
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800375 }
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800376 // X86 instruction size is variable.
377 // align assembly instruction after the opcode
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800378 if (arch == CS_ARCH_X86) {
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800379 for (; j < 16; j++) {
Nguyen Anh Quynhe965a582017-10-25 01:03:24 +0800380 printf(" ");
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800381 }
382 }
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800383
Nguyen Anh Quynhbab2a932016-10-11 16:19:27 +0800384 printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
Nguyen Anh Quynh32238dc2016-10-21 16:42:47 +0800385
386 if (detail_flag) {
Sergi Àlvarez i Capillacff66502017-07-04 09:55:46 +0200387 print_details(handle, arch, md, &insn[i]);
YUHANG TANGbde12ae2016-10-21 16:03:35 +0800388 }
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800389 }
Nguyen Anh Quynh570db5f2016-11-05 00:43:22 +0800390
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800391 cs_free(insn, count);
392 } else {
393 printf("ERROR: invalid assembly code\n");
394 return(-4);
395 }
396
397 cs_close(&handle);
Riccardo Schironee8a818d2018-07-24 04:19:07 +0200398 free(assembly);
Nguyen Anh Quynh815b94a2016-10-10 23:20:29 +0800399
400 return 0;
echotyh51c8c502016-10-10 15:16:56 +0800401}