• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 
10 static csh handle;
11 
12 struct platform {
13 	cs_arch arch;
14 	cs_mode mode;
15 	unsigned char *code;
16 	size_t size;
17 	const char *comment;
18 };
19 
print_string_hex(const char * comment,unsigned char * str,size_t len)20 static void print_string_hex(const char *comment, unsigned char *str, size_t len)
21 {
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 
print_insn_detail(csh cs_handle,cs_insn * ins)32 static 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 
test()62 static 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 
main()120 int main()
121 {
122 	test();
123 
124 	return 0;
125 }
126 
127