blob: 721ce8ff4015a01f7668285a752e863a163eab88 [file] [log] [blame]
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001/* Capstone Disassembler Engine */
2/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <inttypes.h>
7
8#include <capstone.h>
9
10struct platform {
11 cs_arch arch;
12 cs_mode mode;
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080013 unsigned char *code;
14 size_t size;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080015 char *comment;
Nguyen Anh Quynhb8ce68e2013-12-03 23:45:08 +080016 cs_opt_type opt_type;
17 cs_opt_value opt_value;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080018};
19
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080020static void print_string_hex(unsigned char *str, int len)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080021{
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080022 unsigned char *c;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080023
24 printf("Code: ");
25 for (c = str; c < str + len; c++) {
26 printf("0x%02x ", *c & 0xff);
27 }
28 printf("\n");
29}
30
31static void test()
32{
33#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
34#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
35#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00"
36//#define ARM_CODE "\x04\xe0\x2d\xe5"
37#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3"
38#define ARM_CODE2 "\x10\xf1\x10\xe7\x11\xf2\x31\xe7\xdc\xa1\x2e\xf3\xe8\x4e\x62\xf3"
39#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68"
40#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
41#define MIPS_CODE "\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56"
42#define MIPS_CODE2 "\x56\x34\x21\x34\xc2\x17\x01\x00"
43//#define ARM64_CODE "\x00\x40\x21\x4b" // sub w0, w0, w1, uxtw
44//#define ARM64_CODE "\x21\x7c\x02\x9b" // mul x1, x1, x2
45//#define ARM64_CODE "\x20\x74\x0b\xd5" // dc zva, x0
46//#define ARM64_CODE "\xe1\x0b\x40\xb9" // ldr w1, [sp, #0x8]
47#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9"
48
49 struct platform platforms[] = {
50 {
51 .arch = CS_ARCH_X86,
52 .mode = CS_MODE_16,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080053 .code = (unsigned char*)X86_CODE16,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080054 .size = sizeof(X86_CODE16) - 1,
55 .comment = "X86 16bit (Intel syntax)"
56 },
57 {
58 .arch = CS_ARCH_X86,
Nguyen Anh Quynh01aba002013-12-03 21:00:09 +080059 .mode = CS_MODE_32,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080060 .code = (unsigned char*)X86_CODE32,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080061 .size = sizeof(X86_CODE32) - 1,
Nguyen Anh Quynh01aba002013-12-03 21:00:09 +080062 .comment = "X86 32bit (ATT syntax)",
Nguyen Anh Quynhb8ce68e2013-12-03 23:45:08 +080063 .opt_type = CS_OPT_SYNTAX,
Nguyen Anh Quynhc618db42013-12-04 00:05:04 +080064 .opt_value = CS_OPT_SYNTAX_ATT,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080065 },
66 {
67 .arch = CS_ARCH_X86,
68 .mode = CS_MODE_32,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080069 .code = (unsigned char*)X86_CODE32,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080070 .size = sizeof(X86_CODE32) - 1,
71 .comment = "X86 32 (Intel syntax)"
72 },
73 {
74 .arch = CS_ARCH_X86,
75 .mode = CS_MODE_64,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080076 .code = (unsigned char*)X86_CODE64,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080077 .size = sizeof(X86_CODE64) - 1,
78 .comment = "X86 64 (Intel syntax)"
79 },
80 {
81 .arch = CS_ARCH_ARM,
82 .mode = CS_MODE_ARM,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080083 .code = (unsigned char*)ARM_CODE,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080084 .size = sizeof(ARM_CODE) - 1,
85 .comment = "ARM"
86 },
87 {
88 .arch = CS_ARCH_ARM,
89 .mode = CS_MODE_THUMB,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080090 .code = (unsigned char*)THUMB_CODE2,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080091 .size = sizeof(THUMB_CODE2) - 1,
92 .comment = "THUMB-2"
93 },
94 {
95 .arch = CS_ARCH_ARM,
96 .mode = CS_MODE_ARM,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +080097 .code = (unsigned char*)ARM_CODE2,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080098 .size = sizeof(ARM_CODE2) - 1,
99 .comment = "ARM: Cortex-A15 + NEON"
100 },
101 {
102 .arch = CS_ARCH_ARM,
103 .mode = CS_MODE_THUMB,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800104 .code = (unsigned char*)THUMB_CODE,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800105 .size = sizeof(THUMB_CODE) - 1,
106 .comment = "THUMB"
107 },
108 {
109 .arch = CS_ARCH_MIPS,
110 .mode = CS_MODE_32 + CS_MODE_BIG_ENDIAN,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800111 .code = (unsigned char*)MIPS_CODE,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800112 .size = sizeof(MIPS_CODE) - 1,
113 .comment = "MIPS-32 (Big-endian)"
114 },
115 {
116 .arch = CS_ARCH_MIPS,
117 .mode = CS_MODE_64+ CS_MODE_LITTLE_ENDIAN,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800118 .code = (unsigned char*)MIPS_CODE2,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800119 .size = sizeof(MIPS_CODE2) - 1,
120 .comment = "MIPS-64-EL (Little-endian)"
121 },
122 {
123 .arch = CS_ARCH_ARM64,
124 .mode = CS_MODE_ARM,
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800125 .code = (unsigned char*)ARM64_CODE,
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800126 .size = sizeof(ARM64_CODE) - 1,
127 .comment = "ARM-64"
128 },
129 };
130
131 csh handle;
Nguyen Anh Quynh5df9e4b2013-12-03 15:02:12 +0800132 uint64_t address = 0x1000;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800133 //cs_insn insn[16];
134 cs_insn *insn;
135 int i;
136
137 for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
138 cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
139 if (err) {
140 printf("Failed on cs_open() with error returned: %u\n", err);
141 return;
142 }
143
Nguyen Anh Quynhb8ce68e2013-12-03 23:45:08 +0800144 if (platforms[i].opt_type)
145 cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);
Nguyen Anh Quynh01aba002013-12-03 21:00:09 +0800146
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800147 //size_t count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, insn);
148 size_t count = cs_disasm_dyn(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800149 if (count) {
150 printf("****************\n");
151 printf("Platform: %s\n", platforms[i].comment);
152 print_string_hex(platforms[i].code, platforms[i].size);
153 printf("Disasm:\n");
154
Nguyen Anh Quynhb42a6572013-11-29 17:40:07 +0800155 size_t j;
Nguyen Anh Quynh723687e2013-11-29 22:36:45 +0800156
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800157 for (j = 0; j < count; j++) {
Nguyen Anh Quynh723687e2013-11-29 22:36:45 +0800158 printf("0x%"PRIx64":\t%s\t\t%s\n",
Nguyen Anh Quynh7b7b40c2013-12-03 12:24:06 +0800159 insn[j].address, insn[j].mnemonic, insn[j].op_str);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800160 }
161
162 // print out the next offset, after the last insn
Nguyen Anh Quynh7b7b40c2013-12-03 12:24:06 +0800163 printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800164
165 // free memory allocated by cs_disasm_dyn()
166 cs_free(insn);
167 } else {
168 printf("****************\n");
169 printf("Platform: %s\n", platforms[i].comment);
170 print_string_hex(platforms[i].code, platforms[i].size);
171 printf("ERROR: Failed to disasm given code!\n");
172 }
173
174 printf("\n");
175
176 cs_close(handle);
177 }
178}
179
180int main()
181{
182 test();
183
184#if 0
185 #define offsetof(type, member) (int)(&((type *)0)->member)
Nguyen Anh Quynh723687e2013-11-29 22:36:45 +0800186
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800187 cs_insn insn;
188 printf("size: %lu\n", sizeof(insn));
189 printf("@id: %u\n", offsetof(cs_insn, id));
190 printf("@address: %u\n", offsetof(cs_insn, address));
191 printf("@size: %u\n", offsetof(cs_insn, size));
192 printf("@mnemonic: %u\n", offsetof(cs_insn, mnemonic));
193 printf("@op_str: %u\n", offsetof(cs_insn, op_str));
194 printf("@regs_read: %u\n", offsetof(cs_insn, regs_read));
Nguyen Anh Quynhf35e2ad2013-12-03 11:10:26 +0800195 printf("@regs_read_count: %u\n", offsetof(cs_insn, regs_read_count));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800196 printf("@regs_write: %u\n", offsetof(cs_insn, regs_write));
Nguyen Anh Quynhf35e2ad2013-12-03 11:10:26 +0800197 printf("@regs_write_count: %u\n", offsetof(cs_insn, regs_write_count));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800198 printf("@groups: %u\n", offsetof(cs_insn, groups));
Nguyen Anh Quynhf35e2ad2013-12-03 11:10:26 +0800199 printf("@groups_count: %u\n", offsetof(cs_insn, groups_count));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800200 printf("@arch: %u\n", offsetof(cs_insn, x86));
201#endif
202
203 return 0;
204}