1*9a0e4156SSadaf Ebrahimi# By Dang Hoang Vu <[email protected]>, 2014 2*9a0e4156SSadaf Ebrahimi 3*9a0e4156SSadaf Ebrahimicimport pyx.ccapstone as cc 4*9a0e4156SSadaf Ebrahimiimport capstone, ctypes 5*9a0e4156SSadaf Ebrahimifrom . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, CsError 6*9a0e4156SSadaf Ebrahimi 7*9a0e4156SSadaf Ebrahimi_diet = cc.cs_support(capstone.CS_SUPPORT_DIET) 8*9a0e4156SSadaf Ebrahimi 9*9a0e4156SSadaf Ebrahimi 10*9a0e4156SSadaf Ebrahimiclass CsDetail(object): 11*9a0e4156SSadaf Ebrahimi 12*9a0e4156SSadaf Ebrahimi def __init__(self, arch, raw_detail = None): 13*9a0e4156SSadaf Ebrahimi if not raw_detail: 14*9a0e4156SSadaf Ebrahimi return 15*9a0e4156SSadaf Ebrahimi detail = ctypes.cast(raw_detail, ctypes.POINTER(capstone._cs_detail)).contents 16*9a0e4156SSadaf Ebrahimi 17*9a0e4156SSadaf Ebrahimi self.regs_read = detail.regs_read 18*9a0e4156SSadaf Ebrahimi self.regs_read_count = detail.regs_read_count 19*9a0e4156SSadaf Ebrahimi self.regs_write = detail.regs_write 20*9a0e4156SSadaf Ebrahimi self.regs_write_count = detail.regs_write_count 21*9a0e4156SSadaf Ebrahimi self.groups = detail.groups 22*9a0e4156SSadaf Ebrahimi self.groups_count = detail.groups_count 23*9a0e4156SSadaf Ebrahimi 24*9a0e4156SSadaf Ebrahimi if arch == capstone.CS_ARCH_ARM: 25*9a0e4156SSadaf Ebrahimi (self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, \ 26*9a0e4156SSadaf Ebrahimi self.cc, self.update_flags, self.writeback, self.mem_barrier, self.operands) = \ 27*9a0e4156SSadaf Ebrahimi arm.get_arch_info(detail.arch.arm) 28*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_ARM64: 29*9a0e4156SSadaf Ebrahimi (self.cc, self.update_flags, self.writeback, self.operands) = \ 30*9a0e4156SSadaf Ebrahimi arm64.get_arch_info(detail.arch.arm64) 31*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_X86: 32*9a0e4156SSadaf Ebrahimi (self.prefix, self.opcode, self.rex, self.addr_size, \ 33*9a0e4156SSadaf Ebrahimi self.modrm, self.sib, self.disp, \ 34*9a0e4156SSadaf Ebrahimi self.sib_index, self.sib_scale, self.sib_base, \ 35*9a0e4156SSadaf Ebrahimi self.xop_cc, self.sse_cc, self.avx_cc, self.avx_sae, self.avx_rm, \ 36*9a0e4156SSadaf Ebrahimi self.eflags, self.operands) = x86.get_arch_info(detail.arch.x86) 37*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_MIPS: 38*9a0e4156SSadaf Ebrahimi self.operands = mips.get_arch_info(detail.arch.mips) 39*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_PPC: 40*9a0e4156SSadaf Ebrahimi (self.bc, self.bh, self.update_cr0, self.operands) = \ 41*9a0e4156SSadaf Ebrahimi ppc.get_arch_info(detail.arch.ppc) 42*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_SPARC: 43*9a0e4156SSadaf Ebrahimi (self.cc, self.hint, self.operands) = sparc.get_arch_info(detail.arch.sparc) 44*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_SYSZ: 45*9a0e4156SSadaf Ebrahimi (self.cc, self.operands) = systemz.get_arch_info(detail.arch.sysz) 46*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_XCORE: 47*9a0e4156SSadaf Ebrahimi self.operands = xcore.get_arch_info(detail.arch.xcore) 48*9a0e4156SSadaf Ebrahimi elif arch == capstone.CS_ARCH_TMS320C64X: 49*9a0e4156SSadaf Ebrahimi (self.condition, self.funit, self.parallel, self.operands) = tms320c64x.get_arch_info(self._detail.arch.tms320c64x) 50*9a0e4156SSadaf Ebrahimi 51*9a0e4156SSadaf Ebrahimi 52*9a0e4156SSadaf Ebrahimicdef class CsInsn(object): 53*9a0e4156SSadaf Ebrahimi 54*9a0e4156SSadaf Ebrahimi cdef cc.cs_insn _raw 55*9a0e4156SSadaf Ebrahimi cdef cc.csh _csh 56*9a0e4156SSadaf Ebrahimi cdef object _detail 57*9a0e4156SSadaf Ebrahimi 58*9a0e4156SSadaf Ebrahimi def __cinit__(self, _detail): 59*9a0e4156SSadaf Ebrahimi self._detail = _detail 60*9a0e4156SSadaf Ebrahimi 61*9a0e4156SSadaf Ebrahimi # defer to CsDetail structure for everything else. 62*9a0e4156SSadaf Ebrahimi def __getattr__(self, name): 63*9a0e4156SSadaf Ebrahimi _detail = self._detail 64*9a0e4156SSadaf Ebrahimi if not _detail: 65*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DETAIL) 66*9a0e4156SSadaf Ebrahimi return getattr(_detail, name) 67*9a0e4156SSadaf Ebrahimi 68*9a0e4156SSadaf Ebrahimi # return instruction's operands. 69*9a0e4156SSadaf Ebrahimi @property 70*9a0e4156SSadaf Ebrahimi def operands(self): 71*9a0e4156SSadaf Ebrahimi return self._detail.operands 72*9a0e4156SSadaf Ebrahimi 73*9a0e4156SSadaf Ebrahimi # return instruction's ID. 74*9a0e4156SSadaf Ebrahimi @property 75*9a0e4156SSadaf Ebrahimi def id(self): 76*9a0e4156SSadaf Ebrahimi return self._raw.id 77*9a0e4156SSadaf Ebrahimi 78*9a0e4156SSadaf Ebrahimi # return instruction's address. 79*9a0e4156SSadaf Ebrahimi @property 80*9a0e4156SSadaf Ebrahimi def address(self): 81*9a0e4156SSadaf Ebrahimi return self._raw.address 82*9a0e4156SSadaf Ebrahimi 83*9a0e4156SSadaf Ebrahimi # return instruction's size. 84*9a0e4156SSadaf Ebrahimi @property 85*9a0e4156SSadaf Ebrahimi def size(self): 86*9a0e4156SSadaf Ebrahimi return self._raw.size 87*9a0e4156SSadaf Ebrahimi 88*9a0e4156SSadaf Ebrahimi # return instruction's machine bytes (which should have @size bytes). 89*9a0e4156SSadaf Ebrahimi @property 90*9a0e4156SSadaf Ebrahimi def bytes(self): 91*9a0e4156SSadaf Ebrahimi return bytearray(self._raw.bytes[:self._raw.size]) 92*9a0e4156SSadaf Ebrahimi 93*9a0e4156SSadaf Ebrahimi # return instruction's mnemonic. 94*9a0e4156SSadaf Ebrahimi @property 95*9a0e4156SSadaf Ebrahimi def mnemonic(self): 96*9a0e4156SSadaf Ebrahimi if _diet: 97*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @mnemonic & @op_str 98*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 99*9a0e4156SSadaf Ebrahimi 100*9a0e4156SSadaf Ebrahimi return self._raw.mnemonic 101*9a0e4156SSadaf Ebrahimi 102*9a0e4156SSadaf Ebrahimi # return instruction's operands (in string). 103*9a0e4156SSadaf Ebrahimi @property 104*9a0e4156SSadaf Ebrahimi def op_str(self): 105*9a0e4156SSadaf Ebrahimi if _diet: 106*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @mnemonic & @op_str 107*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 108*9a0e4156SSadaf Ebrahimi 109*9a0e4156SSadaf Ebrahimi return self._raw.op_str 110*9a0e4156SSadaf Ebrahimi 111*9a0e4156SSadaf Ebrahimi # return list of all implicit registers being read. 112*9a0e4156SSadaf Ebrahimi @property 113*9a0e4156SSadaf Ebrahimi def regs_read(self): 114*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 115*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 116*9a0e4156SSadaf Ebrahimi 117*9a0e4156SSadaf Ebrahimi if _diet: 118*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @regs_read 119*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 120*9a0e4156SSadaf Ebrahimi 121*9a0e4156SSadaf Ebrahimi if self._detail: 122*9a0e4156SSadaf Ebrahimi detail = self._detail 123*9a0e4156SSadaf Ebrahimi return detail.regs_read[:detail.regs_read_count] 124*9a0e4156SSadaf Ebrahimi 125*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DETAIL) 126*9a0e4156SSadaf Ebrahimi 127*9a0e4156SSadaf Ebrahimi # return list of all implicit registers being modified 128*9a0e4156SSadaf Ebrahimi @property 129*9a0e4156SSadaf Ebrahimi def regs_write(self): 130*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 131*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 132*9a0e4156SSadaf Ebrahimi 133*9a0e4156SSadaf Ebrahimi if _diet: 134*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @regs_write 135*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 136*9a0e4156SSadaf Ebrahimi 137*9a0e4156SSadaf Ebrahimi if self._detail: 138*9a0e4156SSadaf Ebrahimi detail = self._detail 139*9a0e4156SSadaf Ebrahimi return detail.regs_write[:detail.regs_write_count] 140*9a0e4156SSadaf Ebrahimi 141*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DETAIL) 142*9a0e4156SSadaf Ebrahimi 143*9a0e4156SSadaf Ebrahimi # return list of semantic groups this instruction belongs to. 144*9a0e4156SSadaf Ebrahimi @property 145*9a0e4156SSadaf Ebrahimi def groups(self): 146*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 147*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 148*9a0e4156SSadaf Ebrahimi 149*9a0e4156SSadaf Ebrahimi if _diet: 150*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @groups 151*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 152*9a0e4156SSadaf Ebrahimi 153*9a0e4156SSadaf Ebrahimi if self._detail: 154*9a0e4156SSadaf Ebrahimi detail = self._detail 155*9a0e4156SSadaf Ebrahimi return detail.groups[:detail.groups_count] 156*9a0e4156SSadaf Ebrahimi 157*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DETAIL) 158*9a0e4156SSadaf Ebrahimi 159*9a0e4156SSadaf Ebrahimi # get the last error code 160*9a0e4156SSadaf Ebrahimi def errno(self): 161*9a0e4156SSadaf Ebrahimi return cc.cs_errno(self._csh) 162*9a0e4156SSadaf Ebrahimi 163*9a0e4156SSadaf Ebrahimi # get the register name, given the register ID 164*9a0e4156SSadaf Ebrahimi def reg_name(self, reg_id): 165*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 166*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 167*9a0e4156SSadaf Ebrahimi 168*9a0e4156SSadaf Ebrahimi if _diet: 169*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide register's name 170*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 171*9a0e4156SSadaf Ebrahimi 172*9a0e4156SSadaf Ebrahimi return cc.cs_reg_name(self._csh, reg_id) 173*9a0e4156SSadaf Ebrahimi 174*9a0e4156SSadaf Ebrahimi # get the instruction string 175*9a0e4156SSadaf Ebrahimi def insn_name(self): 176*9a0e4156SSadaf Ebrahimi if _diet: 177*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide instruction's name 178*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 179*9a0e4156SSadaf Ebrahimi 180*9a0e4156SSadaf Ebrahimi return cc.cs_insn_name(self._csh, self.id) 181*9a0e4156SSadaf Ebrahimi 182*9a0e4156SSadaf Ebrahimi # get the group string 183*9a0e4156SSadaf Ebrahimi def group_name(self, group_id): 184*9a0e4156SSadaf Ebrahimi if _diet: 185*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide group's name 186*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 187*9a0e4156SSadaf Ebrahimi 188*9a0e4156SSadaf Ebrahimi return cc.cs_group_name(self._csh, group_id) 189*9a0e4156SSadaf Ebrahimi 190*9a0e4156SSadaf Ebrahimi # verify if this insn belong to group with id as @group_id 191*9a0e4156SSadaf Ebrahimi def group(self, group_id): 192*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 193*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 194*9a0e4156SSadaf Ebrahimi 195*9a0e4156SSadaf Ebrahimi if _diet: 196*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @groups 197*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 198*9a0e4156SSadaf Ebrahimi 199*9a0e4156SSadaf Ebrahimi return group_id in self.groups 200*9a0e4156SSadaf Ebrahimi 201*9a0e4156SSadaf Ebrahimi # verify if this instruction implicitly read register @reg_id 202*9a0e4156SSadaf Ebrahimi def reg_read(self, reg_id): 203*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 204*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 205*9a0e4156SSadaf Ebrahimi 206*9a0e4156SSadaf Ebrahimi if _diet: 207*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @regs_read 208*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 209*9a0e4156SSadaf Ebrahimi 210*9a0e4156SSadaf Ebrahimi return reg_id in self.regs_read 211*9a0e4156SSadaf Ebrahimi 212*9a0e4156SSadaf Ebrahimi # verify if this instruction implicitly modified register @reg_id 213*9a0e4156SSadaf Ebrahimi def reg_write(self, reg_id): 214*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 215*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 216*9a0e4156SSadaf Ebrahimi 217*9a0e4156SSadaf Ebrahimi if _diet: 218*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @regs_write 219*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 220*9a0e4156SSadaf Ebrahimi 221*9a0e4156SSadaf Ebrahimi return reg_id in self.regs_write 222*9a0e4156SSadaf Ebrahimi 223*9a0e4156SSadaf Ebrahimi # return number of operands having same operand type @op_type 224*9a0e4156SSadaf Ebrahimi def op_count(self, op_type): 225*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 226*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 227*9a0e4156SSadaf Ebrahimi 228*9a0e4156SSadaf Ebrahimi c = 0 229*9a0e4156SSadaf Ebrahimi for op in self._detail.operands: 230*9a0e4156SSadaf Ebrahimi if op.type == op_type: 231*9a0e4156SSadaf Ebrahimi c += 1 232*9a0e4156SSadaf Ebrahimi return c 233*9a0e4156SSadaf Ebrahimi 234*9a0e4156SSadaf Ebrahimi # get the operand at position @position of all operands having the same type @op_type 235*9a0e4156SSadaf Ebrahimi def op_find(self, op_type, position): 236*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 237*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 238*9a0e4156SSadaf Ebrahimi 239*9a0e4156SSadaf Ebrahimi c = 0 240*9a0e4156SSadaf Ebrahimi for op in self._detail.operands: 241*9a0e4156SSadaf Ebrahimi if op.type == op_type: 242*9a0e4156SSadaf Ebrahimi c += 1 243*9a0e4156SSadaf Ebrahimi if c == position: 244*9a0e4156SSadaf Ebrahimi return op 245*9a0e4156SSadaf Ebrahimi 246*9a0e4156SSadaf Ebrahimi # Return (list-of-registers-read, list-of-registers-modified) by this instructions. 247*9a0e4156SSadaf Ebrahimi # This includes all the implicit & explicit registers. 248*9a0e4156SSadaf Ebrahimi def regs_access(self): 249*9a0e4156SSadaf Ebrahimi if self._raw.id == 0: 250*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_SKIPDATA) 251*9a0e4156SSadaf Ebrahimi 252*9a0e4156SSadaf Ebrahimi cdef cc.uint16_t regs_read[64], regs_write[64] 253*9a0e4156SSadaf Ebrahimi cdef cc.uint8_t read_count, write_count 254*9a0e4156SSadaf Ebrahimi 255*9a0e4156SSadaf Ebrahimi status = cc.cs_regs_access(self._cs.csh, &self._raw, regs_read, &read_count, regs_write, &write_count) 256*9a0e4156SSadaf Ebrahimi if status != capstone.CS_ERR_OK: 257*9a0e4156SSadaf Ebrahimi raise CsError(status) 258*9a0e4156SSadaf Ebrahimi 259*9a0e4156SSadaf Ebrahimi r1 = [] 260*9a0e4156SSadaf Ebrahimi for i from 0 <= i < read_count: r1.append(regs_read[i]) 261*9a0e4156SSadaf Ebrahimi 262*9a0e4156SSadaf Ebrahimi w1 = [] 263*9a0e4156SSadaf Ebrahimi for i from 0 <= i < write_count: w1.append(regs_write[i]) 264*9a0e4156SSadaf Ebrahimi 265*9a0e4156SSadaf Ebrahimi return (r1, w1) 266*9a0e4156SSadaf Ebrahimi 267*9a0e4156SSadaf Ebrahimi 268*9a0e4156SSadaf Ebrahimicdef class Cs(object): 269*9a0e4156SSadaf Ebrahimi 270*9a0e4156SSadaf Ebrahimi cdef cc.csh _csh 271*9a0e4156SSadaf Ebrahimi cdef object _cs 272*9a0e4156SSadaf Ebrahimi 273*9a0e4156SSadaf Ebrahimi def __cinit__(self, _cs): 274*9a0e4156SSadaf Ebrahimi cdef version = cc.cs_version(NULL, NULL) 275*9a0e4156SSadaf Ebrahimi if (version != (capstone.CS_API_MAJOR << 8) + capstone.CS_API_MINOR): 276*9a0e4156SSadaf Ebrahimi # our binding version is different from the core's API version 277*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_VERSION) 278*9a0e4156SSadaf Ebrahimi 279*9a0e4156SSadaf Ebrahimi self._csh = <cc.csh> _cs.csh.value 280*9a0e4156SSadaf Ebrahimi self._cs = _cs 281*9a0e4156SSadaf Ebrahimi 282*9a0e4156SSadaf Ebrahimi 283*9a0e4156SSadaf Ebrahimi # destructor to be called automatically when object is destroyed. 284*9a0e4156SSadaf Ebrahimi def __dealloc__(self): 285*9a0e4156SSadaf Ebrahimi if self._csh: 286*9a0e4156SSadaf Ebrahimi status = cc.cs_close(&self._csh) 287*9a0e4156SSadaf Ebrahimi if status != capstone.CS_ERR_OK: 288*9a0e4156SSadaf Ebrahimi raise CsError(status) 289*9a0e4156SSadaf Ebrahimi 290*9a0e4156SSadaf Ebrahimi 291*9a0e4156SSadaf Ebrahimi # Disassemble binary & return disassembled instructions in CsInsn objects 292*9a0e4156SSadaf Ebrahimi def disasm(self, code, addr, count=0): 293*9a0e4156SSadaf Ebrahimi cdef cc.cs_insn *allinsn 294*9a0e4156SSadaf Ebrahimi 295*9a0e4156SSadaf Ebrahimi cdef res = cc.cs_disasm(self._csh, code, len(code), addr, count, &allinsn) 296*9a0e4156SSadaf Ebrahimi detail = self._cs.detail 297*9a0e4156SSadaf Ebrahimi arch = self._cs.arch 298*9a0e4156SSadaf Ebrahimi 299*9a0e4156SSadaf Ebrahimi try: 300*9a0e4156SSadaf Ebrahimi for i from 0 <= i < res: 301*9a0e4156SSadaf Ebrahimi if detail: 302*9a0e4156SSadaf Ebrahimi dummy = CsInsn(CsDetail(arch, <size_t>allinsn[i].detail)) 303*9a0e4156SSadaf Ebrahimi else: 304*9a0e4156SSadaf Ebrahimi dummy = CsInsn(None) 305*9a0e4156SSadaf Ebrahimi 306*9a0e4156SSadaf Ebrahimi dummy._raw = allinsn[i] 307*9a0e4156SSadaf Ebrahimi dummy._csh = self._csh 308*9a0e4156SSadaf Ebrahimi yield dummy 309*9a0e4156SSadaf Ebrahimi finally: 310*9a0e4156SSadaf Ebrahimi cc.cs_free(allinsn, res) 311*9a0e4156SSadaf Ebrahimi 312*9a0e4156SSadaf Ebrahimi 313*9a0e4156SSadaf Ebrahimi # Light function to disassemble binary. This is about 20% faster than disasm() because 314*9a0e4156SSadaf Ebrahimi # unlike disasm(), disasm_lite() only return tuples of (address, size, mnemonic, op_str), 315*9a0e4156SSadaf Ebrahimi # rather than CsInsn objects. 316*9a0e4156SSadaf Ebrahimi def disasm_lite(self, code, addr, count=0): 317*9a0e4156SSadaf Ebrahimi # TODO: dont need detail, so we might turn off detail, then turn on again when done 318*9a0e4156SSadaf Ebrahimi cdef cc.cs_insn *allinsn 319*9a0e4156SSadaf Ebrahimi 320*9a0e4156SSadaf Ebrahimi if _diet: 321*9a0e4156SSadaf Ebrahimi # Diet engine cannot provide @mnemonic & @op_str 322*9a0e4156SSadaf Ebrahimi raise CsError(capstone.CS_ERR_DIET) 323*9a0e4156SSadaf Ebrahimi 324*9a0e4156SSadaf Ebrahimi cdef res = cc.cs_disasm(self._csh, code, len(code), addr, count, &allinsn) 325*9a0e4156SSadaf Ebrahimi 326*9a0e4156SSadaf Ebrahimi try: 327*9a0e4156SSadaf Ebrahimi for i from 0 <= i < res: 328*9a0e4156SSadaf Ebrahimi insn = allinsn[i] 329*9a0e4156SSadaf Ebrahimi yield (insn.address, insn.size, insn.mnemonic, insn.op_str) 330*9a0e4156SSadaf Ebrahimi finally: 331*9a0e4156SSadaf Ebrahimi cc.cs_free(allinsn, res) 332*9a0e4156SSadaf Ebrahimi 333*9a0e4156SSadaf Ebrahimi 334*9a0e4156SSadaf Ebrahimi# print out debugging info 335*9a0e4156SSadaf Ebrahimidef debug(): 336*9a0e4156SSadaf Ebrahimi if cc.cs_support(capstone.CS_SUPPORT_DIET): 337*9a0e4156SSadaf Ebrahimi diet = "diet" 338*9a0e4156SSadaf Ebrahimi else: 339*9a0e4156SSadaf Ebrahimi diet = "standard" 340*9a0e4156SSadaf Ebrahimi 341*9a0e4156SSadaf Ebrahimi archs = { "arm": capstone.CS_ARCH_ARM, "arm64": capstone.CS_ARCH_ARM64, \ 342*9a0e4156SSadaf Ebrahimi "mips": capstone.CS_ARCH_MIPS, "ppc": capstone.CS_ARCH_PPC, \ 343*9a0e4156SSadaf Ebrahimi "sparc": capstone.CS_ARCH_SPARC, "sysz": capstone.CS_ARCH_SYSZ, \ 344*9a0e4156SSadaf Ebrahimi "xcore": capstone.CS_ARCH_XCORE, "tms320c64x": capstone.CS_ARCH_TMS320C64X } 345*9a0e4156SSadaf Ebrahimi 346*9a0e4156SSadaf Ebrahimi all_archs = "" 347*9a0e4156SSadaf Ebrahimi keys = archs.keys() 348*9a0e4156SSadaf Ebrahimi keys.sort() 349*9a0e4156SSadaf Ebrahimi for k in keys: 350*9a0e4156SSadaf Ebrahimi if cc.cs_support(archs[k]): 351*9a0e4156SSadaf Ebrahimi all_archs += "-%s" %k 352*9a0e4156SSadaf Ebrahimi 353*9a0e4156SSadaf Ebrahimi if cc.cs_support(capstone.CS_ARCH_X86): 354*9a0e4156SSadaf Ebrahimi all_archs += "-x86" 355*9a0e4156SSadaf Ebrahimi if cc.cs_support(capstone.CS_SUPPORT_X86_REDUCE): 356*9a0e4156SSadaf Ebrahimi all_archs += "_reduce" 357*9a0e4156SSadaf Ebrahimi 358*9a0e4156SSadaf Ebrahimi (major, minor, _combined) = capstone.cs_version() 359*9a0e4156SSadaf Ebrahimi 360*9a0e4156SSadaf Ebrahimi return "Cython-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, capstone.CS_API_MAJOR, capstone.CS_API_MINOR) 361