Merge pull request #1342 from ConsenSys/feature/enable_detection_plugins

Enable detection plugins
ether_transfer
Bernhard Mueller 5 years ago committed by GitHub
commit c571fa287f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      mythril/__init__.py
  2. 23
      mythril/plugin/discovery.py
  3. 1
      mythril/plugin/interface.py
  4. 22
      mythril/plugin/loader.py

@ -1,6 +1,14 @@
# We use RsT document formatting in docstring. For example :param to mark parameters. # We use RsT document formatting in docstring. For example :param to mark parameters.
# See PEP 287 # See PEP 287
__docformat__ = "restructuredtext" __docformat__ = "restructuredtext"
import logging
# Accept mythril.VERSION to get mythril's current version number # Accept mythril.VERSION to get mythril's current version number
from .__version__ import __version__ as VERSION # NOQA from .__version__ import __version__ as VERSION # NOQA
from mythril.plugin.loader import MythrilPluginLoader
log = logging.getLogger(__name__)
# Initialise core Mythril Components
log.info("Initializing core Mythril components")
_ = MythrilPluginLoader()

@ -2,6 +2,8 @@ import pkg_resources
from mythril.support.support_utils import Singleton from mythril.support.support_utils import Singleton
from mythril.plugin.interface import MythrilPlugin from mythril.plugin.interface import MythrilPlugin
from typing import List
class PluginDiscovery(object, metaclass=Singleton): class PluginDiscovery(object, metaclass=Singleton):
"""PluginDiscovery class """PluginDiscovery class
@ -9,7 +11,7 @@ class PluginDiscovery(object, metaclass=Singleton):
This plugin implements the logic to discover and build plugins in installed python packages This plugin implements the logic to discover and build plugins in installed python packages
""" """
# Installed plugins structure. Retreives all modules that have an entry point for mythril.plugins # Installed plugins structure. Retrieves all modules that have an entry point for mythril.plugins
_installed_plugins = { _installed_plugins = {
entry_point.name: entry_point.load() entry_point.name: entry_point.load()
for entry_point in pkg_resources.iter_entry_points("mythril.plugins") for entry_point in pkg_resources.iter_entry_points("mythril.plugins")
@ -26,7 +28,22 @@ class PluginDiscovery(object, metaclass=Singleton):
plugin = self._installed_plugins.get(plugin_name) plugin = self._installed_plugins.get(plugin_name)
if plugin is None or not isinstance(plugin, MythrilPlugin): if plugin is None or not issubclass(plugin, MythrilPlugin):
raise ValueError(f"No valid plugin was found for {plugin_name}") raise ValueError(f"No valid plugin was found for {plugin_name}")
return plugin return plugin()
def get_plugins(self, default_enabled=None) -> List[str]:
""" Gets a list of installed mythril plugins
:param default_enabled: Select plugins that are enabled by default
:return: List of plugin names
"""
if default_enabled is None:
return list(self._installed_plugins.keys())
return [
plugin_name
for plugin_name, plugin_class in self._installed_plugins.items()
if plugin_class.plugin_default_enabled == default_enabled
]

@ -12,6 +12,7 @@ class MythrilPlugin:
""" """
author = "Default Author" author = "Default Author"
name = "Plugin Name"
plugin_license = "All rights reserved." plugin_license = "All rights reserved."
plugin_type = "Mythril Plugin" plugin_type = "Mythril Plugin"
plugin_version = "0.0.1 " plugin_version = "0.0.1 "

@ -1,8 +1,11 @@
from mythril.analysis.module import DetectionModule from mythril.analysis.module import DetectionModule
from mythril.plugin.interface import MythrilCLIPlugin, MythrilPlugin from mythril.plugin.interface import MythrilCLIPlugin, MythrilPlugin
from mythril.plugin.discovery import PluginDiscovery
from mythril.support.support_utils import Singleton from mythril.support.support_utils import Singleton
from mythril.analysis.module.loader import ModuleLoader
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -19,12 +22,15 @@ class MythrilPluginLoader(object, metaclass=Singleton):
""" """
def __init__(self): def __init__(self):
log.info("Initializing mythril plugin loader")
self.loaded_plugins = [] self.loaded_plugins = []
self._load_default_enabled()
def load(self, plugin: MythrilPlugin): def load(self, plugin: MythrilPlugin):
"""Loads the passed plugin""" """Loads the passed plugin"""
if not isinstance(plugin, MythrilPlugin): if not isinstance(plugin, MythrilPlugin):
raise ValueError("Passed plugin is not of type MythrilPlugin") raise ValueError("Passed plugin is not of type MythrilPlugin")
logging.info(f"Loading plugin: {plugin.name}")
log.info(f"Loading plugin: {str(plugin)}") log.info(f"Loading plugin: {str(plugin)}")
@ -34,6 +40,16 @@ class MythrilPluginLoader(object, metaclass=Singleton):
raise UnsupportedPluginType("Passed plugin type is not yet supported") raise UnsupportedPluginType("Passed plugin type is not yet supported")
self.loaded_plugins.append(plugin) self.loaded_plugins.append(plugin)
log.info(f"Finished loading plugin: {plugin.name}")
def _load_detection_module(self, plugin: DetectionModule):
pass @staticmethod
def _load_detection_module(plugin: DetectionModule):
"""Loads the passed detection module"""
log.info(f"Loading detection module: {plugin.name}")
ModuleLoader().register_module(plugin)
def _load_default_enabled(self):
log.info("Loading installed analysis modules that are enabled by default")
for plugin_name in PluginDiscovery().get_plugins(default_enabled=True):
plugin = PluginDiscovery().build_plugin(plugin_name)
self.load(plugin)

Loading…
Cancel
Save