1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <inttypes.h>
4 #include <capstone.h>
5
6 struct platform {
7 cs_arch arch;
8 cs_mode mode;
9 char *comment;
10 };
11
main(int argc,char ** argv)12 int 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 },
110 {
111 CS_ARCH_M68K,
112 (cs_mode)0,
113 "M68K"
114 },
115 {
116 CS_ARCH_M680X,
117 (cs_mode)CS_MODE_M680X_6809,
118 "M680X_M6809"
119 },
120 };
121
122 // Read input
123 long bufsize = 0;
124 unsigned char *buf = NULL;
125 FILE *fp = fopen(argv[1], "r");
126
127 if (fp == NULL) return 1;
128
129 if (fseek(fp, 0L, SEEK_END) == 0) {
130 bufsize = ftell(fp);
131
132 if (bufsize == -1) return 1;
133
134 buf = malloc(bufsize + 1);
135
136 if (buf == NULL) return 1;
137 if (fseek(fp, 0L, SEEK_SET) != 0) return 1;
138
139 size_t len = fread(buf, sizeof(char), bufsize, fp);
140
141 if (len == 0) return 2;
142 }
143 fclose(fp);
144
145 // Disassemble
146 csh handle;
147 cs_insn *all_insn;
148 cs_detail *detail;
149 cs_err err;
150
151 if (bufsize < 3) return 0;
152
153 int platforms_len = sizeof(platforms)/sizeof(platforms[0]);
154 int i = (int)buf[0] % platforms_len;
155
156 unsigned char *buf_ptr = buf + 1;
157 long buf_ptr_size = bufsize - 1;
158
159 printf("Platform: %s (0x%.2x of 0x%.2x)\n", platforms[i].comment, i, platforms_len);
160
161 err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
162 if (err) {
163 printf("Failed on cs_open() with error returned: %u\n", err);
164 return 1;
165 }
166
167 cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
168
169 uint64_t address = 0x1000;
170 size_t count = cs_disasm(handle, buf_ptr, buf_ptr_size, address, 0, &all_insn);
171
172 if (count) {
173 size_t j;
174 int n;
175
176 printf("Disasm:\n");
177
178 for (j = 0; j < count; j++) {
179 cs_insn *i = &(all_insn[j]);
180 printf("0x%"PRIx64":\t%s\t\t%s // insn-ID: %u, insn-mnem: %s\n",
181 i->address, i->mnemonic, i->op_str,
182 i->id, cs_insn_name(handle, i->id));
183
184 detail = i->detail;
185
186 if (detail->regs_read_count > 0) {
187 printf("\tImplicit registers read: ");
188 for (n = 0; n < detail->regs_read_count; n++) {
189 printf("%s ", cs_reg_name(handle, detail->regs_read[n]));
190 }
191 printf("\n");
192 }
193
194 if (detail->regs_write_count > 0) {
195 printf("\tImplicit registers modified: ");
196 for (n = 0; n < detail->regs_write_count; n++) {
197 printf("%s ", cs_reg_name(handle, detail->regs_write[n]));
198 }
199 printf("\n");
200 }
201
202 if (detail->groups_count > 0) {
203 printf("\tThis instruction belongs to groups: ");
204 for (n = 0; n < detail->groups_count; n++) {
205 printf("%s ", cs_group_name(handle, detail->groups[n]));
206 }
207 printf("\n");
208 }
209 }
210 printf("0x%"PRIx64":\n", all_insn[j-1].address + all_insn[j-1].size);
211 cs_free(all_insn, count);
212 } else {
213 printf("ERROR: Failed to disasm given code!\n");
214 }
215
216 printf("\n");
217
218 free(buf);
219 cs_close(&handle);
220
221 return 0;
222 }
223