blob: 1b21f27ee8b8b2e82268ad478ac8e28954d0380d [file] [log] [blame]
Nguyen Anh Quynh863ec0a2018-03-31 17:32:22 +08001/* Capstone Disassembler Engine */
2/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2018 */
3
4#include <stdio.h>
5#include <stdlib.h>
6
7#include <capstone/platform.h>
8#include <capstone/capstone.h>
9
10static csh handle;
11
12struct platform {
13 cs_arch arch;
14 cs_mode mode;
15 unsigned char *code;
16 size_t size;
Nguyen Anh Quynh2fc852d2018-07-24 01:41:59 +080017 const char *comment;
Nguyen Anh Quynh863ec0a2018-03-31 17:32:22 +080018};
19
Nguyen Anh Quynh2fc852d2018-07-24 01:41:59 +080020static void print_string_hex(const char *comment, unsigned char *str, size_t len)
Nguyen Anh Quynh863ec0a2018-03-31 17:32:22 +080021{
22 unsigned char *c;
23
24 printf("%s", comment);
25 for (c = str; c < str + len; c++) {
26 printf("0x%02x ", *c & 0xff);
27 }
28
29 printf("\n");
30}
31
32static void print_insn_detail(csh cs_handle, cs_insn *ins)
33{
34 cs_evm *evm;
35
36 // detail can be NULL on "data" instruction if SKIPDATA option is turned ON
37 if (ins->detail == NULL)
38 return;
39
40 evm = &(ins->detail->evm);
41
42 if (evm->pop)
43 printf("\tPop: %u\n", evm->pop);
44
45 if (evm->push)
46 printf("\tPush: %u\n", evm->push);
47
48 if (evm->fee)
49 printf("\tGas fee: %u\n", evm->fee);
50
51 if (ins->detail->groups_count) {
52 int j;
53
54 printf("\tGroups: ");
55 for(j = 0; j < ins->detail->groups_count; j++) {
56 printf("%s ", cs_group_name(handle, ins->detail->groups[j]));
57 }
58 printf("\n");
59 }
60}
61
62static void test()
63{
64#define EVM_CODE "\x60\x61\x50"
65
66 struct platform platforms[] = {
67 {
68 CS_ARCH_EVM,
69 0,
70 (unsigned char *)EVM_CODE,
71 sizeof(EVM_CODE) - 1,
72 "EVM"
73 },
74 };
75
76 uint64_t address = 0x80001000;
77 cs_insn *insn;
78 int i;
79 size_t count;
80
81 for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
82 cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
83 if (err) {
84 printf("Failed on cs_open() with error returned: %u\n", err);
85 abort();
86 }
87
88 cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
89
90 count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
91 if (count) {
92 size_t j;
93 printf("****************\n");
94 printf("Platform: %s\n", platforms[i].comment);
95 print_string_hex("Code:", platforms[i].code, platforms[i].size);
96 printf("Disasm:\n");
97
98 for (j = 0; j < count; j++) {
99 printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
100 print_insn_detail(handle, &insn[j]);
101 }
102 printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);
103
104 // free memory allocated by cs_disasm()
105 cs_free(insn, count);
106 } else {
107 printf("****************\n");
108 printf("Platform: %s\n", platforms[i].comment);
109 print_string_hex("Code:", platforms[i].code, platforms[i].size);
110 printf("ERROR: Failed to disasm given code!\n");
111 abort();
112 }
113
114 printf("\n");
115
116 cs_close(&handle);
117 }
118}
119
120int main()
121{
122 test();
123
124 return 0;
125}
126