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