• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1(* Capstone Disassembly Engine
2* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 *)
3
4open Printf
5open Capstone
6open M680x
7open M680x_const
8
9
10let print_char_hex ch =
11	printf " 0x%02X" (Char.code ch)
12
13let print_int_hex_short value =
14	printf "%02X" value
15
16let print_string_hex comment str =
17	printf "%s" comment;
18	String.iter print_char_hex str;
19	printf "\n"
20
21let print_array_hex_short arr =
22	Array.iter print_int_hex_short arr
23
24let s_access = [
25	"UNCHANGED"; "READ"; "WRITE"; "READ | WRITE" ];;
26
27let _M6800_CODE = "\x01\x09\x36\x64\x7f\x74\x10\x00\x90\x10\xA4\x10\xb6\x10\x00\x39";;
28let _M6801_CODE = "\x04\x05\x3c\x3d\x38\x93\x10\xec\x10\xed\x10\x39";;
29let _M6805_CODE = "\x04\x7f\x00\x17\x22\x28\x00\x2e\x00\x40\x42\x5a\x70\x8e\x97\x9c\xa0\x15\xad\x00\xc3\x10\x00\xda\x12\x34\xe5\x7f\xfe";;
30let _M6808_CODE = "\x31\x22\x00\x35\x22\x45\x10\x00\x4b\x00\x51\x10\x52\x5e\x22\x62\x65\x12\x34\x72\x84\x85\x86\x87\x8a\x8b\x8c\x94\x95\xa7\x10\xaf\x10\x9e\x60\x7f\x9e\x6b\x7f\x00\x9e\xd6\x10\x00\x9e\xe6\x7f";;
31let _HD6301_CODE = "\x6b\x10\x00\x71\x10\x00\x72\x10\x10\x39";;
32let _M6809_CODE = "\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39\xA6\x07\xA6\x27\xA6\x47\xA6\x67\xA6\x0F\xA6\x10\xA6\x80\xA6\x81\xA6\x82\xA6\x83\xA6\x84\xA6\x85\xA6\x86\xA6\x88\x7F\xA6\x88\x80\xA6\x89\x7F\xFF\xA6\x89\x80\x00\xA6\x8B\xA6\x8C\x10\xA6\x8D\x10\x00\xA6\x91\xA6\x93\xA6\x94\xA6\x95\xA6\x96\xA6\x98\x7F\xA6\x98\x80\xA6\x99\x7F\xFF\xA6\x99\x80\x00\xA6\x9B\xA6\x9C\x10\xA6\x9D\x10\x00\xA6\x9F\x10\x00";;
33let _HD6309_CODE = "\x01\x10\x10\x62\x10\x10\x7b\x10\x10\x00\xcd\x49\x96\x02\xd2\x10\x30\x23\x10\x38\x10\x3b\x10\x53\x10\x5d\x11\x30\x43\x10\x11\x37\x25\x10\x11\x38\x12\x11\x39\x23\x11\x3b\x34\x11\x8e\x10\x00\x11\xaf\x10\x11\xab\x10\x11\xf6\x80\x00";;
34let _M6811_CODE = "\x02\x03\x12\x7f\x10\x00\x13\x99\x08\x00\x14\x7f\x02\x15\x7f\x01\x1e\x7f\x20\x00\x8f\xcf\x18\x08\x18\x30\x18\x3c\x18\x67\x18\x8c\x10\x00\x18\x8f\x18\xce\x10\x00\x18\xff\x10\x00\x1a\xa3\x7f\x1a\xac\x1a\xee\x7f\x1a\xef\x7f\xcd\xac\x7f";;
35let _CPU12_CODE = "\x00\x04\x01\x00\x0c\x00\x80\x0e\x00\x80\x00\x11\x1e\x10\x00\x80\x00\x3b\x4a\x10\x00\x04\x4b\x01\x04\x4f\x7f\x80\x00\x8f\x10\x00\xb7\x52\xb7\xb1\xa6\x67\xa6\xfe\xa6\xf7\x18\x02\xe2\x30\x39\xe2\x10\x00\x18\x0c\x30\x39\x10\x00\x18\x11\x18\x12\x10\x00\x18\x19\x00\x18\x1e\x00\x18\x3e\x18\x3f\x00";;
36let _HCS08_CODE = "\x32\x10\x00\x9e\xae\x9e\xce\x7f\x9e\xbe\x10\x00\x9e\xfe\x7f\x3e\x10\x00\x9e\xf3\x7f\x96\x10\x00\x9e\xff\x7f\x82";;
37
38let bit_set value mask =
39	value land mask != 0
40
41let all_tests = [
42        (CS_ARCH_M680X, [CS_MODE_M680X_6301], _HD6301_CODE, "M680X_HD6301");
43        (CS_ARCH_M680X, [CS_MODE_M680X_6309], _HD6309_CODE, "M680X_HD6309");
44        (CS_ARCH_M680X, [CS_MODE_M680X_6800], _M6800_CODE, "M680X_M6800");
45        (CS_ARCH_M680X, [CS_MODE_M680X_6801], _M6801_CODE, "M680X_M6801");
46        (CS_ARCH_M680X, [CS_MODE_M680X_6805], _M6805_CODE, "M680X_M68HC05");
47        (CS_ARCH_M680X, [CS_MODE_M680X_6808], _M6808_CODE, "M680X_M68HC08");
48        (CS_ARCH_M680X, [CS_MODE_M680X_6809], _M6809_CODE, "M680X_M6809");
49        (CS_ARCH_M680X, [CS_MODE_M680X_6811], _M6811_CODE, "M680X_M68HC11");
50        (CS_ARCH_M680X, [CS_MODE_M680X_CPU12], _CPU12_CODE, "M680X_CPU12");
51        (CS_ARCH_M680X, [CS_MODE_M680X_HCS08], _HCS08_CODE, "M680X_HCS08");
52];;
53
54let print_inc_dec inc_dec is_post = (
55	printf "\t\t\t";
56	if is_post then printf "post" else printf "pre";
57	if inc_dec > 0 then
58		printf " increment: %d\n" inc_dec
59	else
60		printf " decrement: %d\n" (abs inc_dec);
61	);
62	();;
63
64let print_op handle flags i op =
65	( match op.value with
66	| M680X_OP_INVALID _ -> ();	(* this would never happens *)
67	| M680X_OP_REGISTER reg -> (
68		printf "\t\toperands[%d].type: REGISTER = %s" i (cs_reg_name handle reg);
69		if (((i == 0) && (bit_set flags _M680X_FIRST_OP_IN_MNEM)) ||
70		    ((i == 1) && (bit_set flags _M680X_SECOND_OP_IN_MNEM))) then
71			printf " (in mnemonic)";
72		printf "\n";
73		);
74	| M680X_OP_IMMEDIATE imm ->
75		printf "\t\toperands[%d].type: IMMEDIATE = #%d\n" i imm;
76	| M680X_OP_DIRECT direct_addr ->
77		printf "\t\toperands[%d].type: DIRECT = 0x%02X\n" i direct_addr;
78	| M680X_OP_EXTENDED ext -> (
79		printf "\t\toperands[%d].type: EXTENDED " i;
80		if ext.indirect then
81			printf "INDIRECT";
82		printf " = 0x%04X\n" ext.addr_ext;
83		);
84	| M680X_OP_RELATIVE rel ->
85		printf "\t\toperands[%d].type: RELATIVE = 0x%04X\n" i rel.addr_rel;
86	| M680X_OP_INDEXED idx -> (
87		printf "\t\toperands[%d].type: INDEXED" i;
88		if (bit_set idx.flags _M680X_IDX_INDIRECT) then
89			printf " INDIRECT";
90		printf "\n";
91		if idx.base_reg != _M680X_REG_INVALID then
92			printf "\t\t\tbase register: %s\n" (cs_reg_name handle idx.base_reg);
93		if idx.offset_reg != _M680X_REG_INVALID then
94			printf "\t\t\toffset register: %s\n" (cs_reg_name handle idx.offset_reg);
95		if idx.offset_bits != 0 && idx.offset_reg == 0 && idx.inc_dec == 0 then begin
96			printf "\t\t\toffset: %d\n" idx.offset;
97			if idx.base_reg == _M680X_REG_PC then
98				printf "\t\t\toffset address: 0x%X\n" idx.offset_addr;
99			printf "\t\t\toffset bits: %u\n" idx.offset_bits;
100		end;
101		if idx.inc_dec != 0 then
102			print_inc_dec idx.inc_dec (bit_set idx.flags _M680X_IDX_POST_INC_DEC);
103		);
104	| M680X_OP_CONSTANT const_val ->
105		printf "\t\toperands[%d].type: CONSTANT = %d\n" i const_val;
106	);
107
108	if op.size != 0 then
109		printf "\t\t\tsize: %d\n" op.size;
110	if op.access != _CS_AC_INVALID then
111		printf "\t\t\taccess: %s\n" (List.nth s_access op.access);
112	();;
113
114
115let print_detail handle insn =
116	match insn.arch with
117	| CS_INFO_M680X m680x -> (
118			(* print all operands info (type & value) *)
119			if (Array.length m680x.operands) > 0 then (
120				printf "\top_count: %d\n" (Array.length m680x.operands);
121				Array.iteri (print_op handle m680x.flags) m680x.operands;
122			);
123			);
124	| _ -> ();
125	;;
126
127let print_reg handle reg =
128	printf " %s" (cs_reg_name handle reg)
129
130let print_insn handle insn =
131	printf "0x%04X:\t" insn.address;
132	print_array_hex_short insn.bytes;
133	printf "\t%s\t%s\n" insn.mnemonic insn.op_str;
134	print_detail handle insn;
135	if (Array.length insn.regs_read) > 0 then begin
136		printf "\tRegisters read:";
137		Array.iter (print_reg handle) insn.regs_read;
138		printf "\n";
139	end;
140	if (Array.length insn.regs_write) > 0 then begin
141		printf "\tRegisters modified:";
142		Array.iter (print_reg handle) insn.regs_write;
143		printf "\n";
144	end;
145	if (Array.length insn.groups) > 0 then
146		printf "\tgroups_count: %d\n" (Array.length insn.groups);
147	printf "\n"
148
149let print_arch x =
150	let (arch, mode, code, comment) = x in
151		let handle = cs_open arch mode in
152		let err = cs_option handle CS_OPT_DETAIL _CS_OPT_ON in
153		match err with
154		| _ -> ();
155		let insns = cs_disasm handle code 0x1000L 0L in
156			printf "********************\n";
157			printf "Platform: %s\n" comment;
158			print_string_hex "Code: " code;
159			printf "Disasm:\n";
160			List.iter (print_insn handle) insns;
161		match cs_close handle with
162		| 0 -> ();
163		| _ -> printf "Failed to close handle";
164		;;
165
166List.iter print_arch all_tests;;
167
168