3 from platform
import system
4 _python2 = sys.version_info[0] < 3
40 'CS_MODE_LITTLE_ENDIAN',
71 'CS_MODE_M680X_CPU12',
72 'CS_MODE_M680X_HCS08',
75 'CS_OPT_SYNTAX_DEFAULT',
76 'CS_OPT_SYNTAX_INTEL',
78 'CS_OPT_SYNTAX_NOREGNAME',
102 'CS_SUPPORT_X86_REDUCE',
103 'CS_SKIPDATA_CALLBACK',
135 CS_VERSION_MAJOR = CS_API_MAJOR
136 CS_VERSION_MINOR = CS_API_MINOR
139 __version__ =
"%u.%u.%u" %(CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA)
151 CS_ARCH_TMS320C64X = 9
158 CS_MODE_LITTLE_ENDIAN = 0
160 CS_MODE_16 = (1 << 1)
161 CS_MODE_32 = (1 << 2)
162 CS_MODE_64 = (1 << 3)
163 CS_MODE_THUMB = (1 << 4)
164 CS_MODE_MCLASS = (1 << 5)
165 CS_MODE_V8 = (1 << 6)
166 CS_MODE_MICRO = (1 << 4)
167 CS_MODE_MIPS3 = (1 << 5)
168 CS_MODE_MIPS32R6 = (1 << 6)
169 CS_MODE_MIPS2 = (1 << 7)
170 CS_MODE_V9 = (1 << 4)
171 CS_MODE_QPX = (1 << 4)
172 CS_MODE_M68K_000 = (1 << 1)
173 CS_MODE_M68K_010 = (1 << 2)
174 CS_MODE_M68K_020 = (1 << 3)
175 CS_MODE_M68K_030 = (1 << 4)
176 CS_MODE_M68K_040 = (1 << 5)
177 CS_MODE_M68K_060 = (1 << 6)
178 CS_MODE_BIG_ENDIAN = (1 << 31)
179 CS_MODE_MIPS32 = CS_MODE_32
180 CS_MODE_MIPS64 = CS_MODE_64
181 CS_MODE_M680X_6301 = (1 << 1)
182 CS_MODE_M680X_6309 = (1 << 2)
183 CS_MODE_M680X_6800 = (1 << 3)
184 CS_MODE_M680X_6801 = (1 << 4)
185 CS_MODE_M680X_6805 = (1 << 5)
186 CS_MODE_M680X_6808 = (1 << 6)
187 CS_MODE_M680X_6809 = (1 << 7)
188 CS_MODE_M680X_6811 = (1 << 8)
189 CS_MODE_M680X_CPU12 = (1 << 9)
190 CS_MODE_M680X_HCS08 = (1 << 10)
198 CS_OPT_SKIPDATA_SETUP = 6
224 CS_AC_READ = (1 << 0)
225 CS_AC_WRITE = (1 << 1)
228 CS_OPT_SYNTAX_DEFAULT = 0
229 CS_OPT_SYNTAX_INTEL = 1
230 CS_OPT_SYNTAX_ATT = 2
231 CS_OPT_SYNTAX_NOREGNAME = 3
232 CS_OPT_SYNTAX_MASM = 4
248 CS_ERR_X86_INTEL = 13
252 CS_SUPPORT_DIET = CS_ARCH_ALL + 1
253 CS_SUPPORT_X86_REDUCE = CS_ARCH_ALL+2
256 CS_AC = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_AC_')}
257 CS_ARCH = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_ARCH_')}
258 CS_ERR = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_ERR_')}
259 CS_GRP = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_GRP_')}
260 CS_MODE = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_MODE_')}
261 CS_OP = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_OP_')}
262 CS_OPT = {v:k
for k,v
in locals().items()
if k.startswith(
'CS_OPT_')}
264 import ctypes, ctypes.util
265 from os.path
import split, join, dirname
266 import distutils.sysconfig
270 if not hasattr(sys.modules[__name__],
'__file__'):
271 __file__ = inspect.getfile(inspect.currentframe())
273 if sys.platform ==
'darwin':
274 _lib =
"libcapstone.dylib"
275 elif sys.platform
in (
'win32',
'cygwin'):
276 _lib =
"capstone.dll"
278 _lib =
"libcapstone.so"
283 lib_file = join(path, _lib)
284 if os.path.exists(lib_file):
285 return ctypes.cdll.LoadLibrary(lib_file)
288 if lib_file.endswith(
'.so'):
289 if os.path.exists(lib_file +
'.4'):
290 return ctypes.cdll.LoadLibrary(lib_file +
'.4')
303 _path_list = [os.getenv(
'LIBCAPSTONE_PATH',
None),
304 pkg_resources.resource_filename(__name__,
'lib'),
305 join(split(__file__)[0],
'lib'),
307 distutils.sysconfig.get_python_lib(),
308 "/usr/local/lib/" if sys.platform ==
'darwin' else '/usr/lib64']
310 for _path
in _path_list:
311 if _path
is None:
continue
313 if _cs
is not None:
break
315 raise ImportError(
"ERROR: fail to load the dynamic library.")
321 """Returns a new ctypes object which is a bitwise copy of an existing one"""
323 ctypes.memmove(ctypes.byref(dst), ctypes.byref(src), ctypes.sizeof(
type(src)))
330 from .
import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm
350 (
'regs_read', ctypes.c_uint16 * 12),
351 (
'regs_read_count', ctypes.c_ubyte),
352 (
'regs_write', ctypes.c_uint16 * 20),
353 (
'regs_write_count', ctypes.c_ubyte),
354 (
'groups', ctypes.c_ubyte * 8),
355 (
'groups_count', ctypes.c_ubyte),
361 (
'id', ctypes.c_uint),
362 (
'address', ctypes.c_uint64),
363 (
'size', ctypes.c_uint16),
364 (
'bytes', ctypes.c_ubyte * 16),
365 (
'mnemonic', ctypes.c_char * 32),
366 (
'op_str', ctypes.c_char * 160),
367 (
'detail', ctypes.POINTER(_cs_detail)),
371 CS_SKIPDATA_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p)
375 (
'mnemonic', ctypes.c_char_p),
376 (
'callback', CS_SKIPDATA_CALLBACK),
377 (
'user_data', ctypes.c_void_p),
382 (
'id', ctypes.c_uint),
383 (
'mnemonic', ctypes.c_char_p),
388 getattr(lib, fname).restype = restype
389 getattr(lib, fname).argtypes = argtypes
391 _setup_prototype(_cs,
"cs_open", ctypes.c_int, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_size_t))
392 _setup_prototype(_cs,
"cs_disasm", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, \
393 ctypes.c_uint64, ctypes.c_size_t, ctypes.POINTER(ctypes.POINTER(_cs_insn)))
395 _setup_prototype(_cs,
"cs_close", ctypes.c_int, ctypes.POINTER(ctypes.c_size_t))
396 _setup_prototype(_cs,
"cs_reg_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint)
397 _setup_prototype(_cs,
"cs_insn_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint)
398 _setup_prototype(_cs,
"cs_group_name", ctypes.c_char_p, ctypes.c_size_t, ctypes.c_uint)
399 _setup_prototype(_cs,
"cs_op_count", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint)
400 _setup_prototype(_cs,
"cs_op_index", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.c_uint, ctypes.c_uint)
402 _setup_prototype(_cs,
"cs_option", ctypes.c_int, ctypes.c_size_t, ctypes.c_int, ctypes.c_void_p)
403 _setup_prototype(_cs,
"cs_version", ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
406 _setup_prototype(_cs,
"cs_regs_access", ctypes.c_int, ctypes.c_size_t, ctypes.POINTER(_cs_insn), ctypes.POINTER(ctypes.c_uint16*64), ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_uint16*64), ctypes.POINTER(ctypes.c_uint8))
416 return _cs.cs_strerror(self.
errnoerrno)
425 major = ctypes.c_int()
426 minor = ctypes.c_int()
427 combined = _cs.cs_version(ctypes.byref(major), ctypes.byref(minor))
428 return (major.value, minor.value, combined)
433 return (CS_API_MAJOR, CS_API_MINOR, (CS_API_MAJOR << 8) + CS_API_MINOR)
437 return _cs.cs_support(query)
455 if major != CS_API_MAJOR
or minor != CS_API_MINOR:
459 csh = ctypes.c_size_t()
460 status = _cs.cs_open(arch, mode, ctypes.byref(csh))
461 if status != CS_ERR_OK:
464 all_insn = ctypes.POINTER(_cs_insn)()
465 res = _cs.cs_disasm(csh, code,
len(code), offset, count, ctypes.byref(all_insn))
471 _cs.cs_free(all_insn, res)
473 status = _cs.cs_errno(csh)
474 if status != CS_ERR_OK:
479 status = _cs.cs_close(ctypes.byref(csh))
480 if status != CS_ERR_OK:
492 if major != CS_API_MAJOR
or minor != CS_API_MINOR:
500 csh = ctypes.c_size_t()
501 status = _cs.cs_open(arch, mode, ctypes.byref(csh))
502 if status != CS_ERR_OK:
505 all_insn = ctypes.POINTER(_cs_insn)()
506 res = _cs.cs_disasm(csh, code,
len(code), offset, count, ctypes.byref(all_insn))
511 yield (insn.address, insn.size, insn.mnemonic.decode(
'ascii'), insn.op_str.decode(
'ascii'))
513 _cs.cs_free(all_insn, res)
515 status = _cs.cs_errno(csh)
516 if status != CS_ERR_OK:
521 status = _cs.cs_close(ctypes.byref(csh))
522 if status != CS_ERR_OK:
526 return default
if name
is None else name.decode(
'ascii')
534 if self.
_cs_cs._detail
and self.
_raw_raw.id != 0:
536 self.
_raw_raw.detail = ctypes.pointer(all_info.detail._type_())
537 ctypes.memmove(ctypes.byref(self.
_raw_raw.detail[0]), ctypes.byref(all_info.detail[0]), ctypes.sizeof(
type(all_info.detail[0])))
545 return self.
_raw_raw.id
550 return self.
_raw_raw.address
555 return self.
_raw_raw.size
560 return bytearray(self.
_raw_raw.bytes)[:self.
_raw_raw.size]
565 if self.
_cs_cs._diet:
569 return self.
_raw_raw.mnemonic.decode(
'ascii')
574 if self.
_cs_cs._diet:
578 return self.
_raw_raw.op_str.decode(
'ascii')
583 if self.
_raw_raw.id == 0:
586 if self.
_cs_cs._diet:
590 if self.
_cs_cs._detail:
591 return self.
_raw_raw.detail.contents.regs_read[:self.
_raw_raw.detail.contents.regs_read_count]
598 if self.
_raw_raw.id == 0:
601 if self.
_cs_cs._diet:
605 if self.
_cs_cs._detail:
606 return self.
_raw_raw.detail.contents.regs_write[:self.
_raw_raw.detail.contents.regs_write_count]
613 if self.
_raw_raw.id == 0:
616 if self.
_cs_cs._diet:
620 if self.
_cs_cs._detail:
621 return self.
_raw_raw.detail.contents.groups[:self.
_raw_raw.detail.contents.groups_count]
626 if self.
_raw_raw.id == 0:
630 arch = self.
_cs_cs.arch
631 if arch == CS_ARCH_ARM:
632 (self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.update_flags, \
633 self.writeback, self.mem_barrier, self.
operandsoperands) = arm.get_arch_info(self.
_raw_raw.detail.contents.arch.arm)
634 elif arch == CS_ARCH_ARM64:
635 (self.cc, self.update_flags, self.writeback, self.
operandsoperands) = \
636 arm64.get_arch_info(self.
_raw_raw.detail.contents.arch.arm64)
637 elif arch == CS_ARCH_X86:
638 (self.prefix, self.opcode, self.rex, self.addr_size, \
639 self.modrm, self.sib, self.disp, \
640 self.sib_index, self.sib_scale, self.sib_base, self.xop_cc, self.sse_cc, \
641 self.avx_cc, self.avx_sae, self.avx_rm, self.eflags, \
642 self.modrm_offset, self.disp_offset, self.disp_size, self.imm_offset, self.imm_size, \
643 self.
operandsoperands) = x86.get_arch_info(self.
_raw_raw.detail.contents.arch.x86)
644 elif arch == CS_ARCH_M68K:
645 (self.
operandsoperands, self.op_size) = m68k.get_arch_info(self.
_raw_raw.detail.contents.arch.m68k)
646 elif arch == CS_ARCH_MIPS:
647 self.
operandsoperands = mips.get_arch_info(self.
_raw_raw.detail.contents.arch.mips)
648 elif arch == CS_ARCH_PPC:
649 (self.bc, self.bh, self.update_cr0, self.
operandsoperands) = \
650 ppc.get_arch_info(self.
_raw_raw.detail.contents.arch.ppc)
651 elif arch == CS_ARCH_SPARC:
652 (self.cc, self.hint, self.
operandsoperands) = sparc.get_arch_info(self.
_raw_raw.detail.contents.arch.sparc)
653 elif arch == CS_ARCH_SYSZ:
654 (self.cc, self.
operandsoperands) = systemz.get_arch_info(self.
_raw_raw.detail.contents.arch.sysz)
655 elif arch == CS_ARCH_XCORE:
656 (self.
operandsoperands) = xcore.get_arch_info(self.
_raw_raw.detail.contents.arch.xcore)
657 elif arch == CS_ARCH_TMS320C64X:
658 (self.condition, self.funit, self.parallel, self.
operandsoperands) = tms320c64x.get_arch_info(self.
_raw_raw.detail.contents.arch.tms320c64x)
659 elif arch == CS_ARCH_M680X:
660 (self.flags, self.
operandsoperands) = m680x.get_arch_info(self.
_raw_raw.detail.contents.arch.m680x)
661 elif arch == CS_ARCH_EVM:
662 (self.pop, self.push, self.fee) = evm.get_arch_info(self.
_raw_raw.detail.contents.arch.evm)
666 if not self.
_cs_cs._detail:
669 attr = object.__getattribute__
670 if not attr(self,
'_cs')._detail:
671 raise AttributeError(name)
672 _dict = attr(self,
'__dict__')
673 if 'operands' not in _dict:
675 if name
not in _dict:
676 if self.
_raw_raw.id == 0:
678 raise AttributeError(name)
683 return _cs.cs_errno(self.
_cs_cs.csh)
687 if self.
_cs_cs._diet:
695 if self.
_cs_cs._diet:
699 if self.
_raw_raw.id == 0:
706 if self.
_cs_cs._diet:
715 if self.
_raw_raw.id == 0:
718 if self.
_cs_cs._diet:
722 return group_id
in self.
groupsgroups
726 if self.
_raw_raw.id == 0:
729 if self.
_cs_cs._diet:
737 if self.
_raw_raw.id == 0:
740 if self.
_cs_cs._diet:
748 if self.
_raw_raw.id == 0:
753 if op.type == op_type:
759 if self.
_raw_raw.id == 0:
764 if op.type == op_type:
772 if self.
_raw_raw.id == 0:
775 regs_read = (ctypes.c_uint16 * 64)()
776 regs_read_count = ctypes.c_uint8()
777 regs_write = (ctypes.c_uint16 * 64)()
778 regs_write_count = ctypes.c_uint8()
780 status = _cs.cs_regs_access(self.
_cs_cs.csh, self.
_raw_raw, ctypes.byref(regs_read), ctypes.byref(regs_read_count), ctypes.byref(regs_write), ctypes.byref(regs_write_count))
781 if status != CS_ERR_OK:
784 if regs_read_count.value > 0:
785 regs_read = regs_read[:regs_read_count.value]
789 if regs_write_count.value > 0:
790 regs_write = regs_write[:regs_write_count.value]
794 return (regs_read, regs_write)
802 if major != CS_API_MAJOR
or minor != CS_API_MINOR:
807 self.arch, self.
_mode_mode = arch, mode
808 self.
cshcsh = ctypes.c_size_t()
809 status = _cs.cs_open(arch, mode, ctypes.byref(self.
cshcsh))
810 if status != CS_ERR_OK:
821 if arch == CS_ARCH_X86:
846 status = _cs.cs_close(ctypes.byref(self.
cshcsh))
847 if status != CS_ERR_OK:
860 return self.
_diet_diet
878 status = _cs.cs_option(self.
cshcsh, CS_OPT_SYNTAX, style)
879 if status != CS_ERR_OK:
895 status = _cs.cs_option(self.
cshcsh, CS_OPT_SKIPDATA, CS_OPT_OFF)
897 status = _cs.cs_option(self.
cshcsh, CS_OPT_SKIPDATA, CS_OPT_ON)
898 if status != CS_ERR_OK:
910 @skipdata_setup.setter
912 _mnem, _cb, _ud = opt
915 self.
_skipdata_opt_skipdata_opt.user_data = ctypes.cast(_ud, ctypes.c_void_p)
916 status = _cs.cs_option(self.
cshcsh, CS_OPT_SKIPDATA_SETUP, ctypes.cast(ctypes.byref(self.
_skipdata_opt_skipdata_opt), ctypes.c_void_p))
917 if status != CS_ERR_OK:
929 @skipdata_mnem.setter
939 @skipdata_callback.setter
941 if not isinstance(val, tuple):
952 _mnem_opt.mnemonic = mnem.encode()
954 _mnem_opt.mnemonic = mnem
955 status = _cs.cs_option(self.
cshcsh, CS_OPT_MNEMONIC, ctypes.cast(ctypes.byref(_mnem_opt), ctypes.c_void_p))
956 if status != CS_ERR_OK:
976 status = _cs.cs_option(self.
cshcsh, CS_OPT_DETAIL, CS_OPT_OFF)
978 status = _cs.cs_option(self.
cshcsh, CS_OPT_DETAIL, CS_OPT_ON)
979 if status != CS_ERR_OK:
995 status = _cs.cs_option(self.
cshcsh, CS_OPT_UNSIGNED, CS_OPT_OFF)
997 status = _cs.cs_option(self.
cshcsh, CS_OPT_UNSIGNED, CS_OPT_ON)
998 if status != CS_ERR_OK:
1007 return self.
_mode_mode
1013 status = _cs.cs_option(self.
cshcsh, CS_OPT_MODE, opt)
1014 if status != CS_ERR_OK:
1017 self.
_mode_mode = opt
1021 return _cs.cs_errno(self.
cshcsh)
1049 all_insn = ctypes.POINTER(_cs_insn)()
1052 code = code.encode()
1056 if isinstance(code, bytearray):
1057 code = ctypes.byref(ctypes.c_char.from_buffer(code))
1058 res = _cs.cs_disasm(self.
cshcsh, code, size, offset, count, ctypes.byref(all_insn))
1061 for i
in range(res):
1062 yield CsInsn(self, all_insn[i])
1064 _cs.cs_free(all_insn, res)
1066 status = _cs.cs_errno(self.
cshcsh)
1067 if status != CS_ERR_OK:
1081 all_insn = ctypes.POINTER(_cs_insn)()
1084 if isinstance(code, bytearray):
1085 code = ctypes.byref(ctypes.c_char.from_buffer(code))
1086 res = _cs.cs_disasm(self.
cshcsh, code, size, offset, count, ctypes.byref(all_insn))
1089 for i
in range(res):
1091 yield (insn.address, insn.size, insn.mnemonic.decode(
'ascii'), insn.op_str.decode(
'ascii'))
1093 _cs.cs_free(all_insn, res)
1095 status = _cs.cs_errno(self.
cshcsh)
1096 if status != CS_ERR_OK:
1106 from .
import ccapstone
1107 return ccapstone.debug()
1117 archs = {
"arm": CS_ARCH_ARM,
"arm64": CS_ARCH_ARM64,
"m68k": CS_ARCH_M68K, \
1118 "mips": CS_ARCH_MIPS,
"ppc": CS_ARCH_PPC,
"sparc": CS_ARCH_SPARC, \
1119 "sysz": CS_ARCH_SYSZ,
'xcore': CS_ARCH_XCORE,
"tms320c64x": CS_ARCH_TMS320C64X, \
1120 "m680x": CS_ARCH_M680X,
'evm': CS_ARCH_EVM }
1124 for k
in sorted(keys):
1126 all_archs +=
"-%s" % k
1131 all_archs +=
"_reduce"
1135 return "python-%s%s-c%u.%u-b%u.%u" % (diet, all_archs, major, minor, CS_API_MAJOR, CS_API_MINOR)
def __init__(self, errno)
def group(self, group_id)
def reg_name(self, reg_id, default=None)
def reg_read(self, reg_id)
def __getattr__(self, name)
def reg_write(self, reg_id)
def insn_name(self, default=None)
def op_find(self, op_type, position)
def op_count(self, op_type)
def __init__(self, cs, all_info)
def group_name(self, group_id, default=None)
def skipdata_callback(self)
def skipdata_setup(self, opt)
def disasm_lite(self, code, offset, count=0)
def mnemonic_setup(self, id, mnem)
def reg_name(self, reg_id, default=None)
def insn_name(self, insn_id, default=None)
def __init__(self, arch, mode)
def group_name(self, group_id, default=None)
def disasm(self, code, offset, count=0)
def __init__(self, csh, arch)
int(* decode)(const ut8 *, ebc_command_t *cmd)
def _setup_prototype(lib, fname, restype, *argtypes)
def _ascii_name_or_default(name, default)
def cs_disasm_quick(arch, mode, code, offset, count=0)
def cs_disasm_lite(arch, mode, code, offset, count=0)
def copy_ctypes_list(src)
static const char hex[16]