mirror of https://github.com/ConsenSys/mythril
commit
9e1403ab95
@ -1 +0,0 @@ |
||||
from mythril.analysis.symbolic import SymExecWrapper |
@ -1,7 +0,0 @@ |
||||
""" Plugin implementations |
||||
|
||||
This module contains the implementation of some features |
||||
|
||||
- benchmarking |
||||
- pruning |
||||
""" |
@ -1,3 +0,0 @@ |
||||
from mythril.laser.ethereum.plugins.implementations.coverage.coverage_plugin import ( |
||||
InstructionCoveragePlugin, |
||||
) |
@ -1,41 +0,0 @@ |
||||
from mythril.laser.ethereum.plugins.plugin import LaserPlugin |
||||
|
||||
|
||||
class PluginFactory: |
||||
""" The plugin factory constructs the plugins provided with laser """ |
||||
|
||||
@staticmethod |
||||
def build_benchmark_plugin(name: str) -> LaserPlugin: |
||||
""" Creates an instance of the benchmark plugin with the given name """ |
||||
from mythril.laser.ethereum.plugins.implementations.benchmark import ( |
||||
BenchmarkPlugin, |
||||
) |
||||
|
||||
return BenchmarkPlugin(name) |
||||
|
||||
@staticmethod |
||||
def build_mutation_pruner_plugin() -> LaserPlugin: |
||||
""" Creates an instance of the mutation pruner plugin""" |
||||
from mythril.laser.ethereum.plugins.implementations.mutation_pruner import ( |
||||
MutationPruner, |
||||
) |
||||
|
||||
return MutationPruner() |
||||
|
||||
@staticmethod |
||||
def build_instruction_coverage_plugin() -> LaserPlugin: |
||||
""" Creates an instance of the instruction coverage plugin""" |
||||
from mythril.laser.ethereum.plugins.implementations.coverage import ( |
||||
InstructionCoveragePlugin, |
||||
) |
||||
|
||||
return InstructionCoveragePlugin() |
||||
|
||||
@staticmethod |
||||
def build_dependency_pruner_plugin() -> LaserPlugin: |
||||
""" Creates an instance of the mutation pruner plugin""" |
||||
from mythril.laser.ethereum.plugins.implementations.dependency_pruner import ( |
||||
DependencyPruner, |
||||
) |
||||
|
||||
return DependencyPruner() |
@ -1,38 +0,0 @@ |
||||
from mythril.laser.ethereum.svm import LaserEVM |
||||
from mythril.laser.ethereum.plugins.plugin import LaserPlugin |
||||
|
||||
from typing import List |
||||
import logging |
||||
|
||||
log = logging.getLogger(__name__) |
||||
|
||||
|
||||
class LaserPluginLoader: |
||||
""" |
||||
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, symbolic_vm: LaserEVM) -> None: |
||||
""" Initializes the plugin loader |
||||
|
||||
:param symbolic_vm: symbolic virtual machine to load plugins for |
||||
""" |
||||
self.symbolic_vm = symbolic_vm |
||||
self.laser_plugins = [] # type: List[LaserPlugin] |
||||
|
||||
def load(self, laser_plugin: LaserPlugin) -> None: |
||||
""" Loads the plugin |
||||
|
||||
:param laser_plugin: plugin that will be loaded in the symbolic virtual machine |
||||
""" |
||||
log.info("Loading plugin: {}".format(str(laser_plugin))) |
||||
laser_plugin.initialize(self.symbolic_vm) |
||||
self.laser_plugins.append(laser_plugin) |
||||
|
||||
def is_enabled(self, laser_plugin: LaserPlugin) -> bool: |
||||
""" Returns whether the plugin is loaded in the symbolic_vm |
||||
|
||||
:param laser_plugin: plugin that will be checked |
||||
""" |
||||
return laser_plugin in self.laser_plugins |
@ -0,0 +1,21 @@ |
||||
from mythril.laser.plugin.interface import LaserPlugin |
||||
|
||||
from abc import ABC, abstractmethod |
||||
from typing import Optional |
||||
|
||||
|
||||
class PluginBuilder(ABC): |
||||
""" PluginBuilder |
||||
|
||||
The plugin builder interface enables construction of Laser plugins |
||||
""" |
||||
|
||||
plugin_name = "Default Plugin Name" |
||||
|
||||
def __init__(self): |
||||
self.enabled = True |
||||
|
||||
@abstractmethod |
||||
def __call__(self, *args, **kwargs) -> LaserPlugin: |
||||
"""Constructs the plugin""" |
||||
pass |
@ -0,0 +1,68 @@ |
||||
import logging |
||||
from typing import Dict, List, Optional |
||||
|
||||
from mythril.laser.ethereum.svm import LaserEVM |
||||
from mythril.laser.plugin.builder import PluginBuilder |
||||
from mythril.support.support_utils import Singleton |
||||
|
||||
log = logging.getLogger(__name__) |
||||
|
||||
|
||||
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] |
||||
|
||||
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.plugin_name}") |
||||
if plugin_builder.plugin_name in self.laser_plugin_builders: |
||||
log.warning( |
||||
f"Laser plugin with name {plugin_builder.plugin_name} was already loaded, skipping..." |
||||
) |
||||
return |
||||
self.laser_plugin_builders[plugin_builder.plugin_name] = plugin_builder |
||||
|
||||
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 |
||||
|
||||
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 |
||||
|
||||
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() |
||||
plugin.initialize(symbolic_vm) |
@ -0,0 +1,11 @@ |
||||
""" Plugin implementations |
||||
|
||||
This module contains the implementation of some features |
||||
|
||||
- benchmarking |
||||
- pruning |
||||
""" |
||||
from mythril.laser.plugin.plugins.benchmark import BenchmarkPluginBuilder |
||||
from mythril.laser.plugin.plugins.coverage.coverage_plugin import CoveragePluginBuilder |
||||
from mythril.laser.plugin.plugins.dependency_pruner import DependencyPrunerBuilder |
||||
from mythril.laser.plugin.plugins.mutation_pruner import MutationPrunerBuilder |
@ -0,0 +1,3 @@ |
||||
from mythril.laser.plugin.plugins.coverage.coverage_plugin import ( |
||||
InstructionCoveragePlugin, |
||||
) |
@ -1,8 +1,6 @@ |
||||
from mythril.laser.ethereum.strategy import BasicSearchStrategy |
||||
from mythril.laser.ethereum.state.global_state import GlobalState |
||||
from mythril.laser.ethereum.plugins.implementations.coverage import ( |
||||
InstructionCoveragePlugin, |
||||
) |
||||
from mythril.laser.plugin.plugins.coverage import InstructionCoveragePlugin |
||||
|
||||
|
||||
class CoverageStrategy(BasicSearchStrategy): |
Loading…
Reference in new issue