def __init__(self, uri, state_serialization_method='pickle'): assert self.__class__ != Store, "The Store class can not be instantiated (create a subclass)" self.uri = uri self._sub = [] if state_serialization_method == 'pickle': self._serializer = PickleSerializer() else: raise NotImplementedError(f"Pickling method '{state_serialization_method}' not supported.")
def __init__(self, lock, store_or_desc=None): if isinstance(store_or_desc, Store): self._store = store_or_desc else: self._store = Store.fromdescriptor(store_or_desc) self._serializer = PickleSerializer() self._last_id = manager().Value('i', 0) self._lock = lock self._prefix = 'state_' self._suffix = '.pkl'
def __init__(self, procs=10, workspace_url: str = None, policy: str = 'random', initial_state=None): # This was copied from the manticore source, but modified to allow for a custom initial state """ A Manticore EVM manager :param procs:, number of workers to use in the exploration :param workspace_url: workspace folder name :param policy: scheduling priority """ self._accounts = dict() self._serializer = PickleSerializer() self._config_procs = procs # Make the constraint store constraints = ConstraintSet() if initial_state == None: # Make the constraint store constraints = ConstraintSet() # make the ethereum world state world = evm.EVMWorld(constraints) initial_state = State(constraints, world) ManticoreBase.__init__(self, initial_state, workspace_url=workspace_url, policy=policy) self.constraints = ConstraintSet() self.detectors = {} self.metadata: Dict[int, SolidityMetadata] = {} # The following should go to manticore.context so we can use multiprocessing self.context['ethereum'] = {} self.context['ethereum']['_saved_states'] = set() self.context['ethereum']['_final_states'] = set() self.context['ethereum']['_completed_transactions'] = 0 self.context['ethereum']['_sha3_states'] = dict() self.context['ethereum']['_known_sha3'] = set() self._executor.subscribe('did_load_state', self._load_state_callback) self._executor.subscribe('will_terminate_state', self._terminate_state_callback) self._executor.subscribe('did_evm_execute_instruction', self._did_evm_execute_instruction_callback) self._executor.subscribe('did_read_code', self._did_evm_read_code) self._executor.subscribe('on_symbolic_sha3', self._on_symbolic_sha3_callback) self._executor.subscribe('on_concrete_sha3', self._on_concrete_sha3_callback) self.subscribe('will_generate_testcase', self._generate_testcase_callback)
class Store(object): """ A `Store` can save arbitrary keys/values (including states) and file streams. Used for generating output, state saving and state loading. In subclasses: * Implement either save_value/load_value, or save_stream/load_stream, or both. * Define a `store_type` class variable of type str. * This is used as a prefix for a store descriptor """ @classmethod def fromdescriptor(cls, desc): """ Create a :class:`~manticore.core.workspace.Store` instance depending on the descriptor. Valid descriptors: * fs:<path> * redis:<hostname>:<port> * mem: :param str desc: Store descriptor :return: Store instance """ type_, uri = ('fs', None) if desc is None else desc.split(':', 1) for subclass in cls.__subclasses__(): if subclass.store_type == type_: return subclass(uri) raise NotImplementedError( "Storage type '{0}' not supported.".format(type_)) def __init__(self, uri, state_serialization_method='pickle'): assert self.__class__ != Store, "The Store class can not be instantiated (create a subclass)" self.uri = uri self._sub = [] if state_serialization_method == 'pickle': self._serializer = PickleSerializer() else: raise NotImplementedError( "Pickling method '{}' not supported.".format( state_serialization_method)) # save_value/load_value and save_stream/load_stream are implemented in terms of each other. A backing store # can choose the pair it's best optimized for. def save_value(self, key, value): """ Save an arbitrary, serializable `value` under `key`. :param str key: A string identifier under which to store the value. :param value: A serializable value :return: """ with self.save_stream(key) as s: s.write(value) def load_value(self, key, binary=False): """ Load an arbitrary value identified by `key`. :param str key: The key that identifies the value :return: The loaded value """ with self.load_stream(key, binary=binary) as s: return s.read() @contextmanager def save_stream(self, key, binary=False): """ Return a managed file-like object into which the calling code can write arbitrary data. :param key: :return: A managed stream-like object """ s = io.BytesIO() if binary else io.StringIO() yield s self.save_value(key, s.getvalue()) @contextmanager def load_stream(self, key, binary=False): """ Return a managed file-like object from which the calling code can read previously-serialized data. :param key: :return: A managed stream-like object """ value = self.load_value(key, binary=binary) yield io.BytesIO(value) if binary else io.StringIO(value) def save_state(self, state, key): """ Save a state to storage. :param manticore.core.State state: :param str key: :return: """ with self.save_stream(key, binary=True) as f: self._serializer.serialize(state, f) def load_state(self, key, delete=True): """ Load a state from storage. :param key: key that identifies state :rtype: manticore.core.State """ with self.load_stream(key, binary=True) as f: state = self._serializer.deserialize(f) if delete: self.rm(key) return state def rm(self, key): """ Remove value identified by `key` from storage. :param str key: What to remove """ raise NotImplementedError def ls(self, glob_str): """ List all keys in storage :return: """ raise NotImplementedError