Fix context saving (#1335)

* Fix context size

* Make UcContext convertible to bytes and picklable

Fix when updaing context

* Test context pickling

* Fix double free when the context is pickled from bytes
This commit is contained in:
lazymio
2020-09-24 00:53:23 +08:00
committed by GitHub
parent 21235916b9
commit 4441394258
3 changed files with 39 additions and 9 deletions

View File

@ -604,7 +604,7 @@ class Uc(object):
return context
def context_update(self, context):
status = _uc.uc_context_save(self._uch, context)
status = _uc.uc_context_save(self._uch, context.context)
if status != uc.UC_ERR_OK:
raise UcError(status)
@ -628,16 +628,40 @@ class Uc(object):
_uc.uc_free(regions)
class UcContext(ctypes.Structure):
class UcContext:
def __init__(self, h):
self.context = uc_context()
status = _uc.uc_context_alloc(h, ctypes.byref(self.context))
self._context = uc_context()
self._size = _uc.uc_context_size(h)
self._to_free = True
status = _uc.uc_context_alloc(h, ctypes.byref(self._context))
if status != uc.UC_ERR_OK:
raise UcError(status)
@property
def context(self):
return self._context
@property
def size(self):
return self._size
# Make UcContext picklable
def __getstate__(self):
return (bytes(self), self.size)
def __setstate__(self, state):
self._size = state[1]
self._context = ctypes.cast(ctypes.create_string_buffer(state[0], self._size), uc_context)
# __init__ won'e be invoked, so we are safe to set it here.
self._to_free = False
def __bytes__(self):
return ctypes.string_at(self.context, self.size)
def __del__(self):
_uc.uc_free(self.context)
# We need this property since we shouldn't free it if the object is constructed from pickled bytes.
if self._to_free:
_uc.uc_free(self._context)
# print out debugging info