python: support XCore
This commit is contained in:
parent
52a8d2afa2
commit
553bb488d7
|
@ -38,6 +38,7 @@ tests/test_ppc
|
|||
tests/test_skipdata
|
||||
tests/test_sparc
|
||||
tests/test_systemz
|
||||
tests/test_xcore
|
||||
tests/*.static
|
||||
|
||||
# vim tmp file
|
||||
|
|
|
@ -55,7 +55,7 @@ static void set_mem_access(MCInst *MI, bool status, int reg)
|
|||
}
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.direct = 1;
|
||||
} else {
|
||||
// the last op should be the memory base
|
||||
MI->flat_insn.xcore.op_count--;
|
||||
|
@ -64,9 +64,9 @@ static void set_mem_access(MCInst *MI, bool status, int reg)
|
|||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
|
||||
if (reg > 0)
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.direct = 1;
|
||||
else
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = -1;
|
||||
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.direct = -1;
|
||||
}
|
||||
} else {
|
||||
// done, create the next operand slot
|
||||
|
|
|
@ -10,6 +10,7 @@ TEST_PPC = $(TMPDIR)/test_ppc
|
|||
TEST_SPARC = $(TMPDIR)/test_sparc
|
||||
TEST_SYSZ = $(TMPDIR)/test_systemz
|
||||
TEST_X86 = $(TMPDIR)/test_x86
|
||||
TEST_XCORE = $(TMPDIR)/test_xcore
|
||||
|
||||
.PHONY: all expected python java ocaml
|
||||
|
||||
|
@ -33,6 +34,7 @@ expected:
|
|||
../tests/test_sparc > $(TEST_SPARC)_e
|
||||
../tests/test_systemz > $(TEST_SYSZ)_e
|
||||
../tests/test_x86 > $(TEST_X86)_e
|
||||
../tests/test_xcore > $(TEST_XCORE)_e
|
||||
|
||||
python: FORCE
|
||||
cd python && $(MAKE)
|
||||
|
@ -44,6 +46,7 @@ python: FORCE
|
|||
python python/test_sparc.py > $(TEST_SPARC)_o
|
||||
python python/test_systemz.py > $(TEST_SYSZ)_o
|
||||
python python/test_x86.py > $(TEST_X86)_o
|
||||
python python/test_xcore.py > $(TEST_XCORE)_o
|
||||
$(MAKE) test_diff
|
||||
|
||||
java: FORCE
|
||||
|
@ -56,6 +59,7 @@ java: FORCE
|
|||
cd java && ./run.sh sparc > $(TEST_SPARC)_o
|
||||
cd java && ./run.sh systemz > $(TEST_SYSZ)_o
|
||||
cd java && ./run.sh x86 > $(TEST_X86)_o
|
||||
cd java && ./run.sh xcore > $(TEST_XCORE)_o
|
||||
$(MAKE) test_diff
|
||||
|
||||
ocaml: FORCE
|
||||
|
@ -69,6 +73,7 @@ test_diff: FORCE
|
|||
$(DIFF) $(TEST_SPARC)_e $(TEST_SPARC)_o
|
||||
$(DIFF) $(TEST_SYSZ)_e $(TEST_SYSZ)_o
|
||||
$(DIFF) $(TEST_X86)_e $(TEST_X86)_o
|
||||
$(DIFF) $(TEST_XCORE)_e $(TEST_XCORE)_o
|
||||
|
||||
clean:
|
||||
rm -rf $(TMPDIR)
|
||||
|
|
|
@ -5,7 +5,7 @@ import sys, re
|
|||
|
||||
INCL_DIR = '../include/'
|
||||
|
||||
include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h' ]
|
||||
include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h' ]
|
||||
|
||||
template = {
|
||||
'java': {
|
||||
|
@ -21,6 +21,7 @@ template = {
|
|||
'ppc.h': 'Ppc',
|
||||
'sparc.h': 'Sparc',
|
||||
'systemz.h': 'Sysz',
|
||||
'xcore.h': 'Xcore',
|
||||
'comment_open': '\t//',
|
||||
'comment_close': '',
|
||||
},
|
||||
|
@ -37,6 +38,7 @@ template = {
|
|||
'ppc.h': 'ppc',
|
||||
'sparc.h': 'sparc',
|
||||
'systemz.h': 'sysz',
|
||||
'xcore.h': 'xcore',
|
||||
'comment_open': '#',
|
||||
'comment_close': '',
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ install_cython:
|
|||
cp capstone/sysz_const.py $(OBJDIR)/pyx/sysz_const.pyx
|
||||
cp capstone/x86.py $(OBJDIR)/pyx/x86.pyx
|
||||
cp capstone/x86_const.py $(OBJDIR)/pyx/x86_const.pyx
|
||||
cp capstone/xcore.py $(OBJDIR)/pyx/xcore.pyx
|
||||
cp capstone/xcore_const.py $(OBJDIR)/pyx/xcore_const.pyx
|
||||
cd $(OBJDIR) && python setup_cython.py build -b ./tmp install
|
||||
|
||||
clean:
|
||||
|
|
|
@ -3,7 +3,7 @@ import sys
|
|||
_python2 = sys.version_info.major < 3
|
||||
if _python2:
|
||||
range = xrange
|
||||
from capstone import arm, arm64, mips, ppc, sparc, systemz, x86
|
||||
from capstone import arm, arm64, mips, ppc, sparc, systemz, x86, xcore
|
||||
|
||||
__all__ = [
|
||||
'Cs',
|
||||
|
@ -26,6 +26,7 @@ __all__ = [
|
|||
'CS_ARCH_PPC',
|
||||
'CS_ARCH_SPARC',
|
||||
'CS_ARCH_SYSZ',
|
||||
'CS_ARCH_XCORE',
|
||||
'CS_ARCH_ALL',
|
||||
|
||||
'CS_MODE_LITTLE_ENDIAN',
|
||||
|
@ -84,7 +85,8 @@ CS_ARCH_X86 = 3
|
|||
CS_ARCH_PPC = 4
|
||||
CS_ARCH_SPARC = 5
|
||||
CS_ARCH_SYSZ = 6
|
||||
CS_ARCH_MAX = 7
|
||||
CS_ARCH_XCORE = 7
|
||||
CS_ARCH_MAX = 8
|
||||
CS_ARCH_ALL = 0xFFFF
|
||||
|
||||
# disasm mode
|
||||
|
@ -194,6 +196,7 @@ class _cs_arch(ctypes.Union):
|
|||
('ppc', ppc.CsPpc),
|
||||
('sparc', sparc.CsSparc),
|
||||
('sysz', systemz.CsSysz),
|
||||
('xcore', xcore.CsXcore),
|
||||
)
|
||||
|
||||
class _cs_detail(ctypes.Structure):
|
||||
|
@ -473,6 +476,8 @@ class CsInsn(object):
|
|||
(self.cc, self.hint, self.operands) = sparc.get_arch_info(detail.arch.sparc)
|
||||
elif arch == CS_ARCH_SYSZ:
|
||||
(self.cc, self.operands) = systemz.get_arch_info(detail.arch.sysz)
|
||||
elif arch == CS_ARCH_XCORE:
|
||||
self.operands = xcore.get_arch_info(detail.arch.xcore)
|
||||
|
||||
|
||||
def __getattr__(self, name):
|
||||
|
@ -790,7 +795,7 @@ def debug():
|
|||
|
||||
archs = { "arm": CS_ARCH_ARM, "arm64": CS_ARCH_ARM64, \
|
||||
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, \
|
||||
"sysz": CS_ARCH_SYSZ }
|
||||
"sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE }
|
||||
|
||||
all_archs = ""
|
||||
keys = archs.keys()
|
||||
|
|
|
@ -1,793 +0,0 @@
|
|||
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
|
||||
|
||||
import arm, arm64, mips, ppc, sparc, systemz, x86
|
||||
|
||||
__all__ = [
|
||||
'Cs',
|
||||
'CsInsn',
|
||||
|
||||
'cs_disasm_quick',
|
||||
'cs_version',
|
||||
'cs_support',
|
||||
'version_bind',
|
||||
'debug',
|
||||
|
||||
'CS_API_MAJOR',
|
||||
'CS_API_MINOR',
|
||||
|
||||
'CS_ARCH_ARM',
|
||||
'CS_ARCH_ARM64',
|
||||
'CS_ARCH_MIPS',
|
||||
'CS_ARCH_X86',
|
||||
'CS_ARCH_PPC',
|
||||
'CS_ARCH_SPARC',
|
||||
'CS_ARCH_SYSZ',
|
||||
'CS_ARCH_ALL',
|
||||
|
||||
'CS_MODE_LITTLE_ENDIAN',
|
||||
'CS_MODE_BIG_ENDIAN',
|
||||
'CS_MODE_16',
|
||||
'CS_MODE_32',
|
||||
'CS_MODE_64',
|
||||
'CS_MODE_ARM',
|
||||
'CS_MODE_THUMB',
|
||||
'CS_MODE_MICRO',
|
||||
'CS_MODE_N64',
|
||||
|
||||
'CS_OPT_SYNTAX',
|
||||
'CS_OPT_SYNTAX_DEFAULT',
|
||||
'CS_OPT_SYNTAX_INTEL',
|
||||
'CS_OPT_SYNTAX_ATT',
|
||||
'CS_OPT_SYNTAX_NOREGNAME',
|
||||
|
||||
'CS_OPT_DETAIL',
|
||||
'CS_OPT_MODE',
|
||||
'CS_OPT_ON',
|
||||
'CS_OPT_OFF',
|
||||
|
||||
'CS_ERR_OK',
|
||||
'CS_ERR_MEM',
|
||||
'CS_ERR_ARCH',
|
||||
'CS_ERR_HANDLE',
|
||||
'CS_ERR_CSH',
|
||||
'CS_ERR_MODE',
|
||||
'CS_ERR_OPTION',
|
||||
'CS_ERR_DETAIL',
|
||||
'CS_ERR_VERSION',
|
||||
'CS_ERR_MEMSETUP',
|
||||
'CS_ERR_DIET',
|
||||
'CS_ERR_SKIPDATA',
|
||||
|
||||
'CS_SUPPORT_DIET',
|
||||
'CS_SUPPORT_X86_REDUCE',
|
||||
|
||||
'CS_SKIPDATA_CALLBACK'
|
||||
]
|
||||
|
||||
# Capstone C interface
|
||||
|
||||
# API version
|
||||
CS_API_MAJOR = 2
|
||||
CS_API_MINOR = 2
|
||||
|
||||
# architectures
|
||||
CS_ARCH_ARM = 0
|
||||
CS_ARCH_ARM64 = 1
|
||||
CS_ARCH_MIPS = 2
|
||||
CS_ARCH_X86 = 3
|
||||
CS_ARCH_PPC = 4
|
||||
CS_ARCH_SPARC = 5
|
||||
CS_ARCH_SYSZ = 6
|
||||
CS_ARCH_MAX = 7
|
||||
CS_ARCH_ALL = 0xFFFF
|
||||
|
||||
# disasm mode
|
||||
CS_MODE_LITTLE_ENDIAN = 0 # little-endian mode (default mode)
|
||||
CS_MODE_ARM = 0 # ARM mode
|
||||
CS_MODE_16 = (1 << 1) # 16-bit mode (for X86, Mips)
|
||||
CS_MODE_32 = (1 << 2) # 32-bit mode (for X86, Mips)
|
||||
CS_MODE_64 = (1 << 3) # 64-bit mode (for X86, Mips)
|
||||
CS_MODE_THUMB = (1 << 4) # ARM's Thumb mode, including Thumb-2
|
||||
CS_MODE_MICRO = (1 << 4) # MicroMips mode (MIPS architecture)
|
||||
CS_MODE_N64 = (1 << 5) # Nintendo-64 mode (MIPS architecture)
|
||||
CS_MODE_V9 = (1 << 4) # Nintendo-64 mode (MIPS architecture)
|
||||
CS_MODE_BIG_ENDIAN = (1 << 31) # big-endian mode
|
||||
|
||||
# Capstone option type
|
||||
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
|
||||
CS_OPT_MEM = 4 # Change engine's mode at run-time
|
||||
CS_OPT_SKIPDATA = 5 # Skip data when disassembling
|
||||
CS_OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option
|
||||
|
||||
# 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)
|
||||
|
||||
# Capstone syntax value
|
||||
CS_OPT_SYNTAX_DEFAULT = 0 # Default assembly syntax of all platforms (CS_OPT_SYNTAX)
|
||||
CS_OPT_SYNTAX_INTEL = 1 # Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86)
|
||||
CS_OPT_SYNTAX_ATT = 2 # ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
|
||||
CS_OPT_SYNTAX_NOREGNAME = 3 # Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC)
|
||||
|
||||
# Capstone error type
|
||||
CS_ERR_OK = 0 # No error: everything was fine
|
||||
CS_ERR_MEM = 1 # Out-Of-Memory error: cs_open(), cs_disasm_ex()
|
||||
CS_ERR_ARCH = 2 # Unsupported architecture: cs_open()
|
||||
CS_ERR_HANDLE = 3 # Invalid handle: cs_op_count(), cs_op_index()
|
||||
CS_ERR_CSH = 4 # Invalid csh argument: cs_close(), cs_errno(), cs_option()
|
||||
CS_ERR_MODE = 5 # Invalid/unsupported mode: cs_open()
|
||||
CS_ERR_OPTION = 6 # Invalid/unsupported option: cs_option()
|
||||
CS_ERR_DETAIL = 7 # Invalid/unsupported option: cs_option()
|
||||
CS_ERR_MEMSETUP = 8
|
||||
CS_ERR_VERSION = 9 # Unsupported version (bindings)
|
||||
CS_ERR_DIET = 10 # Information irrelevant in diet engine
|
||||
CS_ERR_SKIPDATA = 11 # Access irrelevant data for "data" instruction in SKIPDATA mode
|
||||
|
||||
# query id for cs_support()
|
||||
CS_SUPPORT_DIET = CS_ARCH_ALL+1
|
||||
CS_SUPPORT_X86_REDUCE = CS_ARCH_ALL+2
|
||||
|
||||
import ctypes, ctypes.util, sys
|
||||
from os.path import split, join, dirname
|
||||
import distutils.sysconfig
|
||||
|
||||
|
||||
import inspect
|
||||
if not hasattr(sys.modules[__name__], '__file__'):
|
||||
__file__ = inspect.getfile(inspect.currentframe())
|
||||
|
||||
_lib_path = split(__file__)[0]
|
||||
_all_libs = ['libcapstone.dll', 'libcapstone.so', 'libcapstone.dylib']
|
||||
_found = False
|
||||
|
||||
for _lib in _all_libs:
|
||||
try:
|
||||
_lib_file = join(_lib_path, _lib)
|
||||
# print "Trying to load:", _lib_file
|
||||
_cs = ctypes.cdll.LoadLibrary(_lib_file)
|
||||
_found = True
|
||||
break
|
||||
except OSError:
|
||||
pass
|
||||
if _found == False:
|
||||
# try loading from default paths
|
||||
for _lib in _all_libs:
|
||||
try:
|
||||
_cs = ctypes.cdll.LoadLibrary(_lib)
|
||||
_found = True
|
||||
break
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if _found == False:
|
||||
# last try: loading from python lib directory
|
||||
_lib_path = distutils.sysconfig.get_python_lib()
|
||||
for _lib in _all_libs:
|
||||
try:
|
||||
_lib_file = join(_lib_path, 'capstone', _lib)
|
||||
# print "Trying to load:", _lib_file
|
||||
_cs = ctypes.cdll.LoadLibrary(_lib_file)
|
||||
_found = True
|
||||
break
|
||||
except OSError:
|
||||
pass
|
||||
if _found == False:
|
||||
raise ImportError("ERROR: fail to load the dynamic library.")
|
||||
|
||||
|
||||
# low-level structure for C code
|
||||
class _cs_arch(ctypes.Union):
|
||||
_fields_ = (
|
||||
('arm64', arm64.CsArm64),
|
||||
('arm', arm.CsArm),
|
||||
('mips', mips.CsMips),
|
||||
('x86', x86.CsX86),
|
||||
('ppc', ppc.CsPpc),
|
||||
('sparc', sparc.CsSparc),
|
||||
('sysz', systemz.CsSysz),
|
||||
)
|
||||
|
||||
class _cs_detail(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('regs_read', ctypes.c_ubyte * 12),
|
||||
('regs_read_count', ctypes.c_ubyte),
|
||||
('regs_write', ctypes.c_ubyte * 20),
|
||||
('regs_write_count', ctypes.c_ubyte),
|
||||
('groups', ctypes.c_ubyte * 8),
|
||||
('groups_count', ctypes.c_ubyte),
|
||||
('arch', _cs_arch),
|
||||
)
|
||||
|
||||
class _cs_insn(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('id', ctypes.c_uint),
|
||||
('address', ctypes.c_uint64),
|
||||
('size', ctypes.c_uint16),
|
||||
('bytes', ctypes.c_ubyte * 16),
|
||||
('mnemonic', ctypes.c_char * 32),
|
||||
('op_str', ctypes.c_char * 160),
|
||||
('detail', ctypes.POINTER(_cs_detail)),
|
||||
)
|
||||
|
||||
# callback for SKIPDATA option
|
||||
CS_SKIPDATA_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p)
|
||||
|
||||
class _cs_opt_skipdata(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('mnemonic', ctypes.c_char_p),
|
||||
('callback', CS_SKIPDATA_CALLBACK),
|
||||
('user_data', ctypes.c_void_p),
|
||||
)
|
||||
|
||||
# setup all the function prototype
|
||||
def _setup_prototype(lib, fname, restype, *argtypes):
|
||||
getattr(lib, fname).restype = restype
|
||||
getattr(lib, fname).argtypes = argtypes
|
||||
|
||||
_setup_prototype(_cs, "cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t))
|
||||
_setup_prototype(_cs, "cs_disasm_ex", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \
|
||||
ctypes.c_uint64, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn)))
|
||||
_setup_prototype(_cs, "cs_free", None, ctypes.c_void_p, ctypes.c_size_t)
|
||||
_setup_prototype(_cs, "cs_close", ctypes.c_int, ctypes.POINTER(ctypes.c_size_t))
|
||||
_setup_prototype(_cs, "cs_reg_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint)
|
||||
_setup_prototype(_cs, "cs_insn_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint)
|
||||
_setup_prototype(_cs, "cs_op_count", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint)
|
||||
_setup_prototype(_cs, "cs_op_index", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint, ctypes.c_uint)
|
||||
_setup_prototype(_cs, "cs_errno", ctypes.c_int, ctypes.c_size_t)
|
||||
_setup_prototype(_cs, "cs_option", ctypes.c_int, ctypes.c_size_t, ctypes.c_int, ctypes.c_void_p)
|
||||
_setup_prototype(_cs, "cs_version", ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
|
||||
_setup_prototype(_cs, "cs_support", ctypes.c_bool, ctypes.c_int)
|
||||
_setup_prototype(_cs, "cs_strerror", ctypes.c_char_p, ctypes.c_int)
|
||||
|
||||
|
||||
# access to error code via @errno of CsError
|
||||
class CsError(Exception):
|
||||
def __init__(self, errno):
|
||||
self.errno = errno
|
||||
|
||||
def __str__(self):
|
||||
return _cs.cs_strerror(self.errno)
|
||||
|
||||
|
||||
# return the core's version
|
||||
def cs_version():
|
||||
major = ctypes.c_int()
|
||||
minor = ctypes.c_int()
|
||||
combined = _cs.cs_version(ctypes.byref(major), ctypes.byref(minor))
|
||||
return (major.value, minor.value, combined)
|
||||
|
||||
|
||||
# return the binding's version
|
||||
def version_bind():
|
||||
return (CS_API_MAJOR, CS_API_MINOR, (CS_API_MAJOR << 8) + CS_API_MINOR)
|
||||
|
||||
|
||||
def cs_support(query):
|
||||
return _cs.cs_support(query)
|
||||
|
||||
|
||||
# dummy class resembling Cs class, just for cs_disasm_quick()
|
||||
# this class only need to be referenced to via 2 fields: @csh & @arch
|
||||
class _dummy_cs(object):
|
||||
def __init__(self, csh, arch):
|
||||
self.csh = csh
|
||||
self.arch = arch
|
||||
|
||||
|
||||
# Quick & dirty Python function to disasm raw binary code
|
||||
# This function return CsInsn objects
|
||||
# NOTE: you might want to use more efficient Cs class & its methods.
|
||||
def cs_disasm_quick(arch, mode, code, offset, count = 0):
|
||||
# verify version compatibility with the core before doing anything
|
||||
(major, minor, _combined) = cs_version()
|
||||
if major != CS_API_MAJOR or minor != CS_API_MINOR:
|
||||
# our binding version is different from the core's API version
|
||||
raise CsError(CS_ERR_VERSION)
|
||||
|
||||
csh = ctypes.c_size_t()
|
||||
status = _cs.cs_open(arch, mode, ctypes.byref(csh))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
all_insn = ctypes.POINTER(_cs_insn)()
|
||||
res = _cs.cs_disasm_ex(csh, code, len(code), offset, count, ctypes.byref(all_insn))
|
||||
if res > 0:
|
||||
for i in xrange(res):
|
||||
yield CsInsn(_dummy_cs(csh, arch), all_insn[i])
|
||||
|
||||
_cs.cs_free(all_insn, res)
|
||||
else:
|
||||
status = _cs.cs_errno(csh)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
return
|
||||
yield
|
||||
|
||||
status = _cs.cs_close(ctypes.byref(csh))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
|
||||
# Another quick, but lighter function to disasm raw binary code.
|
||||
# This function is faster than cs_disasm_quick() around 20% because
|
||||
# cs_disasm_lite() only return tuples of (address, size, mnemonic, op_str),
|
||||
# rather than CsInsn objects.
|
||||
# NOTE: you might want to use more efficient Cs class & its methods.
|
||||
def cs_disasm_lite(arch, mode, code, offset, count = 0):
|
||||
# verify version compatibility with the core before doing anything
|
||||
(major, minor, _combined) = cs_version()
|
||||
if major != CS_API_MAJOR or minor != CS_API_MINOR:
|
||||
# our binding version is different from the core's API version
|
||||
raise CsError(CS_ERR_VERSION)
|
||||
|
||||
if cs_support(CS_SUPPORT_DIET):
|
||||
# Diet engine cannot provide @mnemonic & @op_str
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
csh = ctypes.c_size_t()
|
||||
status = _cs.cs_open(arch, mode, ctypes.byref(csh))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
all_insn = ctypes.POINTER(_cs_insn)()
|
||||
res = _cs.cs_disasm_ex(csh, code, len(code), offset, count, ctypes.byref(all_insn))
|
||||
if res > 0:
|
||||
for i in xrange(res):
|
||||
insn = all_insn[i]
|
||||
yield (insn.address, insn.size, insn.mnemonic, insn.op_str)
|
||||
|
||||
_cs.cs_free(all_insn, res)
|
||||
else:
|
||||
status = _cs.cs_errno(csh)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
return
|
||||
yield
|
||||
|
||||
status = _cs.cs_close(ctypes.byref(csh))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
|
||||
# Python-style class to disasm code
|
||||
class CsInsn(object):
|
||||
def __init__(self, cs, all_info):
|
||||
self._raw = all_info
|
||||
self._cs = cs
|
||||
|
||||
# return instruction's ID.
|
||||
@property
|
||||
def id(self):
|
||||
return self._raw.id
|
||||
|
||||
# return instruction's address.
|
||||
@property
|
||||
def address(self):
|
||||
return self._raw.address
|
||||
|
||||
# return instruction's size.
|
||||
@property
|
||||
def size(self):
|
||||
return self._raw.size
|
||||
|
||||
# return instruction's machine bytes (which should have @size bytes).
|
||||
@property
|
||||
def bytes(self):
|
||||
return bytearray(self._raw.bytes)[:self._raw.size]
|
||||
|
||||
# return instruction's mnemonic.
|
||||
@property
|
||||
def mnemonic(self):
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide @mnemonic.
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return self._raw.mnemonic
|
||||
|
||||
# return instruction's operands (in string).
|
||||
@property
|
||||
def op_str(self):
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide @op_str.
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return self._raw.op_str
|
||||
|
||||
# return list of all implicit registers being read.
|
||||
@property
|
||||
def regs_read(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide @regs_read.
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
if self._cs._detail:
|
||||
detail = self._raw.detail.contents
|
||||
return detail.regs_read[:detail.regs_read_count]
|
||||
|
||||
raise CsError(CS_ERR_DETAIL)
|
||||
|
||||
# return list of all implicit registers being modified
|
||||
@property
|
||||
def regs_write(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide @regs_write
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
if self._cs._detail:
|
||||
detail = self._raw.detail.contents
|
||||
return detail.regs_write[:detail.regs_write_count]
|
||||
|
||||
raise CsError(CS_ERR_DETAIL)
|
||||
|
||||
# return list of semantic groups this instruction belongs to.
|
||||
@property
|
||||
def groups(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide @groups
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
if self._cs._detail:
|
||||
detail = self._raw.detail.contents
|
||||
return detail.groups[:detail.groups_count]
|
||||
|
||||
raise CsError(CS_ERR_DETAIL)
|
||||
|
||||
def __gen_detail(self):
|
||||
arch = self._cs.arch
|
||||
detail = self._raw.detail.contents
|
||||
if arch == CS_ARCH_ARM:
|
||||
(self.cc, self.update_flags, self.writeback, self.operands) = \
|
||||
arm.get_arch_info(detail.arch.arm)
|
||||
elif arch == CS_ARCH_ARM64:
|
||||
(self.cc, self.update_flags, self.writeback, self.operands) = \
|
||||
arm64.get_arch_info(detail.arch.arm64)
|
||||
elif arch == CS_ARCH_X86:
|
||||
(self.prefix, self.segment, self.opcode, self.op_size, self.addr_size, \
|
||||
self.disp_size, self.imm_size, self.modrm, self.sib, self.disp, \
|
||||
self.sib_index, self.sib_scale, self.sib_base, self.operands) = x86.get_arch_info(detail.arch.x86)
|
||||
elif arch == CS_ARCH_MIPS:
|
||||
self.operands = mips.get_arch_info(detail.arch.mips)
|
||||
elif arch == CS_ARCH_PPC:
|
||||
(self.bc, self.bh, self.update_cr0, self.operands) = \
|
||||
ppc.get_arch_info(detail.arch.ppc)
|
||||
elif arch == CS_ARCH_SPARC:
|
||||
(self.cc, self.hint, self.operands) = sparc.get_arch_info(detail.arch.sparc)
|
||||
elif arch == CS_ARCH_SYSZ:
|
||||
(self.cc, self.operands) = systemz.get_arch_info(detail.arch.sysz)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if not self._cs._detail:
|
||||
raise CsError(CS_ERR_DETAIL)
|
||||
|
||||
attr = object.__getattribute__
|
||||
if not attr(self, '_cs')._detail:
|
||||
return None
|
||||
_dict = attr(self, '__dict__')
|
||||
if 'operands' not in _dict:
|
||||
self.__gen_detail()
|
||||
if name not in _dict:
|
||||
return None
|
||||
return _dict[name]
|
||||
|
||||
# get the last error code
|
||||
def errno(self):
|
||||
return _cs.cs_errno(self._cs.csh)
|
||||
|
||||
# get the register name, given the register ID
|
||||
def reg_name(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide register name
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return _cs.cs_reg_name(self._cs.csh, reg_id)
|
||||
|
||||
# get the instruction string
|
||||
def insn_name(self):
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide instruction name
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return _cs.cs_insn_name(self._cs.csh, self.id)
|
||||
|
||||
# verify if this insn belong to group with id as @group_id
|
||||
def group(self, group_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide group information
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return group_id in self.groups
|
||||
|
||||
# verify if this instruction implicitly read register @reg_id
|
||||
def reg_read(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide regs_read information
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return reg_id in self.regs_read
|
||||
|
||||
# verify if this instruction implicitly modified register @reg_id
|
||||
def reg_write(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
# Diet engine cannot provide regs_write information
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
return reg_id in self.regs_write
|
||||
|
||||
# return number of operands having same operand type @op_type
|
||||
def op_count(self, op_type):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
c = 0
|
||||
for op in self.operands:
|
||||
if op.type == op_type:
|
||||
c += 1
|
||||
return c
|
||||
|
||||
# get the operand at position @position of all operands having the same type @op_type
|
||||
def op_find(self, op_type, position):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
c = 0
|
||||
for op in self.operands:
|
||||
if op.type == op_type:
|
||||
c += 1
|
||||
if c == position:
|
||||
return op
|
||||
|
||||
|
||||
class Cs(object):
|
||||
def __init__(self, arch, mode):
|
||||
# verify version compatibility with the core before doing anything
|
||||
(major, minor, _combined) = cs_version()
|
||||
if major != CS_API_MAJOR or minor != CS_API_MINOR:
|
||||
self.csh = None
|
||||
# our binding version is different from the core's API version
|
||||
raise CsError(CS_ERR_VERSION)
|
||||
|
||||
self.arch, self._mode = arch, mode
|
||||
self.csh = ctypes.c_size_t()
|
||||
status = _cs.cs_open(arch, mode, ctypes.byref(self.csh))
|
||||
if status != CS_ERR_OK:
|
||||
self.csh = None
|
||||
raise CsError(status)
|
||||
|
||||
try:
|
||||
import ccapstone
|
||||
# rewire disasm to use the faster version
|
||||
self.disasm = ccapstone.Cs(self).disasm
|
||||
except:
|
||||
pass
|
||||
|
||||
if arch == CS_ARCH_X86:
|
||||
# Intel syntax is default for X86
|
||||
self._syntax = CS_OPT_SYNTAX_INTEL
|
||||
else:
|
||||
self._syntax = None
|
||||
|
||||
self._detail = False # by default, do not produce instruction details
|
||||
self._diet = cs_support(CS_SUPPORT_DIET)
|
||||
self._x86_compact = cs_support(CS_SUPPORT_X86_REDUCE)
|
||||
|
||||
# default mnemonic for SKIPDATA
|
||||
self._skipdata_mnem = ".byte"
|
||||
self._skipdata = False
|
||||
|
||||
|
||||
# destructor to be called automatically when object is destroyed.
|
||||
def __del__(self):
|
||||
if self.csh:
|
||||
status = _cs.cs_close(ctypes.byref(self.csh))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
|
||||
#def option(self, opt_type, opt_value):
|
||||
# return _cs.cs_option(self.csh, opt_type, opt_value)
|
||||
|
||||
|
||||
# is this a diet engine?
|
||||
@property
|
||||
def diet(self):
|
||||
return self._diet
|
||||
|
||||
|
||||
# is this engine compiled with X86 compact option?
|
||||
@property
|
||||
def x86_compact(self):
|
||||
return self._x86_compact
|
||||
|
||||
|
||||
# return assembly syntax.
|
||||
@property
|
||||
def syntax(self):
|
||||
return self._syntax
|
||||
|
||||
|
||||
# setter: modify assembly syntax.
|
||||
@syntax.setter
|
||||
def syntax(self, style):
|
||||
status = _cs.cs_option(self.csh, CS_OPT_SYNTAX, style)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
# save syntax
|
||||
self._syntax = style
|
||||
|
||||
|
||||
# return current skipdata status
|
||||
@property
|
||||
def skipdata(self):
|
||||
return self._skipdata
|
||||
|
||||
|
||||
# setter: modify skipdata status
|
||||
@syntax.setter
|
||||
def skipdata(self, opt):
|
||||
if opt == False:
|
||||
status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA, CS_OPT_OFF)
|
||||
else:
|
||||
status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA, CS_OPT_ON)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
# save this option
|
||||
self._skipdata = opt
|
||||
|
||||
|
||||
# setter: modify "data" instruction's mnemonic for SKIPDATA
|
||||
@syntax.setter
|
||||
def skipdata_setup(self, opt):
|
||||
_skipdata_opt = _cs_opt_skipdata()
|
||||
_mnem, _cb, _ud = opt
|
||||
_skipdata_opt.mnemonic = _mnem
|
||||
_skipdata_opt.callback = ctypes.cast(_cb, CS_SKIPDATA_CALLBACK)
|
||||
_skipdata_opt.user_data = ctypes.cast(_ud, ctypes.c_void_p)
|
||||
status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA_SETUP, ctypes.cast(ctypes.byref(_skipdata_opt), ctypes.c_void_p))
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
self._skipdata_opt = _skipdata_opt
|
||||
|
||||
|
||||
# is detail mode enable?
|
||||
@property
|
||||
def detail(self):
|
||||
return self._detail
|
||||
|
||||
|
||||
# check to see if this engine supports a particular arch,
|
||||
# or diet mode (depending on @query).
|
||||
def support(self, query):
|
||||
return cs_support(query)
|
||||
|
||||
|
||||
# modify detail mode.
|
||||
@detail.setter
|
||||
def detail(self, opt): # opt is boolean type, so must be either 'True' or 'False'
|
||||
if opt == False:
|
||||
status = _cs.cs_option(self.csh, CS_OPT_DETAIL, CS_OPT_OFF)
|
||||
else:
|
||||
status = _cs.cs_option(self.csh, CS_OPT_DETAIL, CS_OPT_ON)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
# save detail
|
||||
self._detail = opt
|
||||
|
||||
|
||||
# return disassembly mode of this engine.
|
||||
@property
|
||||
def mode(self):
|
||||
return self._mode
|
||||
|
||||
|
||||
# modify engine's mode at run-time.
|
||||
@mode.setter
|
||||
def mode(self, opt): # opt is new disasm mode, of int type
|
||||
status = _cs.cs_option(self.csh, CS_OPT_MODE, opt)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
# save mode
|
||||
self._mode = opt
|
||||
|
||||
|
||||
# Disassemble binary & return disassembled instructions in CsInsn objects
|
||||
def disasm(self, code, offset, count = 0):
|
||||
all_insn = ctypes.POINTER(_cs_insn)()
|
||||
res = _cs.cs_disasm_ex(self.csh, code, len(code), offset, count, ctypes.byref(all_insn))
|
||||
if res > 0:
|
||||
for i in xrange(res):
|
||||
yield CsInsn(self, all_insn[i])
|
||||
_cs.cs_free(all_insn, res)
|
||||
else:
|
||||
status = _cs.cs_errno(self.csh)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
return
|
||||
yield
|
||||
|
||||
|
||||
# Light function to disassemble binary. This is about 20% faster than disasm() because
|
||||
# unlike disasm(), disasm_lite() only return tuples of (address, size, mnemonic, op_str),
|
||||
# rather than CsInsn objects.
|
||||
def disasm_lite(self, code, offset, count = 0):
|
||||
if self._diet:
|
||||
# Diet engine cannot provide @mnemonic & @op_str
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
all_insn = ctypes.POINTER(_cs_insn)()
|
||||
res = _cs.cs_disasm_ex(self.csh, code, len(code), offset, count, ctypes.byref(all_insn))
|
||||
if res > 0:
|
||||
for i in xrange(res):
|
||||
insn = all_insn[i]
|
||||
yield (insn.address, insn.size, insn.mnemonic, insn.op_str)
|
||||
_cs.cs_free(all_insn, res)
|
||||
else:
|
||||
status = _cs.cs_errno(self.csh)
|
||||
if status != CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
return
|
||||
yield
|
||||
|
||||
|
||||
# print out debugging info
|
||||
def debug():
|
||||
# is Cython there?
|
||||
try:
|
||||
import ccapstone
|
||||
return ccapstone.debug()
|
||||
except:
|
||||
# no Cython, fallback to Python code below
|
||||
pass
|
||||
|
||||
if cs_support(CS_SUPPORT_DIET):
|
||||
diet = "diet"
|
||||
else:
|
||||
diet = "standard"
|
||||
|
||||
archs = { "arm": CS_ARCH_ARM, "arm64": CS_ARCH_ARM64, \
|
||||
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, \
|
||||
"sysz": CS_ARCH_SYSZ }
|
||||
|
||||
all_archs = ""
|
||||
keys = archs.keys()
|
||||
keys.sort()
|
||||
for k in keys:
|
||||
if cs_support(archs[k]):
|
||||
all_archs += "-%s" %k
|
||||
|
||||
if cs_support(CS_ARCH_X86):
|
||||
all_archs += "-x86"
|
||||
if cs_support(CS_SUPPORT_X86_REDUCE):
|
||||
all_archs += "_compact"
|
||||
|
||||
(major, minor, _combined) = cs_version()
|
||||
|
||||
return "python-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, CS_API_MAJOR, CS_API_MINOR)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# Capstone Python bindings, by Nguyen Anh Quynnh <aquynh@gmail.com>
|
||||
|
||||
import ctypes, copy
|
||||
from .xcore_const import *
|
||||
|
||||
# define the API
|
||||
class XcoreOpMem(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('base', ctypes.c_uint8),
|
||||
('index', ctypes.c_uint8),
|
||||
('disp', ctypes.c_int32),
|
||||
('direct', ctypes.c_int),
|
||||
)
|
||||
|
||||
class XcoreOpValue(ctypes.Union):
|
||||
_fields_ = (
|
||||
('reg', ctypes.c_uint),
|
||||
('imm', ctypes.c_int64),
|
||||
('mem', XcoreOpMem),
|
||||
)
|
||||
|
||||
class XcoreOp(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('type', ctypes.c_uint),
|
||||
('value', XcoreOpValue),
|
||||
)
|
||||
|
||||
@property
|
||||
def imm(self):
|
||||
return self.value.imm
|
||||
|
||||
@property
|
||||
def reg(self):
|
||||
return self.value.reg
|
||||
|
||||
@property
|
||||
def mem(self):
|
||||
return self.value.mem
|
||||
|
||||
|
||||
class CsXcore(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('op_count', ctypes.c_uint8),
|
||||
('operands', XcoreOp * 8),
|
||||
)
|
||||
|
||||
def get_arch_info(a):
|
||||
return (copy.deepcopy(a.operands[:a.op_count]))
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [xcore_const.py]
|
||||
|
||||
# Operand type for instruction's operands
|
||||
|
||||
XCORE_OP_INVALID = 0
|
||||
XCORE_OP_REG = 1
|
||||
XCORE_OP_IMM = 2
|
||||
XCORE_OP_MEM = 3
|
||||
|
||||
# XCore registers
|
||||
|
||||
XCORE_REG_INVALID = 0
|
||||
XCORE_REG_CP = 1
|
||||
XCORE_REG_DP = 2
|
||||
XCORE_REG_LR = 3
|
||||
XCORE_REG_SP = 4
|
||||
XCORE_REG_R0 = 5
|
||||
XCORE_REG_R1 = 6
|
||||
XCORE_REG_R2 = 7
|
||||
XCORE_REG_R3 = 8
|
||||
XCORE_REG_R4 = 9
|
||||
XCORE_REG_R5 = 10
|
||||
XCORE_REG_R6 = 11
|
||||
XCORE_REG_R7 = 12
|
||||
XCORE_REG_R8 = 13
|
||||
XCORE_REG_R9 = 14
|
||||
XCORE_REG_R10 = 15
|
||||
XCORE_REG_R11 = 16
|
||||
XCORE_REG_MAX = 17
|
||||
|
||||
# XCore instruction
|
||||
|
||||
XCORE_INS_INVALID = 0
|
||||
XCORE_INS_ADD = 1
|
||||
XCORE_INS_ANDNOT = 2
|
||||
XCORE_INS_AND = 3
|
||||
XCORE_INS_ASHR = 4
|
||||
XCORE_INS_BAU = 5
|
||||
XCORE_INS_BITREV = 6
|
||||
XCORE_INS_BLA = 7
|
||||
XCORE_INS_BLAT = 8
|
||||
XCORE_INS_BL = 9
|
||||
XCORE_INS_BF = 10
|
||||
XCORE_INS_BT = 11
|
||||
XCORE_INS_BU = 12
|
||||
XCORE_INS_BRU = 13
|
||||
XCORE_INS_BYTEREV = 14
|
||||
XCORE_INS_CHKCT = 15
|
||||
XCORE_INS_CLRE = 16
|
||||
XCORE_INS_CLRPT = 17
|
||||
XCORE_INS_CLRSR = 18
|
||||
XCORE_INS_CLZ = 19
|
||||
XCORE_INS_CRC8 = 20
|
||||
XCORE_INS_CRC32 = 21
|
||||
XCORE_INS_DCALL = 22
|
||||
XCORE_INS_DENTSP = 23
|
||||
XCORE_INS_DGETREG = 24
|
||||
XCORE_INS_DIVS = 25
|
||||
XCORE_INS_DIVU = 26
|
||||
XCORE_INS_DRESTSP = 27
|
||||
XCORE_INS_DRET = 28
|
||||
XCORE_INS_ECALLF = 29
|
||||
XCORE_INS_ECALLT = 30
|
||||
XCORE_INS_EDU = 31
|
||||
XCORE_INS_EEF = 32
|
||||
XCORE_INS_EET = 33
|
||||
XCORE_INS_EEU = 34
|
||||
XCORE_INS_ENDIN = 35
|
||||
XCORE_INS_ENTSP = 36
|
||||
XCORE_INS_EQ = 37
|
||||
XCORE_INS_EXTDP = 38
|
||||
XCORE_INS_EXTSP = 39
|
||||
XCORE_INS_FREER = 40
|
||||
XCORE_INS_FREET = 41
|
||||
XCORE_INS_GETD = 42
|
||||
XCORE_INS_GET = 43
|
||||
XCORE_INS_GETN = 44
|
||||
XCORE_INS_GETR = 45
|
||||
XCORE_INS_GETSR = 46
|
||||
XCORE_INS_GETST = 47
|
||||
XCORE_INS_GETTS = 48
|
||||
XCORE_INS_INCT = 49
|
||||
XCORE_INS_INIT = 50
|
||||
XCORE_INS_INPW = 51
|
||||
XCORE_INS_INSHR = 52
|
||||
XCORE_INS_INT = 53
|
||||
XCORE_INS_IN = 54
|
||||
XCORE_INS_KCALL = 55
|
||||
XCORE_INS_KENTSP = 56
|
||||
XCORE_INS_KRESTSP = 57
|
||||
XCORE_INS_KRET = 58
|
||||
XCORE_INS_LADD = 59
|
||||
XCORE_INS_LD16S = 60
|
||||
XCORE_INS_LD8U = 61
|
||||
XCORE_INS_LDA16 = 62
|
||||
XCORE_INS_LDAP = 63
|
||||
XCORE_INS_LDAW = 64
|
||||
XCORE_INS_LDC = 65
|
||||
XCORE_INS_LDW = 66
|
||||
XCORE_INS_LDIVU = 67
|
||||
XCORE_INS_LMUL = 68
|
||||
XCORE_INS_LSS = 69
|
||||
XCORE_INS_LSUB = 70
|
||||
XCORE_INS_LSU = 71
|
||||
XCORE_INS_MACCS = 72
|
||||
XCORE_INS_MACCU = 73
|
||||
XCORE_INS_MJOIN = 74
|
||||
XCORE_INS_MKMSK = 75
|
||||
XCORE_INS_MSYNC = 76
|
||||
XCORE_INS_MUL = 77
|
||||
XCORE_INS_NEG = 78
|
||||
XCORE_INS_NOT = 79
|
||||
XCORE_INS_OR = 80
|
||||
XCORE_INS_OUTCT = 81
|
||||
XCORE_INS_OUTPW = 82
|
||||
XCORE_INS_OUTSHR = 83
|
||||
XCORE_INS_OUTT = 84
|
||||
XCORE_INS_OUT = 85
|
||||
XCORE_INS_PEEK = 86
|
||||
XCORE_INS_REMS = 87
|
||||
XCORE_INS_REMU = 88
|
||||
XCORE_INS_RETSP = 89
|
||||
XCORE_INS_SETCLK = 90
|
||||
XCORE_INS_SET = 91
|
||||
XCORE_INS_SETC = 92
|
||||
XCORE_INS_SETD = 93
|
||||
XCORE_INS_SETEV = 94
|
||||
XCORE_INS_SETN = 95
|
||||
XCORE_INS_SETPSC = 96
|
||||
XCORE_INS_SETPT = 97
|
||||
XCORE_INS_SETRDY = 98
|
||||
XCORE_INS_SETSR = 99
|
||||
XCORE_INS_SETTW = 100
|
||||
XCORE_INS_SETV = 101
|
||||
XCORE_INS_SEXT = 102
|
||||
XCORE_INS_SHL = 103
|
||||
XCORE_INS_SHR = 104
|
||||
XCORE_INS_SSYNC = 105
|
||||
XCORE_INS_ST16 = 106
|
||||
XCORE_INS_ST8 = 107
|
||||
XCORE_INS_STW = 108
|
||||
XCORE_INS_SUB = 109
|
||||
XCORE_INS_SYNCR = 110
|
||||
XCORE_INS_TESTCT = 111
|
||||
XCORE_INS_TESTLCL = 112
|
||||
XCORE_INS_TESTWCT = 113
|
||||
XCORE_INS_TSETMR = 114
|
||||
XCORE_INS_START = 115
|
||||
XCORE_INS_WAITEF = 116
|
||||
XCORE_INS_WAITET = 117
|
||||
XCORE_INS_WAITEU = 118
|
||||
XCORE_INS_XOR = 119
|
||||
XCORE_INS_ZEXT = 120
|
||||
XCORE_INS_MAX = 121
|
||||
|
||||
# Group of XCore instructions
|
||||
|
||||
XCORE_GRP_INVALID = 0
|
||||
XCORE_GRP_JUMP = 1
|
||||
XCORE_GRP_MAX = 2
|
|
@ -19,6 +19,8 @@ ext_modules = [ Extension("capstone.capstone", ["pyx/capstone.pyx"], extra_compi
|
|||
Extension("capstone.ppc_const", ["pyx/ppc_const.pyx"], extra_compile_args=compile_args),
|
||||
Extension("capstone.x86", ["pyx/x86.pyx"], extra_compile_args=compile_args),
|
||||
Extension("capstone.x86_const", ["pyx/x86_const.pyx"], extra_compile_args=compile_args)
|
||||
Extension("capstone.xcore", ["pyx/xcore.pyx"], extra_compile_args=compile_args),
|
||||
Extension("capstone.xcore_const", ["pyx/xcore_const.pyx"], extra_compile_args=compile_args)
|
||||
]
|
||||
|
||||
# clean package directory first
|
||||
|
|
|
@ -25,6 +25,7 @@ PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4
|
|||
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"
|
||||
SYSZ_CODE = b"\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"
|
||||
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"
|
||||
|
||||
all_tests = (
|
||||
(CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", 0),
|
||||
|
@ -43,6 +44,7 @@ all_tests = (
|
|||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", 0),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", 0),
|
||||
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", 0),
|
||||
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", 0),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ PPC_CODE = b"\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4
|
|||
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"
|
||||
SYSZ_CODE = b"\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78"
|
||||
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"
|
||||
|
||||
all_tests = (
|
||||
(CS_ARCH_X86, CS_MODE_16, X86_CODE16, "X86 16bit (Intel syntax)", 0),
|
||||
|
@ -36,6 +37,7 @@ all_tests = (
|
|||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, SPARC_CODE, "Sparc", 0),
|
||||
(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN + CS_MODE_V9, SPARCV9_CODE, "SparcV9", 0),
|
||||
(CS_ARCH_SYSZ, 0, SYSZ_CODE, "SystemZ", 0),
|
||||
(CS_ARCH_XCORE, 0, XCORE_CODE, "XCore", 0),
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue