Fix skipdata setup (#1320)

* Fix skipdata_setup for when _cb is None

ctypes prototype does not accept None value,
so if we want to get a NULL function pointer
then we should either call it with no arguments
or pass zero as an argument.

Fixes #1316

* Do store and return skipdata_setup data

* Add convenience wrappers for skipdata_setup

* Uncomment skipdata_setup tests

* Add alternate usage variants to test_skipdata.py

* document getter
This commit is contained in:
Семён Марьясин 2018-12-31 10:42:44 +03:00 committed by Nguyen Anh Quynh
parent 8f4cc4e80d
commit 6c54814d25
2 changed files with 40 additions and 7 deletions

View File

@ -828,6 +828,7 @@ class Cs(object):
# default mnemonic for SKIPDATA
self._skipdata_mnem = ".byte"
self._skipdata_cb = (None, None)
self._skipdata = False
@ -897,7 +898,7 @@ class Cs(object):
@property
def skipdata_setup(self):
return
return (self._skipdata_mnem,) + self._skipdata_cb
@skipdata_setup.setter
@ -905,13 +906,37 @@ class Cs(object):
_skipdata_opt = _cs_opt_skipdata()
_mnem, _cb, _ud = opt
_skipdata_opt.mnemonic = _mnem.encode()
_skipdata_opt.callback = CS_SKIPDATA_CALLBACK(_cb)
_skipdata_opt.callback = CS_SKIPDATA_CALLBACK(_cb or 0)
_skipdata_opt.user_data = ctypes.cast(_ud, ctypes.c_void_p)
status = _cs.cs_option(self.csh, CS_OPT_SKIPDATA_SETUP, ctypes.cast(ctypes.byref(_skipdata_opt), ctypes.c_void_p))
if status != CS_ERR_OK:
raise CsError(status)
self._skipdata_opt = _skipdata_opt
self._skipdata_mnem = _mnem
self._skipdata_cb = (_cb, _ud)
@property
def skipdata_mnem(self):
return self._skipdata_mnem
@skipdata_mnem.setter
def skipdata_mnem(self, mnem):
self.skipdata_setup = (mnem,) + self._skipdata_cb
@property
def skipdata_cb(self):
return self._skipdata_cb
@skipdata_cb.setter
def skipdata_cb(self, val):
if not isinstance(val, tuple):
val = (val, None)
func, data = val
self.skipdata_setup = (self._skipdata_mnem, func, data)
# customize instruction mnemonic

View File

@ -39,13 +39,21 @@ def test_class():
md.skipdata = True
# Default "data" instruction's name is ".byte". To rename it to "db", just uncomment
# Default "data" instruction's name is ".byte". To rename it to "db", just use
# the code below.
# md.skipdata_setup = ("db", None, None)
md.skipdata_setup = ("db", None, None)
# NOTE: This example ignores SKIPDATA's callback (first None) & user_data (second None)
# Can also use dedicated setter
md.skipdata_mnem = 'db'
# To customize the SKIPDATA callback, uncomment the line below.
# md.skipdata_setup = (".db", testcb, None)
# To customize the SKIPDATA callback, use the line below.
md.skipdata_setup = (".db", testcb, None)
# Or use dedicated setter with custom parameter
md.skipdata_cb = (testcb, 42)
# Or provide just a function
md.skipdata_cb = testcb
# Note that reading this property will always return a tuple
assert md.skipdata_cb == (testcb, None), md.skipdata_cb
for insn in md.disasm(code, 0x1000):
#bytes = binascii.hexlify(insn.bytes)