Skip to content

Commit

Permalink
python: add CsInsn.is_invalid_insn to bypass evm issue
Browse files Browse the repository at this point in the history
  • Loading branch information
andelf committed Jan 16, 2025
1 parent 617463e commit ef0dda7
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions bindings/python/capstone/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ class CsInsn(object):
def __init__(self, cs, all_info):
self._raw = copy_ctypes(all_info)
self._cs = cs
if self._cs._detail and self._raw.id != 0:
if self._cs._detail and not self.is_invalid_insn():
# save detail
self._raw.detail = ctypes.pointer(all_info.detail._type_())
ctypes.memmove(ctypes.byref(self._raw.detail[0]), ctypes.byref(all_info.detail[0]),
Expand All @@ -795,6 +795,14 @@ def __init__(self, cs, all_info):
def __repr__(self):
return '<CsInsn 0x%x [%s]: %s %s>' % (self.address, self.bytes.hex(), self.mnemonic, self.op_str)

# return if the instruction is invalid
def is_invalid_insn(self):
arch = self._cs.arch
if arch == CS_ARCH_EVM:
return self.id == evm.EVM_INS_INVALID
else:
return self.id == 0

# return instruction's ID.
@property
def id(self):
Expand Down Expand Up @@ -851,7 +859,7 @@ def op_str(self):
# return list of all implicit registers being read.
@property
def regs_read(self):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -866,7 +874,7 @@ def regs_read(self):
# return list of all implicit registers being modified
@property
def regs_write(self):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -881,7 +889,7 @@ def regs_write(self):
# return list of semantic groups this instruction belongs to.
@property
def groups(self):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -896,7 +904,7 @@ def groups(self):
# return whether instruction has writeback operands.
@property
def writeback(self):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -909,7 +917,7 @@ def writeback(self):
raise CsError(CS_ERR_DETAIL)

def __gen_detail(self):
if self._raw.id == 0:
if self.is_invalid_insn():
# do nothing in skipdata mode
return

Expand Down Expand Up @@ -978,7 +986,7 @@ def __getattr__(self, name):
if 'operands' not in _dict:
self.__gen_detail()
if name not in _dict:
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)
raise AttributeError(f"'CsInsn' has no attribute '{name}'")
return _dict[name]
Expand All @@ -1001,7 +1009,7 @@ def insn_name(self, default=None):
# Diet engine cannot provide instruction name
raise CsError(CS_ERR_DIET)

if self._raw.id == 0:
if self.is_invalid_insn():
return default

return _ascii_name_or_default(_cs.cs_insn_name(self._cs.csh, self.id), default)
Expand All @@ -1016,7 +1024,7 @@ def group_name(self, group_id, default=None):

# verify if this insn belong to group with id as @group_id
def group(self, group_id):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -1027,7 +1035,7 @@ def group(self, group_id):

# verify if this instruction implicitly read register @reg_id
def reg_read(self, reg_id):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -1038,7 +1046,7 @@ def reg_read(self, reg_id):

# verify if this instruction implicitly modified register @reg_id
def reg_write(self, reg_id):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
Expand All @@ -1049,7 +1057,7 @@ def reg_write(self, reg_id):

# return number of operands having same operand type @op_type
def op_count(self, op_type):
if self._raw.id == 0:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

c = 0
Expand All @@ -1060,7 +1068,7 @@ def op_count(self, op_type):

# 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:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

c = 0
Expand All @@ -1073,7 +1081,7 @@ def op_find(self, op_type, position):
# 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:
if self.is_invalid_insn():
raise CsError(CS_ERR_SKIPDATA)

regs_read = (ctypes.c_uint16 * 64)()
Expand Down

0 comments on commit ef0dda7

Please sign in to comment.