Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle alternative IR and CFG #17

Merged
merged 2 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions slither/core/slither_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def __init__(self):
self._show_ignored_findings = False

self._compilation_units: List[SlitherCompilationUnit] = []
self._certik_compilation_units: List[SlitherCompilationUnit] = []

self._contracts: List[Contract] = []
self._contracts_derived: List[Contract] = []
Expand All @@ -90,6 +91,14 @@ def __init__(self):
def compilation_units(self) -> List[SlitherCompilationUnit]:
return list(self._compilation_units)

@property
def certik_compilation_units(self) -> List[SlitherCompilationUnit]:
"""
The list of all compilation units generated to include the CertiK version
of the CFG and IR.
"""
return list(self._certik_compilation_units)

def add_compilation_unit(self, compilation_unit: SlitherCompilationUnit):
self._compilation_units.append(compilation_unit)

Expand Down
7 changes: 7 additions & 0 deletions slither/detectors/abstract_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ def _log(self, info: str) -> None:
if self.logger:
self.logger.info(self.color(info))

@property
def uses_certik_ir() -> bool:
"""
Does this detector expect the CertiK version of SlithIR?
"""
return False

@abc.abstractmethod
def _detect(self) -> List[Output]:
"""TODO Documentation"""
Expand Down
1 change: 1 addition & 0 deletions slither/printers/all_printers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .inheritance.inheritance_graph import PrinterInheritanceGraph
from .call.call_graph import PrinterCallGraph
from .functions.authorization import PrinterWrittenVariablesAndAuthorization
from .summary.certikir import PrinterCertiKIR
from .summary.slithir import PrinterSlithIR
from .summary.slithir_ssa import PrinterSlithIRSSA
from .summary.human_summary import PrinterHumanSummary
Expand Down
17 changes: 17 additions & 0 deletions slither/printers/summary/certikir.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""
Module printing summary of the contract using CertiK IR
"""
from typing import List

from slither.printers.summary.slithir import PrinterSlithIR
from slither.core.compilation_unit import SlitherCompilationUnit

class PrinterCertiKIR(PrinterSlithIR):
ARGUMENT = "certikir"
HELP = "Print the Certik IR representation of the functions"

WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#slithir"

@property
def compilation_units(self) -> List[SlitherCompilationUnit]:
return self.slither.certik_compilation_units
12 changes: 10 additions & 2 deletions slither/printers/summary/slithir.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"""
from slither.core.declarations import Function
from slither.printers.abstract_printer import AbstractPrinter

from typing import List
from slither.core.compilation_unit import SlitherCompilationUnit

def _print_function(function: Function) -> str:
txt = ""
Expand All @@ -26,6 +27,13 @@ class PrinterSlithIR(AbstractPrinter):

WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#slithir"

@property
def compilation_units(self) -> List[SlitherCompilationUnit]:
"""
List of compilation units to print the IR for
"""
return self.slither.compilation_units

def output(self, _filename):
"""
_filename is not used
Expand All @@ -34,7 +42,7 @@ def output(self, _filename):
"""

txt = ""
for compilation_unit in self.slither.compilation_units:
for compilation_unit in self.compilation_units:
for contract in compilation_unit.contracts:
if contract.is_top_level:
continue
Expand Down
25 changes: 21 additions & 4 deletions slither/slither.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging

from typing import Union, List, ValuesView, Type, Dict

from crytic_compile import CryticCompile, InvalidCompilation
Expand Down Expand Up @@ -93,16 +94,25 @@ def __init__(self, target: Union[str, CryticCompile], **kwargs):
except InvalidCompilation as e:
# pylint: disable=raise-missing-from
raise SlitherError(f"Invalid compilation: \n{str(e)}")

for compilation_unit in crytic_compile.compilation_units.values():
compilation_unit_slither = SlitherCompilationUnit(self, compilation_unit)
self._compilation_units.append(compilation_unit_slither)
parser = SlitherCompilationUnitSolc(compilation_unit_slither)
parser = SlitherCompilationUnitSolc(compilation_unit_slither, generates_certik_ir = False)
self._parsers.append(parser)

new_compilation_unit_slither = SlitherCompilationUnit(self, compilation_unit)
self._certik_compilation_units.append(new_compilation_unit_slither)
new_parser = SlitherCompilationUnitSolc(new_compilation_unit_slither, generates_certik_ir = True)
self._parsers.append(new_parser)

for path, ast in compilation_unit.asts.items():
parser.parse_top_level_from_loaded_json(ast, path)
new_parser.parse_top_level_from_loaded_json(ast, path)
self.add_source_code(path)

_update_file_scopes(compilation_unit_slither.scopes.values())
_update_file_scopes(new_compilation_unit_slither.scopes.values())

if kwargs.get("generate_patches", False):
self.generate_patches = True
Expand Down Expand Up @@ -186,9 +196,16 @@ def register_detector(self, detector_class: Type[AbstractDetector]) -> None:
"""
_check_common_things("detector", detector_class, AbstractDetector, self._detectors)

for compilation_unit in self.compilation_units:
instance = detector_class(compilation_unit, self, logger_detector)
self._detectors.append(instance)
if detector_class.uses_certik_ir:
for compilation_unit in self.certik_compilation_units:
instance = detector_class(compilation_unit, self, logger_detector)
self._detectors.append(instance)
else:
for compilation_unit in self.compilation_units:
instance = detector_class(compilation_unit, self, logger_detector)
self._detectors.append(instance)



def register_printer(self, printer_class: Type[AbstractPrinter]) -> None:
"""
Expand Down
10 changes: 9 additions & 1 deletion slither/solc_parsing/slither_compilation_unit_solc.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ def _handle_import_aliases(

class SlitherCompilationUnitSolc:
# pylint: disable=no-self-use,too-many-instance-attributes
def __init__(self, compilation_unit: SlitherCompilationUnit):
def __init__(self, compilation_unit: SlitherCompilationUnit, generates_certik_ir: bool):
duckki marked this conversation as resolved.
Show resolved Hide resolved
super().__init__()

self._contracts_by_id: Dict[int, ContractSolc] = {}
self._parsed = False
self._analyzed = False
self._generates_certik_ir = generates_certik_ir

self._underlying_contract_to_parser: Dict[Contract, ContractSolc] = {}
self._structures_top_level_parser: List[StructureTopLevelSolc] = []
Expand All @@ -84,6 +85,13 @@ def __init__(self, compilation_unit: SlitherCompilationUnit):
def compilation_unit(self) -> SlitherCompilationUnit:
return self._compilation_unit

@property
def generates_certik_ir(self) -> bool:
"""
Does this parser generate the CertiK version of SlithIR?
"""
return self._generates_certik_ir

@property
def all_functions_and_modifiers_parser(self) -> List[FunctionSolc]:
return self._all_functions_and_modifier_parser
Expand Down