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