• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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