Source code for mythril.laser.plugin.loader

import logging
from typing import Dict, List, Optional

from mythril.laser.ethereum.svm import LaserEVM
from mythril.laser.plugin.interface import LaserPlugin
from mythril.laser.plugin.builder import PluginBuilder
from mythril.support.support_utils import Singleton

log = logging.getLogger(__name__)


[docs]class LaserPluginLoader(object, metaclass=Singleton): """ The LaserPluginLoader is used to abstract the logic relating to plugins. Components outside of laser thus don't have to be aware of the interface that plugins provide """ def __init__(self) -> None: """Initializes the plugin loader""" self.laser_plugin_builders = {} # type: Dict[str, PluginBuilder] self.plugin_args = {} # type: Dict[str, Dict] self.plugin_list = {} # type: Dict[str, LaserPlugin]
[docs] def add_args(self, plugin_name, **kwargs): self.plugin_args[plugin_name] = kwargs
[docs] def load(self, plugin_builder: PluginBuilder) -> None: """Enables a Laser Plugin :param plugin_builder: Builder that constructs the plugin """ log.info(f"Loading laser plugin: {plugin_builder.name}") if plugin_builder.name in self.laser_plugin_builders: log.warning( f"Laser plugin with name {plugin_builder.name} was already loaded, skipping..." ) return self.laser_plugin_builders[plugin_builder.name] = plugin_builder
[docs] def is_enabled(self, plugin_name: str) -> bool: """Returns whether the plugin is loaded in the symbolic_vm :param plugin_name: Name of the plugin to check """ if plugin_name not in self.laser_plugin_builders: return False else: return self.laser_plugin_builders[plugin_name].enabled
[docs] def enable(self, plugin_name: str): if plugin_name not in self.laser_plugin_builders: return ValueError(f"Plugin with name: {plugin_name} was not loaded") self.laser_plugin_builders[plugin_name].enabled = True
[docs] def instrument_virtual_machine( self, symbolic_vm: LaserEVM, with_plugins: Optional[List[str]] ): """Load enabled plugins into the passed symbolic virtual machine :param symbolic_vm: The virtual machine to instrument the plugins with :param with_plugins: Override the globally enabled/disabled builders and load all plugins in the list """ for plugin_name, plugin_builder in self.laser_plugin_builders.items(): enabled = ( plugin_builder.enabled if not with_plugins else plugin_name in with_plugins ) if not enabled: continue log.info(f"Instrumenting symbolic vm with plugin: {plugin_name}") plugin = plugin_builder(**self.plugin_args.get(plugin_name, {})) plugin.initialize(symbolic_vm) self.plugin_list[plugin_name] = plugin