python: update to new API cs_disasm_ex()

_v3_old
Nguyen Anh Quynh 11 years ago
parent 04c19beefe
commit 496a62b26b
  1. 70
      bindings/python/capstone/capstone.py

@ -85,7 +85,7 @@ CS_OPT_ON = 3 # Turn ON an option - this is default option for CS_O
# Capstone error type
CS_ERR_OK = 0 # No error: everything was fine
CS_ERR_MEM = 1 # Out-Of-Memory error: cs_open(), cs_disasm_dyn()
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()
@ -138,6 +138,7 @@ 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),
@ -146,15 +147,8 @@ class _cs_arch(ctypes.Union):
('x86', x86.CsX86),
)
# low-level structure for C code
class _cs_insn(ctypes.Structure):
class _cs_detail(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 * 96),
('regs_read', ctypes.c_ubyte * 12),
('regs_read_count', ctypes.c_ubyte),
('regs_write', ctypes.c_ubyte * 20),
@ -164,15 +158,26 @@ class _cs_insn(ctypes.Structure):
('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 * 96),
('detail', ctypes.POINTER(_cs_detail)),
)
# 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_dyn", ctypes.c_size_t, ctypes.c_size_t, ctypes.POINTER(ctypes.c_char), 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)
_setup_prototype(_cs, "cs_free", None, ctypes.c_void_p, ctypes.c_size_t)
_setup_prototype(_cs, "cs_close", ctypes.c_int, 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)
@ -234,12 +239,12 @@ def cs_disasm_quick(arch, mode, code, offset, count = 0):
insns = []
all_insn = ctypes.POINTER(_cs_insn)()
res = _cs.cs_disasm_dyn(csh, code, len(code), offset, count, ctypes.byref(all_insn))
res = _cs.cs_disasm_ex(csh, code, len(code), offset, count, ctypes.byref(all_insn))
if res > 0:
for i in xrange(res):
insns.append(CsInsn(_dummy_cs(csh, arch), all_insn[i]))
_cs.cs_free(all_insn)
_cs.cs_free(all_insn, res)
else:
status = _cs.cs_errno(csh)
if status != CS_ERR_OK:
@ -257,25 +262,28 @@ class CsInsn(object):
self.id = all_info.id
self.address = all_info.address
self.size = all_info.size
self.bytes = bytearray(all_info.bytes)[:self.size]
self.mnemonic = all_info.mnemonic[:] # copy string
self.op_str = all_info.op_str[:] # copy string
self.regs_read = all_info.regs_read[:all_info.regs_read_count]
self.regs_write = all_info.regs_write[:all_info.regs_write_count]
self.groups = all_info.groups[:all_info.groups_count]
self.bytes = bytearray(all_info.bytes)[:self.size]
if cs.arch == CS_ARCH_ARM:
(self.cc, self.update_flags, self.writeback, self.operands) = \
arm.get_arch_info(all_info.arch.arm)
elif cs.arch == CS_ARCH_ARM64:
(self.cc, self.update_flags, self.writeback, self.operands) = \
arm64.get_arch_info(all_info.arch.arm64)
elif cs.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(all_info.arch.x86)
elif cs.arch == CS_ARCH_MIPS:
self.operands = mips.get_arch_info(all_info.arch.mips)
if cs._detail:
detail = all_info.detail.contents
self.regs_read = detail.regs_read[:detail.regs_read_count]
self.regs_write = detail.regs_write[:detail.regs_write_count]
self.groups = detail.groups[:detail.groups_count]
if cs.arch == CS_ARCH_ARM:
(self.cc, self.update_flags, self.writeback, self.operands) = \
arm.get_arch_info(detail.arch.arm)
elif cs.arch == CS_ARCH_ARM64:
(self.cc, self.update_flags, self.writeback, self.operands) = \
arm64.get_arch_info(detail.arch.arm64)
elif cs.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 cs.arch == CS_ARCH_MIPS:
self.operands = mips.get_arch_info(detail.arch.mips)
self.cs = cs
@ -389,11 +397,11 @@ class Cs(object):
def disasm(self, code, offset, count = 0):
insns = []
all_insn = ctypes.POINTER(_cs_insn)()
res = _cs.cs_disasm_dyn(self.csh, code, len(code), offset, count, ctypes.byref(all_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):
insns.append(CsInsn(self, all_insn[i]))
_cs.cs_free(all_insn)
_cs.cs_free(all_insn, res)
else:
status = _cs.cs_errno(self.csh)
if status != CS_ERR_OK:

Loading…
Cancel
Save