xref: /aosp_15_r20/external/capstone/bindings/python/pyx/ccapstone.pyx (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
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