mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-23 13:39:46 +00:00
Seperate cython bindings into seperate bindings package
This commit is contained in:
parent
add1659f32
commit
6f96163adc
79
.github/workflows/CITest.yml
vendored
79
.github/workflows/CITest.yml
vendored
@ -1,10 +1,10 @@
|
||||
name: Run Test
|
||||
on:
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- ".gitignore"
|
||||
- "docs/**"
|
||||
- "ChangeLog"
|
||||
- "ChangeLog"
|
||||
- "CREDITS.TXT"
|
||||
- "COMPILE.TXT"
|
||||
- "COMPILE_MSVC.TXT"
|
||||
@ -30,85 +30,30 @@ jobs:
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.9 make',
|
||||
name: 'ubuntu-22.04 x64 make',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.9',
|
||||
build-system: 'make',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.7 cmake',
|
||||
name: 'ubuntu-22.04 x64 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.7',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.8 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.8',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.9 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.9',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.10 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.10',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.11 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.11',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.11 ASAN',
|
||||
name: 'ubuntu-22.04 x64 ASAN',
|
||||
os: ubuntu-latest,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.11',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'ON'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.12 cmake',
|
||||
os: ubuntu-22.04,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.12',
|
||||
build-system: 'cmake',
|
||||
}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.config.python-version }}
|
||||
|
||||
- name: prepare
|
||||
run: |
|
||||
export LD_LIBRARY_PATH=`pwd`/tests/:$LD_LIBRARY_PATH
|
||||
@ -117,8 +62,6 @@ jobs:
|
||||
git clone https://git.cryptomilk.org/projects/cmocka.git suite/cstest/cmocka
|
||||
chmod +x suite/cstest/build_cstest.sh
|
||||
|
||||
pip install "importlib_resources;python_version<'3.9'"
|
||||
|
||||
- name: make
|
||||
if: startsWith(matrix.config.build-system, 'make')
|
||||
run: |
|
||||
@ -181,16 +124,6 @@ jobs:
|
||||
python cstest_report.py -D -t build/cstest -f ../../tests/cs_details/issue.cs
|
||||
cd ../../
|
||||
|
||||
- name: run cython binding test
|
||||
if: matrix.config.enable-asan == 'OFF'
|
||||
run: |
|
||||
pip install cython
|
||||
cd bindings/python
|
||||
make install_cython
|
||||
cd ..
|
||||
python -c "import capstone;print(capstone.debug())" | grep Cython
|
||||
BUILD_TESTS=no make tests
|
||||
|
||||
Windows:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
name: ${{ matrix.config.name }}
|
||||
@ -213,7 +146,7 @@ jobs:
|
||||
|
||||
- name: '🛠️ Win MSVC 64 setup'
|
||||
if: contains(matrix.config.name, 'MSVC 64')
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: 'x64'
|
||||
|
||||
|
6
.github/workflows/python-tests.yml
vendored
6
.github/workflows/python-tests.yml
vendored
@ -12,6 +12,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-24.04, windows-2022, macOS-14]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
bindings: [python, cython]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -26,8 +27,7 @@ jobs:
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Build and install capstone
|
||||
run: pip install ./bindings/python
|
||||
run: pip install ./bindings/${{ matrix.bindings }}
|
||||
|
||||
- name: Run tests
|
||||
run: python test_all.py
|
||||
working-directory: ./bindings/python/tests
|
||||
run: python ./bindings/${{ matrix.bindings }}/test_all.py
|
||||
|
9
bindings/cython/.gitignore
vendored
Normal file
9
bindings/cython/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
MANIFEST
|
||||
dist/
|
||||
src/
|
||||
capstone/lib
|
||||
capstone/include
|
||||
pyx/lib
|
||||
pyx/include
|
||||
pyx/*.c
|
||||
pyx/*.pyx
|
1
bindings/cython/capstone
Symbolic link
1
bindings/cython/capstone
Symbolic link
@ -0,0 +1 @@
|
||||
../python/capstone
|
12
bindings/cython/capstone.egg-info/PKG-INFO
Normal file
12
bindings/cython/capstone.egg-info/PKG-INFO
Normal file
@ -0,0 +1,12 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: capstone
|
||||
Version: 5.0.0.post1
|
||||
Summary: Capstone disassembly engine
|
||||
Home-page: https://www.capstone-engine.org
|
||||
Author: Nguyen Anh Quynh
|
||||
Author-email: aquynh@gmail.com
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Provides: capstone
|
102
bindings/cython/capstone.egg-info/SOURCES.txt
Normal file
102
bindings/cython/capstone.egg-info/SOURCES.txt
Normal file
@ -0,0 +1,102 @@
|
||||
pyproject.toml
|
||||
setup.py
|
||||
capstone.egg-info/PKG-INFO
|
||||
capstone.egg-info/SOURCES.txt
|
||||
capstone.egg-info/dependency_links.txt
|
||||
capstone.egg-info/top_level.txt
|
||||
pyx/__init__.py
|
||||
pyx/aarch64.pyx
|
||||
pyx/aarch64_const.pyx
|
||||
pyx/alpha.pyx
|
||||
pyx/alpha_const.pyx
|
||||
pyx/arm.pyx
|
||||
pyx/arm_const.pyx
|
||||
pyx/bpf.pyx
|
||||
pyx/bpf_const.pyx
|
||||
pyx/ccapstone.pyx
|
||||
pyx/evm.pyx
|
||||
pyx/evm_const.pyx
|
||||
pyx/hppa.pyx
|
||||
pyx/hppa_const.pyx
|
||||
pyx/m680x.pyx
|
||||
pyx/m680x_const.pyx
|
||||
pyx/m68k.pyx
|
||||
pyx/m68k_const.pyx
|
||||
pyx/mips.pyx
|
||||
pyx/mips_const.pyx
|
||||
pyx/mos65xx.pyx
|
||||
pyx/mos65xx_const.pyx
|
||||
pyx/ppc.pyx
|
||||
pyx/ppc_const.pyx
|
||||
pyx/riscv.pyx
|
||||
pyx/riscv_const.pyx
|
||||
pyx/sh.pyx
|
||||
pyx/sh_const.pyx
|
||||
pyx/sparc.pyx
|
||||
pyx/sparc_const.pyx
|
||||
pyx/systemz.pyx
|
||||
pyx/sysz_const.pyx
|
||||
pyx/tms320c64x.pyx
|
||||
pyx/tms320c64x_const.pyx
|
||||
pyx/tricore.pyx
|
||||
pyx/tricore_const.pyx
|
||||
pyx/wasm.pyx
|
||||
pyx/wasm_const.pyx
|
||||
pyx/x86.pyx
|
||||
pyx/x86_const.pyx
|
||||
pyx/xcore.pyx
|
||||
pyx/xcore_const.pyx
|
||||
pyx/include/capstone/aarch64.h
|
||||
pyx/include/capstone/alpha.h
|
||||
pyx/include/capstone/arm.h
|
||||
pyx/include/capstone/arm64.h
|
||||
pyx/include/capstone/bpf.h
|
||||
pyx/include/capstone/capstone.h
|
||||
pyx/include/capstone/cs_operand.h
|
||||
pyx/include/capstone/evm.h
|
||||
pyx/include/capstone/hppa.h
|
||||
pyx/include/capstone/loongarch.h
|
||||
pyx/include/capstone/m680x.h
|
||||
pyx/include/capstone/m68k.h
|
||||
pyx/include/capstone/mips.h
|
||||
pyx/include/capstone/mos65xx.h
|
||||
pyx/include/capstone/platform.h
|
||||
pyx/include/capstone/ppc.h
|
||||
pyx/include/capstone/riscv.h
|
||||
pyx/include/capstone/sh.h
|
||||
pyx/include/capstone/sparc.h
|
||||
pyx/include/capstone/systemz.h
|
||||
pyx/include/capstone/tms320c64x.h
|
||||
pyx/include/capstone/tricore.h
|
||||
pyx/include/capstone/wasm.h
|
||||
pyx/include/capstone/x86.h
|
||||
pyx/include/capstone/xcore.h
|
||||
pyx/lib/libcapstone.a
|
||||
pyx/lib/libcapstone.dylib
|
||||
tests/test_aarch64.py
|
||||
tests/test_all.py
|
||||
tests/test_alpha.py
|
||||
tests/test_arm.py
|
||||
tests/test_basic.py
|
||||
tests/test_bpf.py
|
||||
tests/test_customized_mnem.py
|
||||
tests/test_detail.py
|
||||
tests/test_evm.py
|
||||
tests/test_hppa.py
|
||||
tests/test_iter.py
|
||||
tests/test_lite.py
|
||||
tests/test_m680x.py
|
||||
tests/test_m68k.py
|
||||
tests/test_mips.py
|
||||
tests/test_mos65xx.py
|
||||
tests/test_ppc.py
|
||||
tests/test_riscv.py
|
||||
tests/test_sh.py
|
||||
tests/test_skipdata.py
|
||||
tests/test_sparc.py
|
||||
tests/test_systemz.py
|
||||
tests/test_tms320c64x.py
|
||||
tests/test_tricore.py
|
||||
tests/test_wasm.py
|
||||
tests/test_x86.py
|
||||
tests/test_xcore.py
|
1
bindings/cython/capstone.egg-info/dependency_links.txt
Normal file
1
bindings/cython/capstone.egg-info/dependency_links.txt
Normal file
@ -0,0 +1 @@
|
||||
|
1
bindings/cython/capstone.egg-info/top_level.txt
Normal file
1
bindings/cython/capstone.egg-info/top_level.txt
Normal file
@ -0,0 +1 @@
|
||||
capstone
|
3
bindings/cython/pyproject.toml
Normal file
3
bindings/cython/pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "cython"]
|
||||
build-backend = "setuptools.build_meta"
|
1
bindings/cython/tests
Symbolic link
1
bindings/cython/tests
Symbolic link
@ -0,0 +1 @@
|
||||
../python/tests
|
@ -1,3 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
@ -1,386 +0,0 @@
|
||||
# By Dang Hoang Vu <danghvu@gmail.com>, 2014
|
||||
|
||||
cimport pyx.ccapstone as cc
|
||||
import capstone, ctypes
|
||||
from . import arm, x86, mips, ppc, aarch64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, CsError
|
||||
|
||||
_diet = cc.cs_support(capstone.CS_SUPPORT_DIET)
|
||||
|
||||
|
||||
class CsDetail(object):
|
||||
|
||||
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_read_count = detail.regs_read_count
|
||||
self.regs_write = detail.regs_write
|
||||
self.regs_write_count = detail.regs_write_count
|
||||
self.groups = detail.groups
|
||||
self.groups_count = detail.groups_count
|
||||
self.writeback = detail.writeback
|
||||
|
||||
if arch == capstone.CS_ARCH_ARM:
|
||||
(self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, \
|
||||
self.cc, self.vcc, self.update_flags, self.post_index, self.mem_barrier, self.pred_mask, self.operands) = \
|
||||
arm.get_arch_info(detail.arch.arm)
|
||||
elif arch == capstone.CS_ARCH_AARCH64:
|
||||
(self.cc, self.update_flags, self.post_index, self.operands) = \
|
||||
aarch64.get_arch_info(detail.arch.aarch64)
|
||||
elif arch == capstone.CS_ARCH_X86:
|
||||
(self.prefix, self.opcode, self.rex, self.addr_size, \
|
||||
self.modrm, self.sib, self.disp, \
|
||||
self.sib_index, self.sib_scale, self.sib_base, \
|
||||
self.xop_cc, self.sse_cc, self.avx_cc, self.avx_sae, self.avx_rm, \
|
||||
self.eflags, self.fpu_flags, self.encoding, self.modrm_offset, self.disp_offset, \
|
||||
self.disp_size, self.imm_offset, self.imm_size, self.operands) = x86.get_arch_info(detail.arch.x86)
|
||||
elif arch == capstone.CS_ARCH_M68K:
|
||||
(self.operands, self.op_size) = m68k.get_arch_info(detail.arch.m68k)
|
||||
elif arch == capstone.CS_ARCH_MIPS:
|
||||
self.operands = mips.get_arch_info(detail.arch.mips)
|
||||
elif arch == capstone.CS_ARCH_PPC:
|
||||
(self.bc, self.update_cr0, self.operands) = \
|
||||
ppc.get_arch_info(detail.arch.ppc)
|
||||
elif arch == capstone.CS_ARCH_SPARC:
|
||||
(self.cc, self.hint, self.operands) = sparc.get_arch_info(detail.arch.sparc)
|
||||
elif arch == capstone.CS_ARCH_SYSZ:
|
||||
(self.cc, self.operands) = systemz.get_arch_info(detail.arch.sysz)
|
||||
elif arch == capstone.CS_ARCH_XCORE:
|
||||
self.operands = xcore.get_arch_info(detail.arch.xcore)
|
||||
elif arch == capstone.CS_ARCH_TMS320C64X:
|
||||
(self.condition, self.funit, self.parallel, self.operands) = tms320c64x.get_arch_info(self._detail.arch.tms320c64x)
|
||||
elif arch == capstone.CS_ARCH_M680X:
|
||||
(self.flags, self.operands) = m680x.get_arch_info(detail.arch.m680x)
|
||||
elif arch == capstone.CS_ARCH_EVM:
|
||||
(self.pop, self.push, self.fee) = evm.get_arch_info(detail.arch.evm)
|
||||
elif arch == capstone.CS_ARCH_MOS65XX:
|
||||
(self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(detail.arch.mos65xx)
|
||||
elif arch == capstone.CS_ARCH_WASM:
|
||||
(self.operands) = wasm.get_arch_info(detail.arch.wasm)
|
||||
elif arch == capstone.CS_ARCH_BPF:
|
||||
(self.operands) = bpf.get_arch_info(detail.arch.bpf)
|
||||
elif arch == capstone.CS_ARCH_RISCV:
|
||||
(self.need_effective_addr, self.operands) = riscv.get_arch_info(detail.arch.riscv)
|
||||
elif arch == capstone.CS_ARCH_SH:
|
||||
(self.sh_insn, self.sh_size, self.operands) = sh.get_arch_info(detail.arch.sh)
|
||||
elif arch == capstone.CS_ARCH_TRICORE:
|
||||
(self.update_flags, self.operands) = tricore.get_arch_info(detail.arch.tricore)
|
||||
|
||||
|
||||
cdef class CsInsn(object):
|
||||
|
||||
cdef cc.cs_insn _raw
|
||||
cdef cc.csh _csh
|
||||
cdef object _detail
|
||||
|
||||
def __cinit__(self, _detail):
|
||||
self._detail = _detail
|
||||
|
||||
# defer to CsDetail structure for everything else.
|
||||
def __getattr__(self, name):
|
||||
_detail = self._detail
|
||||
if not _detail:
|
||||
raise CsError(capstone.CS_ERR_DETAIL)
|
||||
return getattr(_detail, name)
|
||||
|
||||
# return instruction's operands.
|
||||
@property
|
||||
def operands(self):
|
||||
return self._detail.operands
|
||||
|
||||
# return instruction's ID.
|
||||
@property
|
||||
def id(self):
|
||||
return self._raw.id
|
||||
|
||||
# return instruction's address.
|
||||
@property
|
||||
def address(self):
|
||||
return self._raw.address
|
||||
|
||||
# return instruction's size.
|
||||
@property
|
||||
def size(self):
|
||||
return self._raw.size
|
||||
|
||||
# return instruction's machine bytes (which should have @size bytes).
|
||||
@property
|
||||
def bytes(self):
|
||||
return bytearray(self._raw.bytes[:self._raw.size])
|
||||
|
||||
# return instruction's mnemonic.
|
||||
@property
|
||||
def mnemonic(self):
|
||||
if _diet:
|
||||
# Diet engine cannot provide @mnemonic & @op_str
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return self._raw.mnemonic
|
||||
|
||||
# return instruction's operands (in string).
|
||||
@property
|
||||
def op_str(self):
|
||||
if _diet:
|
||||
# Diet engine cannot provide @mnemonic & @op_str
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return self._raw.op_str
|
||||
|
||||
# return list of all implicit registers being read.
|
||||
@property
|
||||
def regs_read(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @regs_read
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
if self._detail:
|
||||
detail = self._detail
|
||||
return detail.regs_read[:detail.regs_read_count]
|
||||
|
||||
raise CsError(capstone.CS_ERR_DETAIL)
|
||||
|
||||
# return list of all implicit registers being modified
|
||||
@property
|
||||
def regs_write(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @regs_write
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
if self._detail:
|
||||
detail = self._detail
|
||||
return detail.regs_write[:detail.regs_write_count]
|
||||
|
||||
raise CsError(capstone.CS_ERR_DETAIL)
|
||||
|
||||
# return list of semantic groups this instruction belongs to.
|
||||
@property
|
||||
def groups(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @groups
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
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):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide register's name
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return cc.cs_reg_name(self._csh, reg_id)
|
||||
|
||||
# get the instruction string
|
||||
def insn_name(self):
|
||||
if _diet:
|
||||
# Diet engine cannot provide instruction's name
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return cc.cs_insn_name(self._csh, self.id)
|
||||
|
||||
# get the group string
|
||||
def group_name(self, group_id):
|
||||
if _diet:
|
||||
# Diet engine cannot provide group's name
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return cc.cs_group_name(self._csh, group_id)
|
||||
|
||||
# verify if this insn belong to group with id as @group_id
|
||||
def group(self, group_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @groups
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return group_id in self.groups
|
||||
|
||||
# verify if this instruction implicitly read register @reg_id
|
||||
def reg_read(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @regs_read
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return reg_id in self.regs_read
|
||||
|
||||
# verify if this instruction implicitly modified register @reg_id
|
||||
def reg_write(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @regs_write
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
return reg_id in self.regs_write
|
||||
|
||||
# return number of operands having same operand type @op_type
|
||||
def op_count(self, op_type):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
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):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
c = 0
|
||||
for op in self._detail.operands:
|
||||
if op.type == op_type:
|
||||
c += 1
|
||||
if c == position:
|
||||
return op
|
||||
|
||||
# Return (list-of-registers-read, list-of-registers-modified) by this instructions.
|
||||
# This includes all the implicit & explicit registers.
|
||||
def regs_access(self):
|
||||
if self._raw.id == 0:
|
||||
raise CsError(capstone.CS_ERR_SKIPDATA)
|
||||
|
||||
cdef cc.uint16_t regs_read[64]
|
||||
cdef cc.uint16_t regs_write[64]
|
||||
cdef cc.uint8_t read_count, write_count
|
||||
|
||||
status = cc.cs_regs_access(self._cs.csh, &self._raw, regs_read, &read_count, regs_write, &write_count)
|
||||
if status != capstone.CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
r1 = []
|
||||
for i from 0 <= i < read_count: r1.append(regs_read[i])
|
||||
|
||||
w1 = []
|
||||
for i from 0 <= i < write_count: w1.append(regs_write[i])
|
||||
|
||||
return (r1, w1)
|
||||
|
||||
|
||||
cdef class Cs(object):
|
||||
|
||||
cdef cc.csh _csh
|
||||
cdef object _cs
|
||||
|
||||
def __cinit__(self, _cs):
|
||||
cdef version = cc.cs_version(NULL, NULL)
|
||||
if (version != (capstone.CS_API_MAJOR << 8) + capstone.CS_API_MINOR):
|
||||
# our binding version is different from the core's API version
|
||||
raise CsError(capstone.CS_ERR_VERSION)
|
||||
|
||||
self._csh = <cc.csh> _cs.csh.value
|
||||
self._cs = _cs
|
||||
|
||||
|
||||
# destructor to be called automatically when object is destroyed.
|
||||
def __dealloc__(self):
|
||||
if self._csh:
|
||||
status = cc.cs_close(&self._csh)
|
||||
if status != capstone.CS_ERR_OK:
|
||||
raise CsError(status)
|
||||
|
||||
|
||||
# Disassemble binary & return disassembled instructions in CsInsn objects
|
||||
def disasm(self, code, addr, count=0):
|
||||
cdef cc.cs_insn *allinsn
|
||||
|
||||
cdef res = cc.cs_disasm(self._csh, code, len(code), addr, count, &allinsn)
|
||||
detail = self._cs.detail
|
||||
arch = self._cs.arch
|
||||
|
||||
try:
|
||||
for i from 0 <= i < res:
|
||||
if detail:
|
||||
dummy = CsInsn(CsDetail(arch, <size_t>allinsn[i].detail))
|
||||
else:
|
||||
dummy = CsInsn(None)
|
||||
|
||||
dummy._raw = allinsn[i]
|
||||
dummy._csh = self._csh
|
||||
yield dummy
|
||||
finally:
|
||||
cc.cs_free(allinsn, res)
|
||||
|
||||
|
||||
# Light function to disassemble binary. This is about 20% faster than disasm() because
|
||||
# unlike disasm(), disasm_lite() only return tuples of (address, size, mnemonic, op_str),
|
||||
# rather than CsInsn objects.
|
||||
def disasm_lite(self, code, addr, count=0):
|
||||
# TODO: don't need detail, so we might turn off detail, then turn on again when done
|
||||
cdef cc.cs_insn *allinsn
|
||||
|
||||
if _diet:
|
||||
# Diet engine cannot provide @mnemonic & @op_str
|
||||
raise CsError(capstone.CS_ERR_DIET)
|
||||
|
||||
cdef res = cc.cs_disasm(self._csh, code, len(code), addr, count, &allinsn)
|
||||
|
||||
try:
|
||||
for i from 0 <= i < res:
|
||||
insn = allinsn[i]
|
||||
yield (insn.address, insn.size, insn.mnemonic, insn.op_str)
|
||||
finally:
|
||||
cc.cs_free(allinsn, res)
|
||||
|
||||
|
||||
# print out debugging info
|
||||
def debug():
|
||||
if cc.cs_support(capstone.CS_SUPPORT_DIET):
|
||||
diet = "diet"
|
||||
else:
|
||||
diet = "standard"
|
||||
|
||||
archs = { "arm": capstone.CS_ARCH_ARM, "aarch64": capstone.CS_ARCH_AARCH64, \
|
||||
"m68k": capstone.CS_ARCH_M68K, "mips": capstone.CS_ARCH_MIPS, \
|
||||
"ppc": capstone.CS_ARCH_PPC, "sparc": capstone.CS_ARCH_SPARC, \
|
||||
"sysz": capstone.CS_ARCH_SYSZ, "xcore": capstone.CS_ARCH_XCORE, \
|
||||
"tms320c64x": capstone.CS_ARCH_TMS320C64X, "m680x": capstone.CS_ARCH_M680X, \
|
||||
"evm": capstone.CS_ARCH_EVM, "mos65xx": capstone.CS_ARCH_MOS65XX, \
|
||||
"wasm": capstone.CS_ARCH_WASM, \
|
||||
"bpf": capstone.CS_ARCH_BPF, "riscv": capstone.CS_ARCH_RISCV, \
|
||||
"sh": capstone.CS_ARCH_SH, "tricore": capstone.CS_ARCH_TRICORE }
|
||||
|
||||
all_archs = ""
|
||||
keys = list(archs.keys())
|
||||
keys.sort()
|
||||
for k in keys:
|
||||
if cc.cs_support(archs[k]):
|
||||
all_archs += "-%s" %k
|
||||
|
||||
if cc.cs_support(capstone.CS_ARCH_X86):
|
||||
all_archs += "-x86"
|
||||
if cc.cs_support(capstone.CS_SUPPORT_X86_REDUCE):
|
||||
all_archs += "_reduce"
|
||||
|
||||
(major, minor, _combined) = capstone.cs_version()
|
||||
|
||||
return "Cython-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, capstone.CS_API_MAJOR, capstone.CS_API_MINOR)
|
Loading…
Reference in New Issue
Block a user