From eb10a162f4ce3fc631448992fd5f26673eae6871 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:11:01 +0200 Subject: [PATCH 1/7] Add Python bindings for WASM --- bindings/python/capstone/__init__.py | 7 ++- bindings/python/capstone/wasm.py | 71 ++++++++++++++++++++++++ bindings/python/pyx/ccapstone.pyx | 5 +- bindings/python/setup_cython.py | 2 +- bindings/python/test_basic.py | 6 ++- bindings/python/test_wasm.py | 81 ++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 bindings/python/capstone/wasm.py create mode 100755 bindings/python/test_wasm.py diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 4ec23458d1..5bd4bc8d8f 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -35,6 +35,7 @@ 'CS_ARCH_TMS320C64X', 'CS_ARCH_M680X', 'CS_ARCH_EVM', + 'CS_ARCH_WASM', 'CS_ARCH_BPF', 'CS_ARCH_RISCV', 'CS_ARCH_MOS65XX', @@ -387,7 +388,7 @@ def copy_ctypes_list(src): return [copy_ctypes(n) for n in src] # Weird import placement because these modules are needed by the below code but need the above functions -from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, bpf, riscv, tricore +from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, tricore class _cs_arch(ctypes.Union): _fields_ = ( @@ -404,6 +405,7 @@ class _cs_arch(ctypes.Union): ('m680x', m680x.CsM680x), ('evm', evm.CsEvm), ('mos65xx', mos65xx.CsMOS65xx), + ('wasm', wasm.CsWasm), ('bpf', bpf.CsBPF), ('riscv', riscv.CsRISCV), ('tricore', tricore.CsTriCore), @@ -727,6 +729,8 @@ def __gen_detail(self): (self.pop, self.push, self.fee) = evm.get_arch_info(self._raw.detail.contents.arch.evm) elif arch == CS_ARCH_MOS65XX: (self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(self._raw.detail.contents.arch.mos65xx) + elif arch == CS_ARCH_WASM: + (self.operands) = wasm.get_arch_info(self._raw.detail.contents.arch.wasm) elif arch == CS_ARCH_BPF: (self.operands) = bpf.get_arch_info(self._raw.detail.contents.arch.bpf) elif arch == CS_ARCH_RISCV: @@ -1199,6 +1203,7 @@ def debug(): "sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, + 'wasm': CS_ARCH_WASM, } all_archs = "" diff --git a/bindings/python/capstone/wasm.py b/bindings/python/capstone/wasm.py new file mode 100644 index 0000000000..23d68ca8ae --- /dev/null +++ b/bindings/python/capstone/wasm.py @@ -0,0 +1,71 @@ +# Capstone Python bindings, by Peace-Maker + +import ctypes + +from . import copy_ctypes_list +from .wasm_const import * + + +# define the API +class WASMBrTable(ctypes.Structure): + _fields_ = ( + ('length', ctypes.c_uint32), + ('address', ctypes.c_uint64), + ('default_target', ctypes.c_uint32), + ) + +class WASMOpValue(ctypes.Union): + _fields_ = ( + ('int7', ctypes.c_int8), + ('varuint32', ctypes.c_uint32), + ('varuint64', ctypes.c_uint64), + ('uint32', ctypes.c_uint32), + ('uint64', ctypes.c_uint64), + ('immediate', ctypes.c_uint32 * 2), + ('brtable', WASMBrTable), + ) + +class WASMOp(ctypes.Structure): + _fields_ = ( + ('type', ctypes.c_uint), + ('size', ctypes.c_uint32), + ('value', WASMOpValue), + ) + + @property + def int7(self): + return self.value.int7 + + @property + def varuint32(self): + return self.value.varuint32 + + @property + def varuint64(self): + return self.value.varuint64 + + @property + def uint32(self): + return self.value.uint32 + + @property + def uint64(self): + return self.value.uint64 + + @property + def immediate(self): + return self.value.immediate + + @property + def brtable(self): + return self.value.brtable + +class CsWasm(ctypes.Structure): + _fields_ = ( + ('op_count', ctypes.c_uint8), + ('operands', WASMOp * 2), + ) + +def get_arch_info(a): + return (copy_ctypes_list(a.operands[:a.op_count])) + diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index dbc92f6e55..3bf5d76c41 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -2,7 +2,7 @@ cimport pyx.ccapstone as cc import capstone, ctypes -from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, bpf, riscv, tricore, CsError +from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, tricore, CsError _diet = cc.cs_support(capstone.CS_SUPPORT_DIET) @@ -57,6 +57,8 @@ class CsDetail(object): (self.pop, self.push, self.fee) = evm.get_arch_info(detail.arch.evm) elif arch == capstone.CS_ARCH_MOS65XX: (self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(detail.arch.mos65xx) + elif arch == capstone.CS_ARCH_WASM: + (self.operands) = wasm.get_arch_info(detail.arch.wasm) elif arch == capstone.CS_ARCH_BPF: (self.operands) = bpf.get_arch_info(detail.arch.bpf) elif arch == capstone.CS_ARCH_RISCV: @@ -361,6 +363,7 @@ def debug(): "sysz": capstone.CS_ARCH_SYSZ, "xcore": capstone.CS_ARCH_XCORE, \ "tms320c64x": capstone.CS_ARCH_TMS320C64X, "m680x": capstone.CS_ARCH_M680X, \ "evm": capstone.CS_ARCH_EVM, "mos65xx": capstone.CS_ARCH_MOS65XX, \ + "wasm": capstone.CS_ARCH_WASM, \ "bpf": capstone.CS_ARCH_BPF, "riscv": capstone.CS_ARCH_RISCV, \ "tricore": capstone.CS_ARCH_TRICORE } diff --git a/bindings/python/setup_cython.py b/bindings/python/setup_cython.py index 953b09a6db..6dc8e0393e 100644 --- a/bindings/python/setup_cython.py +++ b/bindings/python/setup_cython.py @@ -41,7 +41,7 @@ compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] link_args = ['-L' + LIBS_DIR] -ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] +ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] ext_modules = [Extension("capstone.ccapstone", ["pyx/ccapstone.pyx"], diff --git a/bindings/python/test_basic.py b/bindings/python/test_basic.py index 1f4c721a9f..55d153bfc3 100755 --- a/bindings/python/test_basic.py +++ b/bindings/python/test_basic.py @@ -34,6 +34,7 @@ M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24" M680X_CODE = b"\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" +WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" RISCV_CODE64 = b"\x13\x04\xa8\x7a" @@ -65,8 +66,9 @@ (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None), (CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x", None), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None), - (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32", None), - (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64", None), + (CS_ARCH_WASM, 0, WASM_CODE, "WASM", None), + (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "RISCV32", None), + (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "RISCV64", None), ) # ## Test cs_disasm_quick() diff --git a/bindings/python/test_wasm.py b/bindings/python/test_wasm.py new file mode 100755 index 0000000000..2645711320 --- /dev/null +++ b/bindings/python/test_wasm.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +# Capstone Python bindings, by Peace-Maker + +from __future__ import print_function +from capstone import * +from capstone.wasm import * +from xprint import to_hex + +WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" + +all_tests = ( + (CS_ARCH_WASM, 0, WASM_CODE, "WASM"), +) + + +def print_insn_detail(insn): + # print address, mnemonic and operands + print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + + # "data" instruction generated by SKIPDATA option has no detail + if insn.id == 0: + return + + if len(insn.groups) > 0: + print("\tGroups: ", end="") + for group in insn.groups: + print("%s " % insn.group_name(group), end="") + print() + + if len(insn.operands) > 0: + print("\tOperand count: %u" % len(insn.operands)) + c = 0 + for i in insn.operands: + if i.type == WASM_OP_INT7: + print("\t\tOperand[%u] type: int7" % c) + print("\t\tOperand[%u] value: %d" % (c, i.int7)) + elif i.type == WASM_OP_VARUINT32: + print("\t\tOperand[%u] type: varuint32" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.varuint32)) + elif i.type == WASM_OP_VARUINT64: + print("\t\tOperand[%u] type: varuint64" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.varuint64)) + elif i.type == WASM_OP_UINT32: + print("\t\tOperand[%u] type: uint32" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.uint32)) + elif i.type == WASM_OP_UINT64: + print("\t\tOperand[%u] type: uint64" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.uint64)) + elif i.type == WASM_OP_IMM: + print("\t\tOperand[%u] type: imm" % c) + print("\t\tOperand[%u] value: %#x %#x" % (c, i.immediate[0], i.immediate[1])) + elif i.type == WASM_OP_BRTABLE: + print("\t\tOperand[%u] type: brtable" % c) + print("\t\tOperand[%u] value: length=%#x, address=%#x, default_target=%#x" % (c, i.brtable.length, i.brtable.address, i.brtable.default_target)) + print("\t\tOperand[%u] size: %u" % (c, i.size)) + c += 1 + + + +# ## Test class Cs +def test_class(): + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" % comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") + + try: + md = Cs(arch, mode) + md.detail = True + for insn in md.disasm(code, 0xffff): + print_insn_detail(insn) + print() + print("0x%x:\n" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" % e) + + +if __name__ == '__main__': + test_class() From ca2732cf492145df68edf47d8f5b2faee76c429f Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:16:06 +0200 Subject: [PATCH 2/7] Add Python bindings for SH --- bindings/const_generator.py | 3 +- bindings/python/capstone/__init__.py | 26 +- bindings/python/capstone/sh.py | 66 +++++ bindings/python/capstone/sh_const.py | 367 +++++++++++++++++++++++++++ bindings/python/pyx/ccapstone.pyx | 6 +- bindings/python/setup_cython.py | 2 +- bindings/python/test_sh.py | 97 +++++++ tests/Makefile | 4 + 8 files changed, 563 insertions(+), 8 deletions(-) create mode 100644 bindings/python/capstone/sh.py create mode 100644 bindings/python/capstone/sh_const.py create mode 100755 bindings/python/test_sh.py diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 74c5f1e66c..fbe1947409 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -5,7 +5,7 @@ INCL_DIR = '../include/capstone/' -include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'tricore.h' ] +include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'sh.h', 'tricore.h' ] template = { 'java': { @@ -53,6 +53,7 @@ 'mos65xx.h': 'mos65xx', 'bpf.h': 'bpf', 'riscv.h': 'riscv', + 'sh.h': 'sh', 'tricore.h': ['TRICORE', 'TriCore'], 'comment_open': '#', 'comment_close': '', diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 5bd4bc8d8f..5a035b0674 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -35,10 +35,11 @@ 'CS_ARCH_TMS320C64X', 'CS_ARCH_M680X', 'CS_ARCH_EVM', + 'CS_ARCH_MOS65XX', 'CS_ARCH_WASM', 'CS_ARCH_BPF', 'CS_ARCH_RISCV', - 'CS_ARCH_MOS65XX', + 'CS_ARCH_SH', 'CS_ARCH_TRICORE', 'CS_ARCH_ALL', @@ -90,6 +91,13 @@ 'CS_MODE_MOS65XX_65816_LONG_M', 'CS_MODE_MOS65XX_65816_LONG_X', 'CS_MODE_MOS65XX_65816_LONG_MX', + 'CS_MODE_SH2', + 'CS_MODE_SH2A', + 'CS_MODE_SH3', + 'CS_MODE_SH4', + 'CS_MODE_SH4A', + 'CS_MODE_SHFPU', + 'CS_MODE_SHDSP', 'CS_MODE_TRICORE_110', 'CS_MODE_TRICORE_120', 'CS_MODE_TRICORE_130', @@ -186,7 +194,7 @@ CS_ARCH_WASM = 13 CS_ARCH_BPF = 14 CS_ARCH_RISCV = 15 -# CS_ARCH_SH = 16 +CS_ARCH_SH = 16 CS_ARCH_TRICORE = 17 CS_ARCH_MAX = 18 CS_ARCH_ALL = 0xFFFF @@ -240,6 +248,13 @@ CS_MODE_MOS65XX_65816_LONG_M = (1 << 5) # MOS65XXX WDC 65816, 16-bit m, 8-bit x CS_MODE_MOS65XX_65816_LONG_X = (1 << 6) # MOS65XXX WDC 65816, 8-bit m, 16-bit x CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X +CS_MODE_SH2 = 1 << 1 # SH2 +CS_MODE_SH2A = 1 << 2 # SH2A +CS_MODE_SH3 = 1 << 3 # SH3 +CS_MODE_SH4 = 1 << 4 # SH4 +CS_MODE_SH4A = 1 << 5 # SH4A +CS_MODE_SHFPU = 1 << 6 # w/ FPU +CS_MODE_SHDSP = 1 << 7 # w/ DSP CS_MODE_TRICORE_110 = 1 << 1 # Tricore 1.1 CS_MODE_TRICORE_120 = 1 << 2 # Tricore 1.2 CS_MODE_TRICORE_130 = 1 << 3 # Tricore 1.3 @@ -388,7 +403,7 @@ def copy_ctypes_list(src): return [copy_ctypes(n) for n in src] # Weird import placement because these modules are needed by the below code but need the above functions -from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, tricore +from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore class _cs_arch(ctypes.Union): _fields_ = ( @@ -408,6 +423,7 @@ class _cs_arch(ctypes.Union): ('wasm', wasm.CsWasm), ('bpf', bpf.CsBPF), ('riscv', riscv.CsRISCV), + ('sh', sh.CsSH), ('tricore', tricore.CsTriCore), ) @@ -735,6 +751,8 @@ def __gen_detail(self): (self.operands) = bpf.get_arch_info(self._raw.detail.contents.arch.bpf) elif arch == CS_ARCH_RISCV: (self.need_effective_addr, self.operands) = riscv.get_arch_info(self._raw.detail.contents.arch.riscv) + elif arch == CS_ARCH_SH: + (self.sh_insn, self.sh_size, self.operands) = sh.get_arch_info(self._raw.detail.contents.arch.sh) elif arch == CS_ARCH_TRICORE: (self.update_flags, self.operands) = tricore.get_arch_info(self._raw.detail.contents.arch.tricore) @@ -1203,7 +1221,7 @@ def debug(): "sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, - 'wasm': CS_ARCH_WASM, + 'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, } all_archs = "" diff --git a/bindings/python/capstone/sh.py b/bindings/python/capstone/sh.py new file mode 100644 index 0000000000..a00f8c669c --- /dev/null +++ b/bindings/python/capstone/sh.py @@ -0,0 +1,66 @@ +# Capstone Python bindings, by Peace-Maker + +import ctypes +from . import copy_ctypes_list +from .sh_const import * + +# define the API +class SHOpMem(ctypes.Structure): + _fields_ = ( + ('address', ctypes.c_uint), + ('reg', ctypes.c_uint), + ('disp', ctypes.c_uint32), + ) + +class SHOpDsp(ctypes.Structure): + _fields_ = ( + ('insn', ctypes.c_uint), + ('operand', ctypes.c_uint * 2), + ('r', ctypes.c_uint * 6), + ('cc', ctypes.c_uint), + ('imm', ctypes.c_uint8), + ('size', ctypes.c_int), + ) + +class SHOpValue(ctypes.Union): + _fields_ = ( + ('imm', ctypes.c_int64), + ('reg', ctypes.c_uint), + ('mem', SHOpMem), + ('dsp', SHOpDsp), + ) + +class SHOp(ctypes.Structure): + _fields_ = ( + ('type', ctypes.c_uint), + ('value', SHOpValue), + ) + + @property + def imm(self): + return self.value.imm + + @property + def reg(self): + return self.value.reg + + @property + def mem(self): + return self.value.mem + + @property + def dsp(self): + return self.value.dsp + + +class CsSH(ctypes.Structure): + _fields_ = ( + ('insn', ctypes.c_uint), + ('size', ctypes.c_uint8), + ('op_count', ctypes.c_uint8), + ('operands', SHOp * 3), + ) + +def get_arch_info(a): + return (a.insn, a.size, copy_ctypes_list(a.operands[:a.op_count])) + diff --git a/bindings/python/capstone/sh_const.py b/bindings/python/capstone/sh_const.py new file mode 100644 index 0000000000..5c6cdd0cba --- /dev/null +++ b/bindings/python/capstone/sh_const.py @@ -0,0 +1,367 @@ +from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_MEM +# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sh_const.py] + +SH_REG_INVALID = 0 +SH_REG_R0 = 1 +SH_REG_R1 = 2 +SH_REG_R2 = 3 +SH_REG_R3 = 4 +SH_REG_R4 = 5 +SH_REG_R5 = 6 +SH_REG_R6 = 7 +SH_REG_R7 = 8 +SH_REG_R8 = 9 +SH_REG_R9 = 10 +SH_REG_R10 = 11 +SH_REG_R11 = 12 +SH_REG_R12 = 13 +SH_REG_R13 = 14 +SH_REG_R14 = 15 +SH_REG_R15 = 16 +SH_REG_R0_BANK = 17 +SH_REG_R1_BANK = 18 +SH_REG_R2_BANK = 19 +SH_REG_R3_BANK = 20 +SH_REG_R4_BANK = 21 +SH_REG_R5_BANK = 22 +SH_REG_R6_BANK = 23 +SH_REG_R7_BANK = 24 +SH_REG_FR0 = 25 +SH_REG_FR1 = 26 +SH_REG_FR2 = 27 +SH_REG_FR3 = 28 +SH_REG_FR4 = 29 +SH_REG_FR5 = 30 +SH_REG_FR6 = 31 +SH_REG_FR7 = 32 +SH_REG_FR8 = 33 +SH_REG_FR9 = 34 +SH_REG_FR10 = 35 +SH_REG_FR11 = 36 +SH_REG_FR12 = 37 +SH_REG_FR13 = 38 +SH_REG_FR14 = 39 +SH_REG_FR15 = 40 +SH_REG_DR0 = 41 +SH_REG_DR2 = 42 +SH_REG_DR4 = 43 +SH_REG_DR6 = 44 +SH_REG_DR8 = 45 +SH_REG_DR10 = 46 +SH_REG_DR12 = 47 +SH_REG_DR14 = 48 +SH_REG_XD0 = 49 +SH_REG_XD2 = 50 +SH_REG_XD4 = 51 +SH_REG_XD6 = 52 +SH_REG_XD8 = 53 +SH_REG_XD10 = 54 +SH_REG_XD12 = 55 +SH_REG_XD14 = 56 +SH_REG_XF0 = 57 +SH_REG_XF1 = 58 +SH_REG_XF2 = 59 +SH_REG_XF3 = 60 +SH_REG_XF4 = 61 +SH_REG_XF5 = 62 +SH_REG_XF6 = 63 +SH_REG_XF7 = 64 +SH_REG_XF8 = 65 +SH_REG_XF9 = 66 +SH_REG_XF10 = 67 +SH_REG_XF11 = 68 +SH_REG_XF12 = 69 +SH_REG_XF13 = 70 +SH_REG_XF14 = 71 +SH_REG_XF15 = 72 +SH_REG_FV0 = 73 +SH_REG_FV4 = 74 +SH_REG_FV8 = 75 +SH_REG_FV12 = 76 +SH_REG_XMATRX = 77 +SH_REG_PC = 78 +SH_REG_PR = 79 +SH_REG_MACH = 80 +SH_REG_MACL = 81 +SH_REG_SR = 82 +SH_REG_GBR = 83 +SH_REG_SSR = 84 +SH_REG_SPC = 85 +SH_REG_SGR = 86 +SH_REG_DBR = 87 +SH_REG_VBR = 88 +SH_REG_TBR = 89 +SH_REG_RS = 90 +SH_REG_RE = 91 +SH_REG_MOD = 92 +SH_REG_FPUL = 93 +SH_REG_FPSCR = 94 +SH_REG_DSP_X0 = 95 +SH_REG_DSP_X1 = 96 +SH_REG_DSP_Y0 = 97 +SH_REG_DSP_Y1 = 98 +SH_REG_DSP_A0 = 99 +SH_REG_DSP_A1 = 100 +SH_REG_DSP_A0G = 101 +SH_REG_DSP_A1G = 102 +SH_REG_DSP_M0 = 103 +SH_REG_DSP_M1 = 104 +SH_REG_DSP_DSR = 105 +SH_REG_DSP_RSV0 = 106 +SH_REG_DSP_RSV1 = 107 +SH_REG_DSP_RSV2 = 108 +SH_REG_DSP_RSV3 = 109 +SH_REG_DSP_RSV4 = 110 +SH_REG_DSP_RSV5 = 111 +SH_REG_DSP_RSV6 = 112 +SH_REG_DSP_RSV7 = 113 +SH_REG_DSP_RSV8 = 114 +SH_REG_DSP_RSV9 = 115 +SH_REG_DSP_RSVA = 116 +SH_REG_DSP_RSVB = 117 +SH_REG_DSP_RSVC = 118 +SH_REG_DSP_RSVD = 119 +SH_REG_DSP_RSVE = 120 +SH_REG_DSP_RSVF = 121 +SH_REG_ENDING = 122 + +SH_OP_INVALID = 0 +SH_OP_REG = 1 +SH_OP_IMM = 2 +SH_OP_MEM = 3 + +SH_OP_MEM_INVALID = 0 +SH_OP_MEM_REG_IND = 1 +SH_OP_MEM_REG_POST = 2 +SH_OP_MEM_REG_PRE = 3 +SH_OP_MEM_REG_DISP = 4 +SH_OP_MEM_REG_R0 = 5 +SH_OP_MEM_GBR_DISP = 6 +SH_OP_MEM_GBR_R0 = 7 +SH_OP_MEM_PCR = 8 +SH_OP_MEM_TBR_DISP = 9 +SH_INS_DSP_INVALID = 10 +SH_INS_DSP_DOUBLE = 11 +SH_INS_DSP_SINGLE = 12 +SH_INS_DSP_PARALLEL = 13 +SH_INS_DSP_NOP = 1 +SH_INS_DSP_MOV = 2 +SH_INS_DSP_PSHL = 3 +SH_INS_DSP_PSHA = 4 +SH_INS_DSP_PMULS = 5 +SH_INS_DSP_PCLR_PMULS = 6 +SH_INS_DSP_PSUB_PMULS = 7 +SH_INS_DSP_PADD_PMULS = 8 +SH_INS_DSP_PSUBC = 9 +SH_INS_DSP_PADDC = 10 +SH_INS_DSP_PCMP = 11 +SH_INS_DSP_PABS = 12 +SH_INS_DSP_PRND = 13 +SH_INS_DSP_PSUB = 14 +SH_INS_DSP_PSUBr = 15 +SH_INS_DSP_PADD = 16 +SH_INS_DSP_PAND = 17 +SH_INS_DSP_PXOR = 18 +SH_INS_DSP_POR = 19 +SH_INS_DSP_PDEC = 20 +SH_INS_DSP_PINC = 21 +SH_INS_DSP_PCLR = 22 +SH_INS_DSP_PDMSB = 23 +SH_INS_DSP_PNEG = 24 +SH_INS_DSP_PCOPY = 25 +SH_INS_DSP_PSTS = 26 +SH_INS_DSP_PLDS = 27 +SH_INS_DSP_PSWAP = 28 +SH_INS_DSP_PWAD = 29 +SH_INS_DSP_PWSB = 30 +SH_OP_DSP_INVALID = 31 +SH_OP_DSP_REG_PRE = 32 +SH_OP_DSP_REG_IND = 33 +SH_OP_DSP_REG_POST = 34 +SH_OP_DSP_REG_INDEX = 35 +SH_OP_DSP_REG = 36 +SH_OP_DSP_IMM = 37 +SH_DSP_CC_INVALID = 38 +SH_DSP_CC_NONE = 39 +SH_DSP_CC_DCT = 40 +SH_DSP_CC_DCF = 41 +SH_INS_INVALID = 42 +SH_INS_ADD_r = 43 +SH_INS_ADD = 44 +SH_INS_ADDC = 45 +SH_INS_ADDV = 46 +SH_INS_AND = 47 +SH_INS_BAND = 48 +SH_INS_BANDNOT = 49 +SH_INS_BCLR = 50 +SH_INS_BF = 51 +SH_INS_BF_S = 52 +SH_INS_BLD = 53 +SH_INS_BLDNOT = 54 +SH_INS_BOR = 55 +SH_INS_BORNOT = 56 +SH_INS_BRA = 57 +SH_INS_BRAF = 58 +SH_INS_BSET = 59 +SH_INS_BSR = 60 +SH_INS_BSRF = 61 +SH_INS_BST = 62 +SH_INS_BT = 63 +SH_INS_BT_S = 64 +SH_INS_BXOR = 65 +SH_INS_CLIPS = 66 +SH_INS_CLIPU = 67 +SH_INS_CLRDMXY = 68 +SH_INS_CLRMAC = 69 +SH_INS_CLRS = 70 +SH_INS_CLRT = 71 +SH_INS_CMP_EQ = 72 +SH_INS_CMP_GE = 73 +SH_INS_CMP_GT = 74 +SH_INS_CMP_HI = 75 +SH_INS_CMP_HS = 76 +SH_INS_CMP_PL = 77 +SH_INS_CMP_PZ = 78 +SH_INS_CMP_STR = 79 +SH_INS_DIV0S = 80 +SH_INS_DIV0U = 81 +SH_INS_DIV1 = 82 +SH_INS_DIVS = 83 +SH_INS_DIVU = 84 +SH_INS_DMULS_L = 85 +SH_INS_DMULU_L = 86 +SH_INS_DT = 87 +SH_INS_EXTS_B = 88 +SH_INS_EXTS_W = 89 +SH_INS_EXTU_B = 90 +SH_INS_EXTU_W = 91 +SH_INS_FABS = 92 +SH_INS_FADD = 93 +SH_INS_FCMP_EQ = 94 +SH_INS_FCMP_GT = 95 +SH_INS_FCNVDS = 96 +SH_INS_FCNVSD = 97 +SH_INS_FDIV = 98 +SH_INS_FIPR = 99 +SH_INS_FLDI0 = 100 +SH_INS_FLDI1 = 101 +SH_INS_FLDS = 102 +SH_INS_FLOAT = 103 +SH_INS_FMAC = 104 +SH_INS_FMOV = 105 +SH_INS_FMUL = 106 +SH_INS_FNEG = 107 +SH_INS_FPCHG = 108 +SH_INS_FRCHG = 109 +SH_INS_FSCA = 110 +SH_INS_FSCHG = 111 +SH_INS_FSQRT = 112 +SH_INS_FSRRA = 113 +SH_INS_FSTS = 114 +SH_INS_FSUB = 115 +SH_INS_FTRC = 116 +SH_INS_FTRV = 117 +SH_INS_ICBI = 118 +SH_INS_JMP = 119 +SH_INS_JSR = 120 +SH_INS_JSR_N = 121 +SH_INS_LDBANK = 122 +SH_INS_LDC = 123 +SH_INS_LDRC = 124 +SH_INS_LDRE = 125 +SH_INS_LDRS = 126 +SH_INS_LDS = 127 +SH_INS_LDTLB = 128 +SH_INS_MAC_L = 129 +SH_INS_MAC_W = 130 +SH_INS_MOV = 131 +SH_INS_MOVA = 132 +SH_INS_MOVCA = 133 +SH_INS_MOVCO = 134 +SH_INS_MOVI20 = 135 +SH_INS_MOVI20S = 136 +SH_INS_MOVLI = 137 +SH_INS_MOVML = 138 +SH_INS_MOVMU = 139 +SH_INS_MOVRT = 140 +SH_INS_MOVT = 141 +SH_INS_MOVU = 142 +SH_INS_MOVUA = 143 +SH_INS_MUL_L = 144 +SH_INS_MULR = 145 +SH_INS_MULS_W = 146 +SH_INS_MULU_W = 147 +SH_INS_NEG = 148 +SH_INS_NEGC = 149 +SH_INS_NOP = 150 +SH_INS_NOT = 151 +SH_INS_NOTT = 152 +SH_INS_OCBI = 153 +SH_INS_OCBP = 154 +SH_INS_OCBWB = 155 +SH_INS_OR = 156 +SH_INS_PREF = 157 +SH_INS_PREFI = 158 +SH_INS_RESBANK = 159 +SH_INS_ROTCL = 160 +SH_INS_ROTCR = 161 +SH_INS_ROTL = 162 +SH_INS_ROTR = 163 +SH_INS_RTE = 164 +SH_INS_RTS = 165 +SH_INS_RTS_N = 166 +SH_INS_RTV_N = 167 +SH_INS_SETDMX = 168 +SH_INS_SETDMY = 169 +SH_INS_SETRC = 170 +SH_INS_SETS = 171 +SH_INS_SETT = 172 +SH_INS_SHAD = 173 +SH_INS_SHAL = 174 +SH_INS_SHAR = 175 +SH_INS_SHLD = 176 +SH_INS_SHLL = 177 +SH_INS_SHLL16 = 178 +SH_INS_SHLL2 = 179 +SH_INS_SHLL8 = 180 +SH_INS_SHLR = 181 +SH_INS_SHLR16 = 182 +SH_INS_SHLR2 = 183 +SH_INS_SHLR8 = 184 +SH_INS_SLEEP = 185 +SH_INS_STBANK = 186 +SH_INS_STC = 187 +SH_INS_STS = 188 +SH_INS_SUB = 189 +SH_INS_SUBC = 190 +SH_INS_SUBV = 191 +SH_INS_SWAP_B = 192 +SH_INS_SWAP_W = 193 +SH_INS_SYNCO = 194 +SH_INS_TAS = 195 +SH_INS_TRAPA = 196 +SH_INS_TST = 197 +SH_INS_XOR = 198 +SH_INS_XTRCT = 199 +SH_INS_DSP = 200 +SH_INS_ENDING = 201 + +SH_GRP_INVALID = 0 +SH_GRP_JUMP = 1 +SH_GRP_CALL = 2 +SH_GRP_INT = 3 +SH_GRP_RET = 4 +SH_GRP_IRET = 5 +SH_GRP_PRIVILEGE = 6 +SH_GRP_BRANCH_RELATIVE = 7 +SH_GRP_SH1 = 8 +SH_GRP_SH2 = 9 +SH_GRP_SH2E = 10 +SH_GRP_SH2DSP = 11 +SH_GRP_SH2A = 12 +SH_GRP_SH2AFPU = 13 +SH_GRP_SH3 = 14 +SH_GRP_SH3DSP = 15 +SH_GRP_SH4 = 16 +SH_GRP_SH4A = 17 +SH_GRP_ENDING = 18 diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index 3bf5d76c41..6c8375c094 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -2,7 +2,7 @@ cimport pyx.ccapstone as cc import capstone, ctypes -from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, tricore, CsError +from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, CsError _diet = cc.cs_support(capstone.CS_SUPPORT_DIET) @@ -63,6 +63,8 @@ class CsDetail(object): (self.operands) = bpf.get_arch_info(detail.arch.bpf) elif arch == capstone.CS_ARCH_RISCV: (self.need_effective_addr, self.operands) = riscv.get_arch_info(detail.arch.riscv) + elif arch == capstone.CS_ARCH_SH: + (self.sh_insn, self.sh_size, self.operands) = sh.get_arch_info(detail.arch.sh) elif arch == capstone.CS_ARCH_TRICORE: (self.update_flags, self.operands) = tricore.get_arch_info(detail.arch.tricore) @@ -365,7 +367,7 @@ def debug(): "evm": capstone.CS_ARCH_EVM, "mos65xx": capstone.CS_ARCH_MOS65XX, \ "wasm": capstone.CS_ARCH_WASM, \ "bpf": capstone.CS_ARCH_BPF, "riscv": capstone.CS_ARCH_RISCV, \ - "tricore": capstone.CS_ARCH_TRICORE } + "sh": capstone.CS_ARCH_SH, "tricore": capstone.CS_ARCH_TRICORE } all_archs = "" keys = list(archs.keys()) diff --git a/bindings/python/setup_cython.py b/bindings/python/setup_cython.py index 6dc8e0393e..70fcc856c9 100644 --- a/bindings/python/setup_cython.py +++ b/bindings/python/setup_cython.py @@ -41,7 +41,7 @@ compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] link_args = ['-L' + LIBS_DIR] -ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] +ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'sh', 'sh_const', 'tricore', 'tricore_const' ] ext_modules = [Extension("capstone.ccapstone", ["pyx/ccapstone.pyx"], diff --git a/bindings/python/test_sh.py b/bindings/python/test_sh.py new file mode 100755 index 0000000000..1afe31c3eb --- /dev/null +++ b/bindings/python/test_sh.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +# Capstone Python bindings, by Peace-Maker + +from __future__ import print_function +from capstone import * +from capstone.sh import * +from xprint import to_x, to_hex + +SH4A_CODE = b"\x0c\x31\x10\x20\x22\x21\x36\x64\x46\x25\x12\x12\x1c\x02\x08\xc1\x05\xc7\x0c\x71\x1f\x02\x22\xcf\x06\x89\x23\x00\x2b\x41\x0b\x00\x0e\x40\x32\x00\x0a\xf1\x09\x00" +SH2A_CODE = b"\x32\x11\x92\x00\x32\x49\x31\x00" +all_tests = ( + (CS_ARCH_SH, CS_MODE_SH4A | CS_MODE_SHFPU, SH4A_CODE, "SH_SH4A"), + (CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN, SH2A_CODE, "SH_SH2A"), +) + + +reg_address_msg = [ + "Register indirect", + "Register indirect with predecrement", + "Register indirect with postincrement", +] + +def print_read_write_regs(insn): + if len(insn.regs_read) > 0: + print("\tRegisters read: %s" % " ".join(insn.reg_name(m) for m in insn.regs_read)) + + if len(insn.regs_write) > 0: + print("\tRegisters modified: %s" % " ".join(insn.reg_name(m) for m in insn.regs_write)) + +def print_insn_detail(insn): + # print address, mnemonic and operands + print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + + # "data" instruction generated by SKIPDATA option has no detail + if insn.id == 0: + return + + if len(insn.operands) > 0: + print("\top_count: %u" % len(insn.operands)) + c = 0 + for i in insn.operands: + if i.type == SH_OP_REG: + print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg))) + elif i.type == SH_OP_IMM: + print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm))) + elif i.type == SH_OP_MEM: + print("\t\toperands[%u].type: MEM " % c) + if i.mem.address in [SH_OP_MEM_REG_IND, SH_OP_MEM_REG_POST, SH_OP_MEM_REG_PRE]: + print("%s REG %s" % (reg_address_msg[i.mem.address - SH_OP_MEM_REG_IND], insn.reg_name(i.mem.reg))) + elif i.mem.address == SH_OP_MEM_REG_DISP: + print("Register indirect with displacement REG %s, DISP %d" % (insn.reg_name(i.mem.reg), i.mem.disp)) + elif i.mem.address == SH_OP_MEM_REG_R0: + print("R0 indexed") + elif i.mem.address == SH_OP_MEM_GBR_DISP: + print("GBR base with displacement DISP %d" % i.mem.disp) + elif i.mem.address == SH_OP_MEM_GBR_R0: + print("GBR base with R0 indexed") + elif i.mem.address == SH_OP_MEM_PCR: + print("PC relative Address=0x%08x" % i.mem.disp) + elif i.mem.address == SH_OP_MEM_TBR_DISP: + print("TBR base with displacement DISP %d", i.mem.disp) + else: + print("Unknown addressing mode %x" % i.mem.address) + + if i.sh_size != 0: + print("\t\t\tsh_size: %u" % i.sh_size) + c += 1 + + print_read_write_regs(insn) + + if len(insn.groups) > 0: + print('\tgroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups))) + + +# ## Test class Cs +def test_class(): + + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" %comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") + + try: + md = Cs(arch, mode) + md.detail = True + for insn in md.disasm(code, 0x80000000): + print_insn_detail(insn) + print() + print("0x%x:" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" %e) + + +if __name__ == '__main__': + test_class() diff --git a/tests/Makefile b/tests/Makefile index a66df22fcc..b9e90c6d01 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -132,6 +132,10 @@ endif ifneq (,$(findstring tricore,$(CAPSTONE_ARCHS))) SOURCES += test_tricore.c endif +ifneq (,$(findstring sh,$(CAPSTONE_ARCHS))) +CFLAGS += -DCAPSTONE_HAS_SH +SOURCES += test_sh.c +endif OBJS = $(addprefix $(OBJDIR)/,$(SOURCES:.c=.o)) BINARY = $(addprefix $(TESTDIR)/,$(SOURCES:.c=$(BIN_EXT))) From 25dcb454aa9a29daf4059c6e75967402b14fae0b Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:20:37 +0200 Subject: [PATCH 3/7] Update CS_* constants in Python bindings --- bindings/python/capstone/__init__.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 5a035b0674..92bd5777e7 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -119,7 +119,13 @@ 'CS_OPT_ON', 'CS_OPT_OFF', + 'CS_OPT_INVALID', 'CS_OPT_MEM', + 'CS_OPT_SKIPDATA', + 'CS_OPT_SKIPDATA_SETUP', + 'CS_OPT_MNEMONIC', + 'CS_OPT_UNSIGNED', + 'CS_OPT_NO_BRANCH_OFFSET', 'CS_ERR_OK', 'CS_ERR_MEM', @@ -135,6 +141,7 @@ 'CS_ERR_SKIPDATA', 'CS_ERR_X86_ATT', 'CS_ERR_X86_INTEL', + 'CS_ERR_X86_MASM', 'CS_SUPPORT_DIET', 'CS_SUPPORT_X86_REDUCE', @@ -143,8 +150,8 @@ 'CS_OP_INVALID', 'CS_OP_REG', 'CS_OP_IMM', - 'CS_OP_MEM', 'CS_OP_FP', + 'CS_OP_MEM', 'CS_GRP_INVALID', 'CS_GRP_JUMP', @@ -264,6 +271,7 @@ CS_MODE_TRICORE_162 = 1 << 7 # Tricore 1.6.2 # Capstone option type +CS_OPT_INVALID = 0 # No option specified CS_OPT_SYNTAX = 1 # Intel X86 asm syntax (CS_ARCH_X86 arch) CS_OPT_DETAIL = 2 # Break down instruction structure into details CS_OPT_MODE = 3 # Change engine's mode at run-time @@ -272,17 +280,18 @@ CS_OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option CS_OPT_MNEMONIC = 7 # Customize instruction mnemonic CS_OPT_UNSIGNED = 8 # Print immediate in unsigned form +CS_OPT_NO_BRANCH_OFFSET = 9 # ARM, prints branch immediates without offset. # Capstone option value CS_OPT_OFF = 0 # Turn OFF an option - default option of CS_OPT_DETAIL CS_OPT_ON = 3 # Turn ON an option (CS_OPT_DETAIL) # Common instruction operand types - to be consistent across all architectures. -CS_OP_INVALID = 0 -CS_OP_REG = 1 -CS_OP_IMM = 2 -CS_OP_MEM = 3 -CS_OP_FP = 4 +CS_OP_INVALID = 0 # uninitialized/invalid operand. +CS_OP_REG = 1 # Register operand. +CS_OP_IMM = 2 # Immediate operand. +CS_OP_FP = 3 # Floating-Point operand. +CS_OP_MEM = 0x80 # Memory operand. Can be ORed with another operand type. # Common instruction groups - to be consistent across all architectures. CS_GRP_INVALID = 0 # uninitialized/invalid group. From 20f78434243bdb09720f26c89627f19d50414011 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:22:56 +0200 Subject: [PATCH 4/7] Update Python bindings for x86 --- bindings/python/capstone/__init__.py | 2 +- bindings/python/capstone/x86.py | 17 +++++++++++++++-- bindings/python/pyx/ccapstone.pyx | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 92bd5777e7..ca0435ad01 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -730,7 +730,7 @@ def __gen_detail(self): (self.prefix, self.opcode, self.rex, self.addr_size, \ self.modrm, self.sib, self.disp, \ self.sib_index, self.sib_scale, self.sib_base, self.xop_cc, self.sse_cc, \ - self.avx_cc, self.avx_sae, self.avx_rm, self.eflags, \ + self.avx_cc, self.avx_sae, self.avx_rm, self.eflags, self.fpu_flags, \ self.encoding, self.modrm_offset, self.disp_offset, self.disp_size, self.imm_offset, self.imm_size, \ self.operands) = x86.get_arch_info(self._raw.detail.contents.arch.x86) elif arch == CS_ARCH_M68K: diff --git a/bindings/python/capstone/x86.py b/bindings/python/capstone/x86.py index f8056f1a94..caa5e35ebd 100644 --- a/bindings/python/capstone/x86.py +++ b/bindings/python/capstone/x86.py @@ -43,6 +43,11 @@ def reg(self): def mem(self): return self.value.mem +class X86Flags(ctypes.Union): + _fields_ = ( + ('eflags', ctypes.c_uint64), + ('fpu_flags', ctypes.c_uint64), + ) class CsX86Encoding(ctypes.Structure): _fields_ = ( @@ -70,16 +75,24 @@ class CsX86(ctypes.Structure): ('avx_cc', ctypes.c_uint), ('avx_sae', ctypes.c_bool), ('avx_rm', ctypes.c_uint), - ('eflags', ctypes.c_uint64), + ('flags', X86Flags), ('op_count', ctypes.c_uint8), ('operands', X86Op * 8), ('encoding', CsX86Encoding), ) + @property + def eflags(self): + return self.flags.eflags + + @property + def fpu_flags(self): + return self.flags.fpu_flags + def get_arch_info(a): return (a.prefix[:], a.opcode[:], a.rex, a.addr_size, \ a.modrm, a.sib, a.disp, a.sib_index, a.sib_scale, \ - a.sib_base, a.xop_cc, a.sse_cc, a.avx_cc, a.avx_sae, a.avx_rm, a.eflags, \ + a.sib_base, a.xop_cc, a.sse_cc, a.avx_cc, a.avx_sae, a.avx_rm, a.eflags, a.fpu_flags, \ a.encoding, a.encoding.modrm_offset, a.encoding.disp_offset, a.encoding.disp_size, a.encoding.imm_offset, a.encoding.imm_size, \ copy_ctypes_list(a.operands[:a.op_count])) diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index 6c8375c094..932752c4de 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -34,7 +34,7 @@ class CsDetail(object): self.modrm, self.sib, self.disp, \ self.sib_index, self.sib_scale, self.sib_base, \ self.xop_cc, self.sse_cc, self.avx_cc, self.avx_sae, self.avx_rm, \ - self.eflags, self.encoding, self.modrm_offset, self.disp_offset, \ + self.eflags, self.fpu_flags, self.encoding, self.modrm_offset, self.disp_offset, \ self.disp_size, self.imm_offset, self.imm_size, self.operands) = x86.get_arch_info(detail.arch.x86) elif arch == capstone.CS_ARCH_M68K: (self.operands, self.op_size) = m68k.get_arch_info(detail.arch.m68k) From d03d23ee8816707e93ec3176e06e991b80b01dd5 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:23:22 +0200 Subject: [PATCH 5/7] Update Python bindings for m68k --- bindings/python/capstone/m68k.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/python/capstone/m68k.py b/bindings/python/capstone/m68k.py index 9cc8936548..9356462808 100644 --- a/bindings/python/capstone/m68k.py +++ b/bindings/python/capstone/m68k.py @@ -66,6 +66,10 @@ def simm(self): @property def reg(self): return self.value.reg + + @property + def reg_pair(self): + return self.value.reg_pair @property def mem(self): From 9b036506dfadc1ff0160f0c707123aab99115f7a Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:23:59 +0200 Subject: [PATCH 6/7] Update Python bindings for mos65xx --- bindings/python/capstone/mos65xx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/capstone/mos65xx.py b/bindings/python/capstone/mos65xx.py index 11b3462a58..87a5f87054 100644 --- a/bindings/python/capstone/mos65xx.py +++ b/bindings/python/capstone/mos65xx.py @@ -8,8 +8,8 @@ class MOS65xxOpValue(ctypes.Union): _fields_ = ( ('reg', ctypes.c_uint), - ('imm', ctypes.c_uint8), - ('mem', ctypes.c_uint16), + ('imm', ctypes.c_uint16), + ('mem', ctypes.c_uint32), ) class MOS65xxOp(ctypes.Structure): From 768013b27a8bbfd3d3b3eaf35e936eece2153c3c Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:56:35 +0200 Subject: [PATCH 7/7] Resurrect binding diff tests There used to be tests comparing the output of the C test_* programs with the equivalent test in the binding language. Update the tests to match the Python bindings. --- .github/workflows/CITest.yml | 22 +++++++- .gitignore | 1 + bindings/Makefile | 49 ++++++++++++++--- bindings/python/Makefile | 5 +- bindings/python/test_arm.py | 15 ++--- bindings/python/test_arm64.py | 20 +++---- bindings/python/test_basic.py | 14 +++-- bindings/python/test_bpf.py | 4 +- bindings/python/test_customized_mnem.py | 6 +- bindings/python/test_detail.py | 29 ++++++---- bindings/python/test_evm.py | 2 + bindings/python/test_m68k.py | 14 +++-- bindings/python/test_mips.py | 3 + bindings/python/test_mos65xx.py | 42 +++++++++----- bindings/python/test_ppc.py | 4 +- bindings/python/test_riscv.py | 3 + bindings/python/test_tms320c64x.py | 23 +++++++- bindings/python/test_tricore.py | 13 ++--- bindings/python/test_x86.py | 73 +++++++++++++++++++++---- tests/Makefile | 1 + tests/test_arm.c | 10 +++- tests/test_basic.c | 5 +- tests/test_detail.c | 36 ++++++------ tests/test_m68k.c | 5 ++ tests/test_mos65xx.c | 4 +- tests/test_riscv.c | 2 +- tests/test_sh.c | 40 +++++--------- tests/test_tms320c64x.c | 4 +- tests/test_tricore.c | 2 - tests/test_wasm.c | 10 ++++ 30 files changed, 318 insertions(+), 143 deletions(-) diff --git a/.github/workflows/CITest.yml b/.github/workflows/CITest.yml index 85a7e44ab6..003f284c39 100644 --- a/.github/workflows/CITest.yml +++ b/.github/workflows/CITest.yml @@ -86,7 +86,7 @@ jobs: ./make.sh; make check; cp libcapstone.so.5 libcapstone.so.5.0 - # sudo make install + sudo make install - name: cmake if: startsWith(matrix.config.build-system, 'cmake') @@ -96,7 +96,9 @@ jobs: cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 ..; cmake --build . --config Release; cp libcapstone.* ../; - # sudo make install; + cp libcapstone.* ../tests/; + cp test_* ../tests/; + sudo make install; - name: build python binding shell: 'script -q -e -c "bash {0}"' @@ -106,6 +108,22 @@ jobs: make && make check ; cd ../..; + - name: run python binding test + run: | + cd bindings/python + make install3 + cd .. + BUILD_TESTS=no make tests + + - name: run cython binding test + run: | + pip install cython + cd bindings/python + make install3_cython + cd .. + python -c "import capstone;print(capstone.debug())" | grep Cython + BUILD_TESTS=no make tests + - name: cstest shell: 'script -q -e -c "bash {0}"' run: | diff --git a/.gitignore b/.gitignore index aa1c8b6457..405d85d506 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ tests/test_wasm tests/test_mos65xx tests/test_bpf tests/test_riscv +tests/test_sh # regress binaries suite/regress/invalid_read_in_print_operand diff --git a/bindings/Makefile b/bindings/Makefile index 83e9b255fd..50f84f5cf1 100644 --- a/bindings/Makefile +++ b/bindings/Makefile @@ -2,7 +2,9 @@ TMPDIR = /tmp/capstone_test DIFF = diff -u -w -TEST = $(TMPDIR)/test +TEST_BASIC = $(TMPDIR)/test_basic +TEST_DETAIL = $(TMPDIR)/test_detail +TEST_CUSTOMIZED_MNEM = $(TMPDIR)/test_customized_mnem TEST_ARM = $(TMPDIR)/test_arm TEST_ARM64 = $(TMPDIR)/test_arm64 TEST_M68K = $(TMPDIR)/test_m68k @@ -13,11 +15,19 @@ TEST_SPARC = $(TMPDIR)/test_sparc TEST_SYSZ = $(TMPDIR)/test_systemz TEST_X86 = $(TMPDIR)/test_x86 TEST_XCORE = $(TMPDIR)/test_xcore +TEST_WASM = $(TMPDIR)/test_wasm TEST_BPF = $(TMPDIR)/test_bpf TEST_RISCV = $(TMPDIR)/test_riscv +TEST_EVM = $(TMPDIR)/test_evm +TEST_M680X = $(TMPDIR)/test_m680x +TEST_TRICORE = $(TMPDIR)/test_tricore +TEST_SH = $(TMPDIR)/test_sh +TEST_TMS320C64X = $(TMPDIR)/test_tms320c64x PYTHON2 ?= python +BUILD_TESTS ?= yes + .PHONY: all expected python java ocaml all: @@ -25,15 +35,17 @@ all: cd java && $(MAKE) gen_const cd ocaml && $(MAKE) gen_const -tests: expected python java #oclma ruby +tests: expected python #java oclma ruby test_java: expected java test_python: expected python expected: - cd ../tests && $(MAKE) + if [ "$(BUILD_TESTS)" = "yes" ]; then cd ../tests && $(MAKE); fi mkdir -p $(TMPDIR) - ../tests/test > $(TEST)_e + ../tests/test_basic > $(TEST_BASIC)_e + ../tests/test_detail > $(TEST_DETAIL)_e + ../tests/test_customized_mnem > $(TEST_CUSTOMIZED_MNEM)_e ../tests/test_arm > $(TEST_ARM)_e ../tests/test_arm64 > $(TEST_ARM64)_e ../tests/test_m68k > $(TEST_M68K)_e @@ -44,12 +56,20 @@ expected: ../tests/test_systemz > $(TEST_SYSZ)_e ../tests/test_x86 > $(TEST_X86)_e ../tests/test_xcore > $(TEST_XCORE)_e + ../tests/test_wasm > $(TEST_WASM)_e ../tests/test_bpf > $(TEST_BPF)_e ../tests/test_riscv > $(TEST_RISCV)_e + ../tests/test_evm > $(TEST_EVM)_e + ../tests/test_m680x > $(TEST_M680X)_e + ../tests/test_sh > $(TEST_SH)_e + ../tests/test_tricore > $(TEST_TRICORE)_e + ../tests/test_tms320c64x > $(TEST_TMS320C64X)_e python: FORCE cd python && $(MAKE) - $(PYTHON2) python/test.py > $(TEST)_o + $(PYTHON2) python/test_basic.py > $(TEST_BASIC)_o + $(PYTHON2) python/test_detail.py > $(TEST_DETAIL)_o + $(PYTHON2) python/test_customized_mnem.py > $(TEST_CUSTOMIZED_MNEM)_o $(PYTHON2) python/test_arm.py > $(TEST_ARM)_o $(PYTHON2) python/test_arm64.py > $(TEST_ARM64)_o $(PYTHON2) python/test_m68k.py > $(TEST_M68K)_o @@ -60,13 +80,19 @@ python: FORCE $(PYTHON2) python/test_systemz.py > $(TEST_SYSZ)_o $(PYTHON2) python/test_x86.py > $(TEST_X86)_o $(PYTHON2) python/test_xcore.py > $(TEST_XCORE)_o + $(PYTHON2) python/test_wasm.py > $(TEST_WASM)_o $(PYTHON2) python/test_bpf.py > $(TEST_BPF)_o $(PYTHON2) python/test_riscv.py > $(TEST_RISCV)_o + $(PYTHON2) python/test_evm.py > $(TEST_EVM)_o + $(PYTHON2) python/test_m680x.py > $(TEST_M680X)_o + $(PYTHON2) python/test_sh.py > $(TEST_SH)_o + $(PYTHON2) python/test_tricore.py > $(TEST_TRICORE)_o + $(PYTHON2) python/test_tms320c64x.py > $(TEST_TMS320C64X)_o $(MAKE) test_diff java: FORCE cd java && $(MAKE) - cd java && ./run.sh > $(TEST)_o + cd java && ./run.sh > $(TEST_BASIC)_o cd java && ./run.sh arm > $(TEST_ARM)_o cd java && ./run.sh arm64 > $(TEST_ARM64)_o cd java && ./run.sh mips > $(TEST_MIPS)_o @@ -80,7 +106,9 @@ java: FORCE ocaml: FORCE test_diff: FORCE - $(DIFF) $(TEST)_e $(TEST)_o + $(DIFF) $(TEST_BASIC)_e $(TEST_BASIC)_o + $(DIFF) $(TEST_DETAIL)_e $(TEST_DETAIL)_o + $(DIFF) $(TEST_CUSTOMIZED_MNEM)_e $(TEST_CUSTOMIZED_MNEM)_o $(DIFF) $(TEST_ARM)_e $(TEST_ARM)_o $(DIFF) $(TEST_ARM64)_e $(TEST_ARM64)_o $(DIFF) $(TEST_M68K)_e $(TEST_M68K)_o @@ -91,7 +119,14 @@ test_diff: FORCE $(DIFF) $(TEST_SYSZ)_e $(TEST_SYSZ)_o $(DIFF) $(TEST_X86)_e $(TEST_X86)_o $(DIFF) $(TEST_XCORE)_e $(TEST_XCORE)_o + $(DIFF) $(TEST_WASM)_e $(TEST_WASM)_o $(DIFF) $(TEST_BPF)_e $(TEST_BPF)_o + $(DIFF) $(TEST_RISCV)_e $(TEST_RISCV)_o + $(DIFF) $(TEST_EVM)_e $(TEST_EVM)_o + $(DIFF) $(TEST_M680X)_e $(TEST_M680X)_o + $(DIFF) $(TEST_SH)_e $(TEST_SH)_o + $(DIFF) $(TEST_TRICORE)_e $(TEST_TRICORE)_o + $(DIFF) $(TEST_TMS320C64X)_e $(TEST_TMS320C64X)_o clean: rm -rf $(TMPDIR) diff --git a/bindings/python/Makefile b/bindings/python/Makefile index b901b061d1..f606220170 100644 --- a/bindings/python/Makefile +++ b/bindings/python/Makefile @@ -4,7 +4,7 @@ PYTHON3 ?= python3 .PHONY: gen_const install install3 install_cython sdist sdist3 bdist bdist3 clean check gen_const: - cd .. && $(PYTHON2) const_generator.py python + cd .. && $(PYTHON3) const_generator.py python install: rm -rf src/ @@ -71,7 +71,8 @@ clean: TESTS = test_basic.py test_detail.py test_arm.py test_arm64.py test_m68k.py test_mips.py TESTS += test_ppc.py test_sparc.py test_systemz.py test_x86.py test_xcore.py test_tms320c64x.py TESTS += test_m680x.py test_skipdata.py test_mos65xx.py test_bpf.py test_riscv.py -TESTS += test_evm.py +TESTS += test_evm.py test_tricore.py test_lite.py test_customized_mnem.py +TESTS += test_wasm.py test_sh.py check: @for t in $(TESTS); do \ diff --git a/bindings/python/test_arm.py b/bindings/python/test_arm.py index cfcb31baff..4fb4245fd6 100755 --- a/bindings/python/test_arm.py +++ b/bindings/python/test_arm.py @@ -8,9 +8,9 @@ from xprint import to_hex, to_x_32 -ARM_CODE = b"\x86\x48\x60\xf4\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\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00" +ARM_CODE = b"\x86\x48\x60\xf4\x4d\x0f\xe2\xf4\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\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00" ARM_CODE2 = b"\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c" -THUMB_CODE = b"\x70\x47\x00\xf0\x10\xe8\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0" +THUMB_CODE = b"\x60\xf9\x1f\x04\xe0\xf9\x4f\x07\x70\x47\x00\xf0\x10\xe8\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0" THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0\x18\xbf\xad\xbf\xf3\xff\x0b\x0c\x86\xf3\x00\x89\x80\xf3\x00\x8c\x4f\xfa\x99\xf6\xd0\xff\xa2\x01" THUMB_MCLASS = b"\xef\xf3\x02\x80" ARMV8 = b"\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5" @@ -76,11 +76,11 @@ def print_insn_detail(insn): print("\t\toperands[%u].neon_lane = %u" % (c, i.neon_lane)) if i.access == CS_AC_READ: - print("\t\toperands[%u].access: READ\n" % (c)) + print("\t\toperands[%u].access: READ" % (c)) elif i.access == CS_AC_WRITE: - print("\t\toperands[%u].access: WRITE\n" % (c)) + print("\t\toperands[%u].access: WRITE" % (c)) elif i.access == CS_AC_READ | CS_AC_WRITE: - print("\t\toperands[%u].access: READ | WRITE\n" % (c)) + print("\t\toperands[%u].access: READ | WRITE" % (c)) if i.shift.type != ARM_SFT_INVALID and i.shift.value: print("\t\t\tShift: %u = %u" \ @@ -92,6 +92,8 @@ def print_insn_detail(insn): c += 1 + if not insn.cc in [ARM_CC_AL, ARM_CC_INVALID]: + print("\tCode condition: %u" % insn.cc) if insn.update_flags: print("\tUpdate-flags: True") if insn.writeback: @@ -99,8 +101,6 @@ def print_insn_detail(insn): print("\tWrite-back: Post") else: print("\tWrite-back: Pre") - if not insn.cc in [ARM_CC_AL, ARM_CC_INVALID]: - print("\tCode condition: %u" % insn.cc) if insn.cps_mode: print("\tCPSI-mode: %u" %(insn.cps_mode)) if insn.cps_flag: @@ -146,6 +146,7 @@ def test_class(): for insn in md.disasm(code, 0x80001000): print_insn_detail(insn) print () + print("0x%x:\n" % (insn.address + insn.size)) except CsError as e: print("ERROR: %s" % e) diff --git a/bindings/python/test_arm64.py b/bindings/python/test_arm64.py index 78b6483b6e..78a49ea8a2 100755 --- a/bindings/python/test_arm64.py +++ b/bindings/python/test_arm64.py @@ -5,10 +5,10 @@ from __future__ import print_function from capstone import * from capstone.arm64 import * -from xprint import to_hex, to_x +from xprint import to_hex, to_x, to_x_32 -ARM64_CODE = b"\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c" +ARM64_CODE = b"\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c\xfd\x7b\xba\xa9\xfd\xc7\x43\xf8" all_tests = ( (CS_ARCH_ARM64, CS_MODE_ARM, ARM64_CODE, "ARM-64"), @@ -46,7 +46,7 @@ def print_insn_detail(insn): % (c, insn.reg_name(i.mem.index))) if i.mem.disp != 0: print("\t\t\toperands[%u].mem.disp: 0x%s" \ - % (c, to_x(i.mem.disp))) + % (c, to_x_32(i.mem.disp))) if i.type == ARM64_OP_REG_MRS: print("\t\toperands[%u].type: REG_MRS = 0x%x" % (c, i.reg)) if i.type == ARM64_OP_REG_MSR: @@ -74,6 +74,13 @@ def print_insn_detail(insn): if i.sme_index.disp != 0 : print("\t\t\toperands[%u].index.disp: 0x%x" %(c, i.sme_index.disp)) + if i.access == CS_AC_READ: + print("\t\toperands[%u].access: READ" % (c)) + elif i.access == CS_AC_WRITE: + print("\t\toperands[%u].access: WRITE" % (c)) + elif i.access == CS_AC_READ | CS_AC_WRITE: + print("\t\toperands[%u].access: READ | WRITE" % (c)) + if i.shift.type != ARM64_SFT_INVALID and i.shift.value: print("\t\t\tShift: type = %u, value = %u" % (i.shift.type, i.shift.value)) @@ -86,13 +93,6 @@ def print_insn_detail(insn): if i.vector_index != -1: print("\t\t\tVector Index: %u" % i.vector_index) - if i.access == CS_AC_READ: - print("\t\toperands[%u].access: READ\n" % (c)) - elif i.access == CS_AC_WRITE: - print("\t\toperands[%u].access: WRITE\n" % (c)) - elif i.access == CS_AC_READ | CS_AC_WRITE: - print("\t\toperands[%u].access: READ | WRITE\n" % (c)) - if insn.writeback: if insn.post_index: diff --git a/bindings/python/test_basic.py b/bindings/python/test_basic.py index 55d153bfc3..c2942b4898 100755 --- a/bindings/python/test_basic.py +++ b/bindings/python/test_basic.py @@ -34,7 +34,10 @@ M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24" M680X_CODE = b"\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" +EVM_CODE = b"\x60\x61" WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" +MOS65XX_CODE = b"\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42" +EBPF_CODE = b"\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" RISCV_CODE64 = b"\x13\x04\xa8\x7a" @@ -58,15 +61,18 @@ (CS_ARCH_ARM64, CS_MODE_ARM, ARM64_CODE, "ARM-64", None), (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64", None), (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, PPC_CODE, "PPC-64, print register with number only", CS_OPT_SYNTAX_NOREGNAME), - (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", CS_OPT_SYNTAX_NOREGNAME), + (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN + CS_MODE_QPX, PPC_CODE2, "PPC-64 + QPX", None), (CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", None), (CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None), (CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None), (CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None), - (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None), + (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K", None), (CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x", None), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None), + (CS_ARCH_EVM, 0, EVM_CODE, "EVM", None), (CS_ARCH_WASM, 0, WASM_CODE, "WASM", None), + (CS_ARCH_MOS65XX, 0, MOS65XX_CODE, "MOS65XX", None), + (CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED, EBPF_CODE, "eBPF", None), (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "RISCV32", None), (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "RISCV64", None), ) @@ -76,7 +82,7 @@ def test_cs_disasm_quick(): for arch, mode, code, comment, syntax in all_tests: print('*' * 40) print("Platform: %s" % comment) - print("Disasm:"), + print("Disasm:") print(to_hex(code)) for insn in cs_disasm_quick(arch, mode, code, 0x1000): print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) @@ -119,7 +125,7 @@ def test_class(): for insn in md.disasm(code, 0x1000): # bytes = binascii.hexlify(insn.bytes) # print("0x%x:\t%s\t%s\t// hex-code: %s" %(insn.address, insn.mnemonic, insn.op_str, bytes)) - print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + print("0x%x:\t%s\t\t%s" % (insn.address, insn.mnemonic, insn.op_str)) print("0x%x:" % (insn.address + insn.size)) print() diff --git a/bindings/python/test_bpf.py b/bindings/python/test_bpf.py index 4df7f3599e..2e7d64d8b7 100755 --- a/bindings/python/test_bpf.py +++ b/bindings/python/test_bpf.py @@ -6,7 +6,7 @@ from __future__ import print_function from capstone import * from capstone.bpf import * -from xprint import to_hex, to_x_32 +from xprint import to_hex, to_x, to_x_32 CBPF_CODE = b"\x94\x09\x00\x00\x37\x13\x03\x00\x87\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00" @@ -37,7 +37,7 @@ def print_insn_detail(insn): if op.type == BPF_OP_REG: print("REG = " + insn.reg_name(op.reg)) elif op.type == BPF_OP_IMM: - print("IMM = " + hex(op.imm)[:-1]) + print("IMM = 0x" + to_x(op.imm)) elif op.type == BPF_OP_OFF: print("OFF = +0x" + to_x_32(op.off)) elif op.type == BPF_OP_MEM: diff --git a/bindings/python/test_customized_mnem.py b/bindings/python/test_customized_mnem.py index a09cc727fd..57dd12a0f7 100755 --- a/bindings/python/test_customized_mnem.py +++ b/bindings/python/test_customized_mnem.py @@ -15,7 +15,7 @@ def print_insn(md, code): print("%s\t" % to_hex(code, False), end="") for insn in md.disasm(code, 0x1000): - print("\t%s\t%s\n" % (insn.mnemonic, insn.op_str)) + print("\t%s\t%s" % (insn.mnemonic, insn.op_str)) def test(): @@ -25,11 +25,11 @@ def test(): print("Disassemble X86 code with default instruction mnemonic") print_insn(md, X86_CODE32) - print("Now customize engine to change mnemonic from 'JNE' to 'JNZ'") + print("\nNow customize engine to change mnemonic from 'JNE' to 'JNZ'") md.mnemonic_setup(X86_INS_JNE, "jnz") print_insn(md, X86_CODE32) - print("Reset engine to use the default mnemonic") + print("\nReset engine to use the default mnemonic") md.mnemonic_setup(X86_INS_JNE, None) print_insn(md, X86_CODE32) except CsError as e: diff --git a/bindings/python/test_detail.py b/bindings/python/test_detail.py index e7cc6a8823..021ab896e7 100755 --- a/bindings/python/test_detail.py +++ b/bindings/python/test_detail.py @@ -4,6 +4,7 @@ from __future__ import print_function from capstone import * +from xprint import to_hex X86_CODE16 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00" X86_CODE32 = b"\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00" @@ -11,15 +12,15 @@ ARM_CODE = b"\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" ARM_CODE2 = b"\x10\xf1\x10\xe7\x11\xf2\x31\xe7\xdc\xa1\x2e\xf3\xe8\x4e\x62\xf3" THUMB_CODE = b"\x70\x47\xeb\x46\x83\xb0\xc9\x68" -THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88" +THUMB_CODE2 = b"\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0" THUMB_MCLASS = b"\xef\xf3\x02\x80" ARMV8 = b"\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5" -MIPS_CODE = b"\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56" +MIPS_CODE = b"\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56\x00\x80\x04\x08" MIPS_CODE2 = b"\x56\x34\x21\x34\xc2\x17\x01\x00" MIPS_32R6M = b"\x00\x07\x00\x07\x00\x11\x93\x7c\x01\x8c\x8b\x7c\x00\xc7\x48\xd0" MIPS_32R6 = b"\xec\x80\x00\x19\x7c\x43\x22\xa0" ARM64_CODE = b"\x09\x00\x38\xd5\xbf\x40\x00\xd5\x0c\x05\x13\xd5\x20\x50\x02\x0e\x20\xe4\x3d\x0f\x00\x18\xa0\x5f\xa2\x00\xae\x9e\x9f\x37\x03\xd5\xbf\x33\x03\xd5\xdf\x3f\x03\xd5\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9\x20\x04\x81\xda\x20\x08\x02\x8b\x10\x5b\xe8\x3c" -PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21" +PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14" PPC_CODE2 = b"\x10\x60\x2a\x10\x10\x64\x28\x88\x7c\x4a\x5d\x0f" SPARC_CODE = b"\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03" SPARCV9_CODE = b"\x81\xa8\x0a\x24\x89\xa0\x10\x20\x89\xa0\x1a\x60\x89\xa0\x00\xe0" @@ -27,6 +28,8 @@ XCORE_CODE = b"\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10" M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" M680X_CODE = b"\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" +MOS65XX_CODE = b"\x0A\x00\xFE\x34\x12\xD0\xFF\xEA\x19\x56\x34\x46\x80" +EBPF_CODE = b"\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" all_tests = ( (CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", None), @@ -50,8 +53,10 @@ (CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", None), (CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", None), (CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", None), - (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None), + (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K", None), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None), + (CS_ARCH_MOS65XX, 0, MOS65XX_CODE, "MOS65XX", None), + (CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED, EBPF_CODE, "eBPF", None), ) @@ -65,29 +70,30 @@ def print_detail(insn): return if len(insn.regs_read) > 0: - print("\tImplicit registers read: ", end=''), + print("\tImplicit registers read: ", end='') for m in insn.regs_read: - print("%s " % insn.reg_name(m), end=''), + print("%s " % insn.reg_name(m), end='') print() if len(insn.regs_write) > 0: - print("\tImplicit registers modified: ", end=''), + print("\tImplicit registers modified: ", end='') for m in insn.regs_write: - print("%s " % insn.reg_name(m), end=''), + print("%s " % insn.reg_name(m), end='') print() if len(insn.groups) > 0: - print("\tThis instruction belongs to groups: ", end=''), + print("\tThis instruction belongs to groups: ", end='') for m in insn.groups: - print("%s " % insn.group_name(m), end=''), + print("%s " % insn.group_name(m), end='') print() # ## Test class Cs def test_class(): for (arch, mode, code, comment, syntax) in all_tests: - print('*' * 40) + print('*' * 16) print("Platform: %s" % comment) + print("Code: %s" % to_hex(code)) print("Disasm:") try: @@ -100,6 +106,7 @@ def test_class(): for insn in md.disasm(code, 0x1000): print_detail(insn) + print("0x%x:" % (insn.address + insn.size)) print() except CsError as e: print("ERROR: %s" % e) diff --git a/bindings/python/test_evm.py b/bindings/python/test_evm.py index 8922fe0e32..97838a75a3 100755 --- a/bindings/python/test_evm.py +++ b/bindings/python/test_evm.py @@ -21,6 +21,7 @@ def test_class(): address = 0x80001000 for (arch, mode, code, comment) in all_tests: + print("*" * 16) print("Platform: %s" % comment) print("Code: %s " % to_hex(code)) print("Disasm:") @@ -41,6 +42,7 @@ def test_class(): for m in i.groups: print("%s " % i.group_name(m), end=''), print() + print ("0x%x:\n" % (i.address + i.size)) except CsError as e: print("ERROR: %s" % e.__str__()) diff --git a/bindings/python/test_m68k.py b/bindings/python/test_m68k.py index 557369ccaf..2f6b53791e 100755 --- a/bindings/python/test_m68k.py +++ b/bindings/python/test_m68k.py @@ -4,9 +4,9 @@ from __future__ import print_function from capstone import * from capstone.m68k import * -from xprint import to_hex, to_x +from xprint import to_hex -M68K_CODE = b"\x4c\x00\x54\x04\x48\xe7\xe0\x30\x4c\xdf\x0c\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4e\xb9\x00\x00\x00\x12\x4e\x75" +M68K_CODE = b"\xf0\x10\xf0\x00\x48\xaf\xff\xff\x7f\xff\x11\xb0\x01\x37\x7f\xff\xff\xff\x12\x34\x56\x78\x01\x33\x10\x10\x10\x10\x32\x32\x32\x32\x4C\x00\x54\x04\x48\xe7\xe0\x30\x4C\xDF\x0C\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" all_tests = ( (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K"), @@ -54,9 +54,9 @@ def print_read_write_regs(insn): def print_insn_detail(insn): if len(insn.operands) > 0: print("\top_count: %u" % (len(insn.operands))) - print("\tgroups_count: %u" % len(insn.groups)) print_read_write_regs(insn) + print("\tgroups_count: %u" % len(insn.groups)) for i, op in enumerate(insn.operands): if op.type == M68K_OP_REG: @@ -80,10 +80,14 @@ def print_insn_detail(insn): print("\t\taddress mode: %s" % (s_addressing_modes[op.address_mode])) elif op.type == M68K_OP_FP_SINGLE: print("\t\toperands[%u].type: FP_SINGLE" % i) - print("\t\toperands[%u].simm: %f", i, op.simm) + print("\t\toperands[%u].simm: %f" % (i, op.simm)) elif op.type == M68K_OP_FP_DOUBLE: print("\t\toperands[%u].type: FP_DOUBLE" % i) - print("\t\toperands[%u].dimm: %lf", i, op.dimm) + print("\t\toperands[%u].dimm: %lf" % (i, op.dimm)) + elif op.type == M68K_OP_REG_BITS: + print("\t\toperands[%u].type: REG_BITS = $%x" % (i, op.register_bits)) + elif op.type == M68K_OP_REG_PAIR: + print("\t\toperands[%u].type: REG_PAIR = (%s, %s)" % (i, insn.reg_name(op.reg_pair.reg_0), insn.reg_name(op.reg_pair.reg_1))) elif op.type == M68K_OP_BR_DISP: print("\t\toperands[%u].br_disp.disp: 0x%x" % (i, op.br_disp.disp)) print("\t\toperands[%u].br_disp.disp_size: %d" % (i, op.br_disp.disp_size)) diff --git a/bindings/python/test_mips.py b/bindings/python/test_mips.py index 976380c2df..b775ef5d93 100755 --- a/bindings/python/test_mips.py +++ b/bindings/python/test_mips.py @@ -11,12 +11,15 @@ MIPS_CODE2 = b"\x56\x34\x21\x34\xc2\x17\x01\x00" MIPS_32R6M = b"\x00\x07\x00\x07\x00\x11\x93\x7c\x01\x8c\x8b\x7c\x00\xc7\x48\xd0" MIPS_32R6 = b"\xec\x80\x00\x19\x7c\x43\x22\xa0" +MIPS_64SD = b"\x70\x00\xb2\xff" all_tests = ( (CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, MIPS_CODE, "MIPS-32 (Big-endian)"), (CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, MIPS_CODE2, "MIPS-64-EL (Little-endian)"), (CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_MICRO + CS_MODE_BIG_ENDIAN, MIPS_32R6M, "MIPS-32R6 | Micro (Big-endian)"), (CS_ARCH_MIPS, CS_MODE_MIPS32R6 + CS_MODE_BIG_ENDIAN, MIPS_32R6, "MIPS-32R6 (Big-endian)"), + (CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_MIPS2 | CS_MODE_LITTLE_ENDIAN, MIPS_64SD, "MIPS-64-EL + Mips II (Little-endian)"), + (CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN, MIPS_64SD, "MIPS-64-EL (Little-endian)"), ) diff --git a/bindings/python/test_mos65xx.py b/bindings/python/test_mos65xx.py index 5b667b1f04..387f1a14cc 100755 --- a/bindings/python/test_mos65xx.py +++ b/bindings/python/test_mos65xx.py @@ -6,7 +6,17 @@ from capstone.mos65xx import * from xprint import to_hex, to_x -MOS65XX_CODE = b"\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42" +M6502_CODE = b"\xa1\x12\xa5\x12\xa9\x12\xad\x34\x12\xb1\x12\xb5\x12\xb9\x34\x12\xbd\x34\x12\x0d\x34\x12\x00\x81\x87\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42" +M65C02_CODE = b"\x1a\x3a\x02\x12\x03\x5c\x34\x12" +MW65C02_CODE = b"\x07\x12\x27\x12\x47\x12\x67\x12\x87\x12\xa7\x12\xc7\x12\xe7\x12\x10\xfe\x0f\x12\xfd\x4f\x12\xfd\x8f\x12\xfd\xcf\x12\xfd" +M65816_CODE = b"\xa9\x34\x12\xad\x34\x12\xbd\x34\x12\xb9\x34\x12\xaf\x56\x34\x12\xbf\x56\x34\x12\xa5\x12\xb5\x12\xb2\x12\xa1\x12\xb1\x12\xa7\x12\xb7\x12\xa3\x12\xb3\x12\xc2\x00\xe2\x00\x54\x34\x12\x44\x34\x12\x02\x12" + +all_tests = ( + (CS_ARCH_MOS65XX, CS_MODE_MOS65XX_6502, M6502_CODE, "MOS65XX_6502"), + (CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65C02, M65C02_CODE, "MOS65XX_65C02"), + (CS_ARCH_MOS65XX, CS_MODE_MOS65XX_W65C02, MW65C02_CODE, "MOS65XX_W65C02"), + (CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65816_LONG_MX, M65816_CODE, "MOS65XX_65816 (long m/x)"), +) address_modes=[ "No address mode", @@ -35,7 +45,7 @@ "absolute long indexed with x", "stack relative", "stack relative indirect indexed with y", -]; +] def print_insn_detail(insn): @@ -62,21 +72,23 @@ def print_insn_detail(insn): # ## Test class Cs def test_class(): - print("*" * 16) - print("Platform: %s" % "MOS65XX") - print("Code: %s" % to_hex(MOS65XX_CODE)) - print("Disasm:") + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" % comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") - try: - md = Cs(CS_ARCH_MOS65XX, 0) - md.detail = True - for insn in md.disasm(MOS65XX_CODE, 0x1000): - print_insn_detail(insn) - print() + try: + md = Cs(arch, mode) + md.detail = True + md.syntax = CS_OPT_SYNTAX_MOTOROLA + for insn in md.disasm(code, 0x1000): + print_insn_detail(insn) + print() - print("0x%x:\n" % (insn.address + insn.size)) - except CsError as e: - print("ERROR: %s" % e) + print("0x%x:\n" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" % e) if __name__ == '__main__': diff --git a/bindings/python/test_ppc.py b/bindings/python/test_ppc.py index acb4b26ae4..8bc926ceaa 100755 --- a/bindings/python/test_ppc.py +++ b/bindings/python/test_ppc.py @@ -4,7 +4,7 @@ from __future__ import print_function from capstone import * from capstone.ppc import * -from xprint import to_hex, to_x_32 +from xprint import to_hex, to_x, to_x_32 PPC_CODE = b"\x43\x20\x0c\x07\x41\x56\xff\x17\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14" PPC_CODE2 = b"\x10\x60\x2a\x10\x10\x64\x28\x88\x7c\x4a\x5d\x0f" @@ -32,7 +32,7 @@ def print_insn_detail(insn): if i.type == PPC_OP_REG: print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg))) if i.type == PPC_OP_IMM: - print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x_32(i.imm))) + print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm))) if i.type == PPC_OP_MEM: print("\t\toperands[%u].type: MEM" % c) if i.mem.base != 0: diff --git a/bindings/python/test_riscv.py b/bindings/python/test_riscv.py index 21bd03cf2f..0df298c6f8 100755 --- a/bindings/python/test_riscv.py +++ b/bindings/python/test_riscv.py @@ -41,6 +41,9 @@ def print_insn_detail(insn): print("\t\t\toperands[%u].mem.disp: 0x%s" \ % (c, to_x(i.mem.disp))) c += 1 + + if len(insn.groups) > 0: + print('\tgroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups))) # ## Test class Cs diff --git a/bindings/python/test_tms320c64x.py b/bindings/python/test_tms320c64x.py index 4960401c40..c2c960ae8d 100755 --- a/bindings/python/test_tms320c64x.py +++ b/bindings/python/test_tms320c64x.py @@ -67,7 +67,29 @@ def print_insn_detail(insn): if i.type == TMS320C64X_OP_REGPAIR: print("\t\toperands[%u].type: REGPAIR = %s:%s" % (c, insn.reg_name(i.reg + 1), insn.reg_name(i.reg))) c += 1 + + print("\tFunctional unit: ", end="") + if insn.funit.unit == TMS320C64X_FUNIT_D: + print("D%u" % insn.funit.side) + elif insn.funit.unit == TMS320C64X_FUNIT_L: + print("L%u" % insn.funit.side) + elif insn.funit.unit == TMS320C64X_FUNIT_M: + print("M%u" % insn.funit.side) + elif insn.funit.unit == TMS320C64X_FUNIT_S: + print("S%u" % insn.funit.side) + elif insn.funit.unit == TMS320C64X_FUNIT_NO: + print("No Functional Unit") + else: + print("Unknown (Unit %u, Side %u)" % (insn.funit.unit, insn.funit.side)) + if insn.funit.crosspath == 1: + print("\tCrosspath: 1") + + if insn.condition.reg != TMS320C64X_REG_INVALID: + print("\tCondition: [%c%s]" % ("!" if insn.condition.zero == 1 else " ", insn.reg_name(insn.condition.reg))) + print("\tParallel: %s" % ("true" if insn.parallel == 1 else "false")) + + print() # ## Test class Cs def test_class(): @@ -83,7 +105,6 @@ def test_class(): md.detail = True for insn in md.disasm(code, 0x1000): print_insn_detail(insn) - print () print("0x%x:\n" % (insn.address + insn.size)) except CsError as e: print("ERROR: %s" %e) diff --git a/bindings/python/test_tricore.py b/bindings/python/test_tricore.py index 7fad11007e..a247b325cb 100755 --- a/bindings/python/test_tricore.py +++ b/bindings/python/test_tricore.py @@ -5,10 +5,9 @@ from __future__ import print_function from capstone import * from capstone.tricore import * -from xprint import to_x, to_hex +from xprint import to_x_32, to_hex -TRICORE_CODE = b"\x16\x01\x20\x01\x1d\x00\x02\x00\x8f\x70\x00\x11\x40\xae\x89\xee\x04\x09\x42\xf2\xe2\xf2\xc2\x11\x19" \ - b"\xff\xc0\x70\x19\xff\x20\x10" +TRICORE_CODE = b"\x09\xcf\xbc\xf5\x09\xf4\x01\x00\x89\xfb\x8f\x74\x89\xfe\x48\x01\x29\x00\x19\x25\x29\x03\x09\xf4\x85\xf9\x68\x0f\x16\x01" all_tests = ( (CS_ARCH_TRICORE, CS_MODE_TRICORE_162, TRICORE_CODE, "TriCore"), @@ -30,7 +29,7 @@ def print_insn_detail(insn): if i.type == TRICORE_OP_REG: print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg))) if i.type == TRICORE_OP_IMM: - print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm))) + print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x_32(i.imm))) if i.type == TRICORE_OP_MEM: print("\t\toperands[%u].type: MEM" % c) if i.mem.base != 0: @@ -38,8 +37,9 @@ def print_insn_detail(insn): % (c, insn.reg_name(i.mem.base))) if i.mem.disp != 0: print("\t\t\toperands[%u].mem.disp: 0x%s" \ - % (c, to_x(i.mem.disp))) + % (c, to_x_32(i.mem.disp))) c += 1 + print() # ## Test class Cs @@ -55,8 +55,7 @@ def test_class(): md.detail = True for insn in md.disasm(code, 0x1000): print_insn_detail(insn) - print() - print("0x%x:\n" % (insn.address + insn.size)) + print("0x%x:" % (insn.address + insn.size)) except CsError as e: print("ERROR: %s" % e) diff --git a/bindings/python/test_x86.py b/bindings/python/test_x86.py index d24cdde1b1..3c08e7783c 100755 --- a/bindings/python/test_x86.py +++ b/bindings/python/test_x86.py @@ -115,6 +115,50 @@ def get_eflag_name(eflag): else: return None +def get_fpu_flag_name(flag): + if flag == X86_FPU_FLAGS_MODIFY_C0: + return "MOD_C0" + elif flag == X86_FPU_FLAGS_MODIFY_C1: + return "MOD_C1" + elif flag == X86_FPU_FLAGS_MODIFY_C2: + return "MOD_C2" + elif flag == X86_FPU_FLAGS_MODIFY_C3: + return "MOD_C3" + elif flag == X86_FPU_FLAGS_RESET_C0: + return "RESET_C0" + elif flag == X86_FPU_FLAGS_RESET_C1: + return "RESET_C1" + elif flag == X86_FPU_FLAGS_RESET_C2: + return "RESET_C2" + elif flag == X86_FPU_FLAGS_RESET_C3: + return "RESET_C3" + elif flag == X86_FPU_FLAGS_SET_C0: + return "SET_C0" + elif flag == X86_FPU_FLAGS_SET_C1: + return "SET_C1" + elif flag == X86_FPU_FLAGS_SET_C2: + return "SET_C2" + elif flag == X86_FPU_FLAGS_SET_C3: + return "SET_C3" + elif flag == X86_FPU_FLAGS_UNDEFINED_C0: + return "UNDEF_C0" + elif flag == X86_FPU_FLAGS_UNDEFINED_C1: + return "UNDEF_C1" + elif flag == X86_FPU_FLAGS_UNDEFINED_C2: + return "UNDEF_C2" + elif flag == X86_FPU_FLAGS_UNDEFINED_C3: + return "UNDEF_C3" + elif flag == X86_FPU_FLAGS_TEST_C0: + return "TEST_C0" + elif flag == X86_FPU_FLAGS_TEST_C1: + return "TEST_C1" + elif flag == X86_FPU_FLAGS_TEST_C2: + return "TEST_C2" + elif flag == X86_FPU_FLAGS_TEST_C3: + return "TEST_C3" + else: + return None + def print_insn_detail(mode, insn): def print_string_hex(comment, str): @@ -150,7 +194,7 @@ def print_string_hex(comment, str): print("\tmodrm_offset: 0x%x" % (insn.encoding.modrm_offset)) # print displacement value - print("\tdisp: 0x%s" % to_x_32(insn.disp)) + print("\tdisp: 0x%s" % to_x(insn.disp)) # print displacement offset (offset into instruction bytes) if insn.encoding.disp_offset != 0: @@ -236,11 +280,11 @@ def print_string_hex(comment, str): print("\t\toperands[%u].size: %u" % (c, i.size)) if i.access == CS_AC_READ: - print("\t\toperands[%u].access: READ\n" % (c)) + print("\t\toperands[%u].access: READ" % (c)) elif i.access == CS_AC_WRITE: - print("\t\toperands[%u].access: WRITE\n" % (c)) + print("\t\toperands[%u].access: WRITE" % (c)) elif i.access == CS_AC_READ | CS_AC_WRITE: - print("\t\toperands[%u].access: READ | WRITE\n" % (c)) + print("\t\toperands[%u].access: READ | WRITE" % (c)) (regs_read, regs_write) = insn.regs_access() @@ -255,13 +299,22 @@ def print_string_hex(comment, str): for r in regs_write: print(" %s" %(insn.reg_name(r)), end="") print("") - - if insn.eflags: + + if insn.eflags or insn.fpu_flags: updated_flags = [] - for i in range(0,46): - if insn.eflags & (1 << i): - updated_flags.append(get_eflag_name(1 << i)) - print("\tEFLAGS: %s" % (','.join(p for p in updated_flags))) + for group in insn.groups: + if group == X86_GRP_FPU: + for i in range(64): + if insn.fpu_flags & (1 << i): + updated_flags.append(get_fpu_flag_name(1 << i)) + print("\tFPU_FLAGS: %s" % (' '.join(p for p in updated_flags))) + break + + if not updated_flags: + for i in range(64): + if insn.eflags & (1 << i): + updated_flags.append(get_eflag_name(1 << i)) + print("\tEFLAGS: %s" % (' '.join(p for p in updated_flags))) # ## Test class Cs diff --git a/tests/Makefile b/tests/Makefile index b9e90c6d01..1a34994b22 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -130,6 +130,7 @@ CFLAGS += -DCAPSTONE_HAS_BPF SOURCES += test_bpf.c endif ifneq (,$(findstring tricore,$(CAPSTONE_ARCHS))) +CFLAGS += -DCAPSTONE_HAS_TRICORE SOURCES += test_tricore.c endif ifneq (,$(findstring sh,$(CAPSTONE_ARCHS))) diff --git a/tests/test_arm.c b/tests/test_arm.c index a5016fafb4..6407dd314f 100644 --- a/tests/test_arm.c +++ b/tests/test_arm.c @@ -128,7 +128,7 @@ static void print_insn_detail(csh cs_handle, cs_insn *ins) } if (op->subtracted) - printf("\t\tSubtracted: True\n"); + printf("\t\toperands[%u].subtracted = True\n", i); } if (arm->cc != ARM_CC_AL && arm->cc != ARM_CC_INVALID) @@ -137,8 +137,12 @@ static void print_insn_detail(csh cs_handle, cs_insn *ins) if (arm->update_flags) printf("\tUpdate-flags: True\n"); - if (arm->writeback) - printf("\tWrite-back: True\n"); + if (arm->writeback) { + if (arm->post_index) + printf("\tWrite-back: Post\n"); + else + printf("\tWrite-back: Pre\n"); + } if (arm->cps_mode) printf("\tCPSI-mode: %u\n", arm->cps_mode); diff --git a/tests/test_basic.c b/tests/test_basic.c index 3a8e1e0b9b..44d782692f 100644 --- a/tests/test_basic.c +++ b/tests/test_basic.c @@ -67,7 +67,7 @@ static void test() #define XCORE_CODE "\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10" #endif #ifdef CAPSTONE_HAS_M68K -#define M68K_CODE "\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28" +#define M68K_CODE "\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" #endif #ifdef CAPSTONE_HAS_TMS320C64X #define TMS320C64X_CODE "\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24" @@ -84,8 +84,9 @@ static void test() #ifdef CAPSTONE_HAS_MOS65XX #define MOS65XX_CODE "\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42" #endif +#ifdef CAPSTONE_HAS_BPF #define EBPF_CODE "\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" - +#endif #ifdef CAPSTONE_HAS_RISCV #define RISCV_CODE32 "\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" #define RISCV_CODE64 "\x13\x04\xa8\x7a" // aaa80413 diff --git a/tests/test_detail.c b/tests/test_detail.c index ea7d1fdd18..c184ea6d27 100644 --- a/tests/test_detail.c +++ b/tests/test_detail.c @@ -67,7 +67,7 @@ static void test() #define XCORE_CODE "\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10" #endif #ifdef CAPSTONE_HAS_M68K -#define M68K_CODE "\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28" +#define M68K_CODE "\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" #endif #ifdef CAPSTONE_HAS_M680X #define M680X_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" @@ -75,7 +75,9 @@ static void test() #ifdef CAPSTONE_HAS_MOS65XX #define MOS65XX_CODE "\x0A\x00\xFE\x34\x12\xD0\xFF\xEA\x19\x56\x34\x46\x80" #endif +#ifdef CAPSTONE_HAS_BPF #define EBPF_CODE "\x97\x09\x00\x00\x37\x13\x03\x00\xdc\x02\x00\x00\x20\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xdb\x3a\x00\x01\x00\x00\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x6d\x33\x17\x02\x00\x00\x00\x00" +#endif struct platform platforms[] = { #ifdef CAPSTONE_HAS_X86 @@ -118,13 +120,6 @@ static void test() sizeof(ARM_CODE) - 1, "ARM" }, - { - CS_ARCH_ARM, - CS_MODE_THUMB, - (unsigned char *)THUMB_CODE2, - sizeof(THUMB_CODE2) - 1, - "THUMB-2" - }, { CS_ARCH_ARM, CS_MODE_ARM, @@ -139,6 +134,13 @@ static void test() sizeof(THUMB_CODE) - 1, "THUMB" }, + { + CS_ARCH_ARM, + CS_MODE_THUMB, + (unsigned char *)THUMB_CODE2, + sizeof(THUMB_CODE2) - 1, + "THUMB-2" + }, { CS_ARCH_ARM, (cs_mode)(CS_MODE_THUMB + CS_MODE_MCLASS), @@ -154,6 +156,15 @@ static void test() "Arm-V8" }, #endif +#ifdef CAPSTONE_HAS_ARM64 + { + CS_ARCH_ARM64, + CS_MODE_ARM, + (unsigned char *)ARM64_CODE, + sizeof(ARM64_CODE) - 1, + "ARM-64" + }, +#endif #ifdef CAPSTONE_HAS_MIPS { CS_ARCH_MIPS, @@ -184,15 +195,6 @@ static void test() "MIPS-32R6 (Big-endian)" }, #endif -#ifdef CAPSTONE_HAS_ARM64 - { - CS_ARCH_ARM64, - CS_MODE_ARM, - (unsigned char *)ARM64_CODE, - sizeof(ARM64_CODE) - 1, - "ARM-64" - }, -#endif #ifdef CAPSTONE_HAS_POWERPC { CS_ARCH_PPC, diff --git a/tests/test_m68k.c b/tests/test_m68k.c index aff11dfaca..e003f486be 100644 --- a/tests/test_m68k.c +++ b/tests/test_m68k.c @@ -57,6 +57,7 @@ const char* s_addressing_modes[] = { "Absolute Data Addressing - Short", "Absolute Data Addressing - Long", "Immediate value", + "Branch Displacement", }; static void print_read_write_regs(cs_detail* detail) @@ -143,6 +144,10 @@ static void print_insn_detail(cs_insn *ins) cs_reg_name(handle, op->reg_pair.reg_0), cs_reg_name(handle, op->reg_pair.reg_1)); break; + case M68K_OP_BR_DISP: + printf("\t\toperands[%u].br_disp.disp: 0x%x", i, op->br_disp.disp); + printf("\t\toperands[%u].br_disp.disp_size: %d", i, op->br_disp.disp_size); + break; } } diff --git a/tests/test_mos65xx.c b/tests/test_mos65xx.c index 6053c81c1f..bb53bea2e8 100644 --- a/tests/test_mos65xx.c +++ b/tests/test_mos65xx.c @@ -23,7 +23,7 @@ static void print_string_hex(const char *comment, unsigned char *str, size_t len printf("%s", comment); for (c = str; c < str + len; c++) { - printf(" 0x%02x", *c & 0xff); + printf("0x%02x ", *c & 0xff); } printf("\n"); @@ -197,7 +197,7 @@ static void test() printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); - print_string_hex("Code:", platforms[i].code, platforms[i].size); + print_string_hex("Code: ", platforms[i].code, platforms[i].size); printf("Disasm:\n"); for (j = 0; j < count; j++) { diff --git a/tests/test_riscv.c b/tests/test_riscv.c index a9b8b10c83..5b5d67c4b7 100644 --- a/tests/test_riscv.c +++ b/tests/test_riscv.c @@ -69,7 +69,7 @@ static void print_insn_detail(cs_insn *ins) //print the groups this instruction belongs to if (detail->groups_count > 0) { - printf("\tThis instruction belongs to groups: "); + printf("\tgroups: "); for (n = 0; n < detail->groups_count; n++) { printf("%s ", cs_group_name(handle, detail->groups[n])); } diff --git a/tests/test_sh.c b/tests/test_sh.c index 439b1c2241..baf97072d3 100644 --- a/tests/test_sh.c +++ b/tests/test_sh.c @@ -29,14 +29,6 @@ static void print_string_hex(const char *comment, unsigned char *str, size_t len printf("\n"); } -static void print_string_hex_short(unsigned char *str, size_t len) -{ - unsigned char *c; - - for (c = str; c < str + len; c++) - printf("%02x", *c & 0xff); -} - static void print_read_write_regs(csh handle, cs_detail *detail) { int i; @@ -73,6 +65,7 @@ static void print_insn_detail(csh handle, cs_insn *insn) cs_detail *detail = insn->detail; cs_sh *sh = NULL; int i; + int n; // detail can be NULL on "data" instruction if SKIPDATA option is turned ON if (detail == NULL) @@ -151,8 +144,12 @@ static void print_insn_detail(csh handle, cs_insn *insn) print_read_write_regs(handle, detail); - if (detail->groups_count) { - printf("\tgroups_count: %u\n", detail->groups_count); + if (detail->groups_count > 0) { + printf("\tgroups: "); + for (n = 0; n < detail->groups_count; n++) { + printf("%s ", cs_group_name(handle, detail->groups[n])); + } + printf("\n"); } printf("\n"); @@ -166,11 +163,11 @@ static bool consistency_checks() static void test() { #define SH4A_CODE \ - "\xc\x31\x10\x20\x22\x21\x36\x64\x46\x25\x12\x12\x1c\x2\x8\xc1\x5\xc7\xc" \ - "\x71\x1f\x2\x22\xcf\x6\x89\x23\x0\x2b\x41\xb\x0\xe\x40\x32\x0\xa\xf1\x9\x0" + "\x0c\x31\x10\x20\x22\x21\x36\x64\x46\x25\x12\x12\x1c\x02\x08\xc1\x05\xc7\x0c" \ + "\x71\x1f\x02\x22\xcf\x06\x89\x23\x00\x2b\x41\x0b\x00\x0e\x40\x32\x00\x0a\xf1\x09\x00" #define SH2A_CODE \ - "\x32\x11\x92\x0\x32\x49\x31\x0" + "\x32\x11\x92\x00\x32\x49\x31\x00" struct platform platforms[] = { { @@ -194,7 +191,6 @@ static void test() cs_insn *insn; int i; size_t count; - const char *nine_spaces = " "; if (!consistency_checks()) abort(); @@ -219,33 +215,25 @@ static void test() if (count) { size_t j; - printf("********************\n"); + printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code: ", platforms[i].code, platforms[i].size); printf("Disasm:\n"); for (j = 0; j < count; j++) { - int slen; - printf("0x%08x: ", (uint32_t)insn[j].address); - print_string_hex_short(insn[j].bytes, - insn[j].size); - printf("%.*s", 1 + ((5 - insn[j].size) * 2), - nine_spaces); - printf("%s", insn[j].mnemonic); - slen = (int)strlen(insn[j].mnemonic); - printf("%.*s", 1 + (5 - slen), nine_spaces); - printf("%s\n", insn[j].op_str); + printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); #ifdef WITH_DETAILS print_insn_detail(handle, &insn[j]); #endif } + printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size); // free memory allocated by cs_disasm() cs_free(insn, count); } else { - printf("********************\n"); + printf("****************\n"); printf("Platform: %s\n", platforms[i].comment); print_string_hex("Code:", platforms[i].code, platforms[i].size); diff --git a/tests/test_tms320c64x.c b/tests/test_tms320c64x.c index 86a6d76d78..28bc05e286 100644 --- a/tests/test_tms320c64x.c +++ b/tests/test_tms320c64x.c @@ -59,11 +59,11 @@ static void print_insn_detail(cs_insn *ins) printf("\t\t\toperands[%u].mem.disptype: ", i); if(op->mem.disptype == TMS320C64X_MEM_DISP_INVALID) { printf("Invalid\n"); - printf("\t\t\toperands[%u].mem.disp: %u\n", i, op->mem.disp); + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); } if(op->mem.disptype == TMS320C64X_MEM_DISP_CONSTANT) { printf("Constant\n"); - printf("\t\t\toperands[%u].mem.disp: %u\n", i, op->mem.disp); + printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp); } if(op->mem.disptype == TMS320C64X_MEM_DISP_REGISTER) { printf("Register\n"); diff --git a/tests/test_tricore.c b/tests/test_tricore.c index fc90148188..c423d72d25 100644 --- a/tests/test_tricore.c +++ b/tests/test_tricore.c @@ -132,8 +132,6 @@ static void test() printf("ERROR: Failed to disasm given code!\n"); } - printf("\n"); - cs_close(&handle); } } diff --git a/tests/test_wasm.c b/tests/test_wasm.c index 0f98bdf60d..95e387d193 100644 --- a/tests/test_wasm.c +++ b/tests/test_wasm.c @@ -78,10 +78,20 @@ static void print_insn_detail(csh cs_handle, cs_insn *ins) printf("\t\tOperand[%u] type: varuint64\n", i); printf("\t\tOperand[%u] value: 0x%" PRIx64 "\n", i, wasm->operands[i].varuint64); break; + case WASM_OP_IMM: + printf("\t\tOperand[%u] type: imm\n", i); + printf("\t\tOperand[%u] value: 0x%x 0x%x\n", i, wasm->operands[i].immediate[0], wasm->operands[i].immediate[1]); + break; + case WASM_OP_BRTABLE: + printf("\t\tOperand[%u] type: brtable\n", i); + printf("\t\tOperand[%u] value: length=0x%x, address=0x%" PRIx64 ", default_target=%x\n", i, wasm->operands[i].brtable.length, wasm->operands[i].brtable.address, wasm->operands[i].brtable.default_target); + break; } printf("\t\tOperand[%u] size: %u\n", i, wasm->operands[i].size); } } + + printf("\n"); } static void test()