Add Python bindings for SH

This commit is contained in:
Peace-Maker 2023-07-13 19:16:06 +02:00
parent 2aa4eb559d
commit a4699018fb
9 changed files with 564 additions and 8 deletions

1
.gitignore vendored
View file

@ -72,6 +72,7 @@ tests/test_evm
tests/test_wasm
tests/test_mos65xx
tests/test_bpf
tests/test_sh
tests/test_riscv
# regress binaries

View file

@ -5,7 +5,7 @@ import sys, re
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 @@ template = {
'mos65xx.h': 'mos65xx',
'bpf.h': 'bpf',
'riscv.h': 'riscv',
'sh.h': 'sh',
'tricore.h': ['TRICORE', 'TriCore'],
'comment_open': '#',
'comment_close': '',

View file

@ -35,10 +35,11 @@ __all__ = [
'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 @@ __all__ = [
'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',
@ -207,7 +215,7 @@ CS_ARCH_MOS65XX = 12
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
@ -261,6 +269,13 @@ CS_MODE_MOS65XX_65816 = (1 << 4) # MOS65XXX WDC 65816, 8-bit m/x
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
@ -425,7 +440,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_ = (
@ -445,6 +460,7 @@ class _cs_arch(ctypes.Union):
('wasm', wasm.CsWasm),
('bpf', bpf.CsBPF),
('riscv', riscv.CsRISCV),
('sh', sh.CsSH),
('tricore', tricore.CsTriCore),
)
@ -772,6 +788,8 @@ class CsInsn(object):
(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)
@ -1240,7 +1258,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 = ""

View file

@ -0,0 +1,66 @@
# Capstone Python bindings, by Peace-Maker <peacemakerctf@gmail.com>
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]))

View file

@ -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

View file

@ -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())

View file

@ -41,7 +41,7 @@ else:
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"],

97
bindings/python/test_sh.py Executable file
View file

@ -0,0 +1,97 @@
#!/usr/bin/env python
# Capstone Python bindings, by Peace-Maker <peacemakerctf@gmail.com>
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()

View file

@ -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)))