diff --git a/bindings/python/pyx/ccapstone.pxd b/bindings/python/pyx/ccapstone.pxd index 5acefab6b4..e9a8acd35b 100644 --- a/bindings/python/pyx/ccapstone.pxd +++ b/bindings/python/pyx/ccapstone.pxd @@ -1,65 +1,67 @@ +# By Dang Hoang Vu , 2014 + from libcpp cimport bool from libc.stdint cimport uint8_t, uint64_t, uint16_t cdef extern from "": - ctypedef size_t csh + ctypedef size_t csh - ctypedef enum cs_mode: - pass + ctypedef enum cs_mode: + pass - ctypedef enum cs_arch: - pass + ctypedef enum cs_arch: + pass - ctypedef struct cs_detail: - pass + ctypedef struct cs_detail: + pass - ctypedef struct cs_insn: - unsigned int id - uint64_t address - uint16_t size - uint8_t bytes[16] - char mnemonic[32] - char op_str[96] - cs_detail *detail + ctypedef struct cs_insn: + unsigned int id + uint64_t address + uint16_t size + uint8_t bytes[16] + char mnemonic[32] + char op_str[96] + cs_detail *detail - ctypedef enum cs_err: - pass + ctypedef enum cs_err: + pass - ctypedef enum cs_opt_type: - pass + ctypedef enum cs_opt_type: + pass - unsigned int cs_version(int *major, int *minor) + unsigned int cs_version(int *major, int *minor) - bool cs_support(int arch) + bool cs_support(int arch) - cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) + cs_err cs_open(cs_arch arch, cs_mode mode, csh *handle) - cs_err cs_close(csh handle) + cs_err cs_close(csh handle) - cs_err cs_errno(csh handle) + cs_err cs_errno(csh handle) - size_t cs_disasm_ex(csh handle, - const uint8_t *code, size_t code_size, - uint64_t address, - size_t count, - cs_insn **insn) + size_t cs_disasm_ex(csh handle, + const uint8_t *code, size_t code_size, + uint64_t address, + size_t count, + cs_insn **insn) - cs_err cs_option(csh handle, cs_opt_type type, size_t value) + cs_err cs_option(csh handle, cs_opt_type type, size_t value) - void cs_free(cs_insn *insn, size_t count) + void cs_free(cs_insn *insn, size_t count) - const char *cs_reg_name(csh handle, unsigned int reg_id) + const char *cs_reg_name(csh handle, unsigned int reg_id) - const char *cs_insn_name(csh handle, unsigned int insn_id) + const char *cs_insn_name(csh handle, unsigned int insn_id) - bool cs_insn_group(csh handle, cs_insn *insn, unsigned int group_id) + bool cs_insn_group(csh handle, cs_insn *insn, unsigned int group_id) - bool cs_reg_read(csh handle, cs_insn *insn, unsigned int reg_id) + bool cs_reg_read(csh handle, cs_insn *insn, unsigned int reg_id) - bool cs_reg_write(csh handle, cs_insn *insn, unsigned int reg_id) + bool cs_reg_write(csh handle, cs_insn *insn, unsigned int reg_id) - int cs_op_count(csh handle, cs_insn *insn, unsigned int op_type) + int cs_op_count(csh handle, cs_insn *insn, unsigned int op_type) - int cs_op_index(csh handle, cs_insn *insn, unsigned int op_type, - unsigned int position) + int cs_op_index(csh handle, cs_insn *insn, unsigned int op_type, + unsigned int position) diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index 48a4124e5e..3aba07bc94 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -1,164 +1,167 @@ +# By Dang Hoang Vu , 2014 + cimport pyx.ccapstone as cc import capstone, ctypes from capstone import arm, x86, mips, ppc, arm64, CsError class CsDetail: - def __init__(self, arch, raw_detail = None): - if not raw_detail: - return - detail = ctypes.cast(raw_detail, ctypes.POINTER(capstone._cs_detail)).contents - - self.regs_read = detail.regs_read - self.regs_write = detail.regs_write - self.groups = detail.groups - - if arch == capstone.CS_ARCH_ARM: - (self.cc, self.update_flags, self.writeback, self.operands) = \ - arm.get_arch_info(detail.arch.arm) - elif arch == capstone.CS_ARCH_ARM64: - (self.cc, self.update_flags, self.writeback, self.operands) = \ - arm64.get_arch_info(detail.arch.arm64) - elif arch == capstone.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 == capstone.CS_ARCH_MIPS: - self.operands = mips.get_arch_info(detail.arch.mips) - elif arch == capstone.CS_ARCH_PPC: - (self.bc, self.bh, self.update_cr0, self.operands) = \ - ppc.get_arch_info(detail.arch.ppc) + def __init__(self, arch, raw_detail = None): + if not raw_detail: + return + detail = ctypes.cast(raw_detail, ctypes.POINTER(capstone._cs_detail)).contents + + self.regs_read = detail.regs_read + self.regs_write = detail.regs_write + self.groups = detail.groups + + if arch == capstone.CS_ARCH_ARM: + (self.cc, self.update_flags, self.writeback, self.operands) = \ + arm.get_arch_info(detail.arch.arm) + elif arch == capstone.CS_ARCH_ARM64: + (self.cc, self.update_flags, self.writeback, self.operands) = \ + arm64.get_arch_info(detail.arch.arm64) + elif arch == capstone.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 == capstone.CS_ARCH_MIPS: + self.operands = mips.get_arch_info(detail.arch.mips) + elif arch == capstone.CS_ARCH_PPC: + (self.bc, self.bh, self.update_cr0, self.operands) = \ + ppc.get_arch_info(detail.arch.ppc) + cdef class CsInsn(object): - cdef cc.cs_insn _raw - cdef cc.csh _csh - cdef object _detail - - def __cinit__(self, _detail): - self._detail = _detail - - def __getattr__(self, name): - _detail = self._detail - if not _detail: - raise CsError(capstone.CS_ERR_DETAIL) - return getattr(_detail, name) - - @property - def operands(self): - return self._detail.operands - - @property - def id(self): - return self._raw.id - - @property - def address(self): - return self._raw.address - - @property - def size(self): - return self._raw.size - - @property - def bytes(self): - return bytearray(self._raw.bytes)[:self._raw.size] - - @property - def mnemonic(self): - return self._raw.mnemonic - - @property - def op_str(self): - return self._raw.op_str - - @property - def regs_read(self): - if self._detail: - detail = self._detail - return detail.regs_read[:detail.regs_read_count] - - raise CsError(capstone.CS_ERR_DETAIL) - - @property - def regs_write(self): - if self._detail: - detail = self._detail - return detail.regs_write[:detail.regs_write_count] - - raise CsError(capstone.CS_ERR_DETAIL) - - @property - def groups(self): - if self._detail: - detail = self._detail - return detail.groups[:detail.groups_count] - - raise CsError(capstone.CS_ERR_DETAIL) - - # get the last error code - def errno(self): - return cc.cs_errno(self._csh) - - # get the register name, given the register ID - def reg_name(self, reg_id): - return cc.cs_reg_name(self._csh, reg_id) - - # get the instruction string - def insn_name(self): - return cc.cs_insn_name(self._csh, self.id) - - # verify if this insn belong to group with id as @group_id - def group(self, group_id): - return group_id in self._detail.groups - - # verify if this instruction implicitly read register @reg_id - def reg_read(self, reg_id): - return reg_id in self._detail.regs_read - - # verify if this instruction implicitly modified register @reg_id - def reg_write(self, reg_id): - return reg_id in self._detail.regs_write - - # return number of operands having same operand type @op_type - def op_count(self, op_type): - c = 0 - for op in self._detail.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): - c = 0 - for op in self._detail.operands: - if op.type == op_type: - c += 1 - if c == position: - return op + cdef cc.cs_insn _raw + cdef cc.csh _csh + cdef object _detail + + def __cinit__(self, _detail): + self._detail = _detail + + def __getattr__(self, name): + _detail = self._detail + if not _detail: + raise CsError(capstone.CS_ERR_DETAIL) + return getattr(_detail, name) + + @property + def operands(self): + return self._detail.operands + + @property + def id(self): + return self._raw.id + + @property + def address(self): + return self._raw.address + + @property + def size(self): + return self._raw.size + + @property + def bytes(self): + return bytearray(self._raw.bytes)[:self._raw.size] + + @property + def mnemonic(self): + return self._raw.mnemonic + + @property + def op_str(self): + return self._raw.op_str + + @property + def regs_read(self): + if self._detail: + detail = self._detail + return detail.regs_read[:detail.regs_read_count] + + raise CsError(capstone.CS_ERR_DETAIL) + + @property + def regs_write(self): + if self._detail: + detail = self._detail + return detail.regs_write[:detail.regs_write_count] + + raise CsError(capstone.CS_ERR_DETAIL) + + @property + def groups(self): + if self._detail: + detail = self._detail + return detail.groups[:detail.groups_count] + + raise CsError(capstone.CS_ERR_DETAIL) + + # get the last error code + def errno(self): + return cc.cs_errno(self._csh) + + # get the register name, given the register ID + def reg_name(self, reg_id): + return cc.cs_reg_name(self._csh, reg_id) + + # get the instruction string + def insn_name(self): + return cc.cs_insn_name(self._csh, self.id) + + # verify if this insn belong to group with id as @group_id + def group(self, group_id): + return group_id in self._detail.groups + + # verify if this instruction implicitly read register @reg_id + def reg_read(self, reg_id): + return reg_id in self._detail.regs_read + + # verify if this instruction implicitly modified register @reg_id + def reg_write(self, reg_id): + return reg_id in self._detail.regs_write + + # return number of operands having same operand type @op_type + def op_count(self, op_type): + c = 0 + for op in self._detail.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): + c = 0 + for op in self._detail.operands: + if op.type == op_type: + c += 1 + if c == position: + return op -cdef class Cs: - cdef cc.csh csh - cdef object _cs +cdef class Cs: - def __cinit__(self, _cs): - self.csh = _cs.csh.value - self._cs = _cs + cdef cc.csh csh + cdef object _cs - def disasm(self, code, addr, count=0): - cdef cc.cs_insn *allinsn - cdef res = cc.cs_disasm_ex(self.csh, code, len(code), addr, count, &allinsn) - detail = self._cs.detail - arch = self._cs.arch + def __cinit__(self, _cs): + self.csh = _cs.csh.value + self._cs = _cs - for i from 0 <= i < res: - if detail: - dummy = CsInsn(CsDetail(arch, allinsn[i].detail)) - else: - dummy = CsInsn(None) - dummy._raw = allinsn[i] - dummy._csh = self.csh - yield dummy + def disasm(self, code, addr, count=0): + cdef cc.cs_insn *allinsn + cdef res = cc.cs_disasm_ex(self.csh, code, len(code), addr, count, &allinsn) + detail = self._cs.detail + arch = self._cs.arch + for i from 0 <= i < res: + if detail: + dummy = CsInsn(CsDetail(arch, allinsn[i].detail)) + else: + dummy = CsInsn(None) + dummy._raw = allinsn[i] + dummy._csh = self.csh + yield dummy