def fire_lasers( self, modules: Optional[List[str]] = None, transaction_count: Optional[int] = None, ) -> Report: """ :param modules: The analysis modules which should be executed :param transaction_count: The amount of transactions to be executed :return: The Report class which contains the all the issues/vulnerabilities """ all_issues = [] # type: List[Issue] SolverStatistics().enabled = True exceptions = [] for contract in self.contracts: StartTime() # Reinitialize start time for new contracts try: sym = SymExecWrapper( contract, self.address, self.strategy, dynloader=DynLoader( self.eth, storage_loading=self.onchain_storage_access, contract_loading=self.dynld, ), max_depth=self.max_depth, execution_timeout=self.execution_timeout, loop_bound=self.loop_bound, create_timeout=self.create_timeout, transaction_count=transaction_count, modules=modules, compulsory_statespace=False, enable_iprof=self.enable_iprof, disable_dependency_pruning=self.disable_dependency_pruning, ) issues = fire_lasers(sym, modules) except KeyboardInterrupt: log.critical("Keyboard Interrupt") issues = retrieve_callback_issues(modules) except Exception: log.critical( "Exception occurred, aborting analysis. Please report this issue to the Mythril GitHub page.\n" + traceback.format_exc()) issues = retrieve_callback_issues(modules) exceptions.append(traceback.format_exc()) for issue in issues: issue.add_code_info(contract) all_issues += issues log.info("Solver statistics: \n{}".format(str(SolverStatistics()))) source_data = Source() source_data.get_source_from_contracts_list(self.contracts) # Finally, output the results report = Report(contracts=self.contracts, exceptions=exceptions) for issue in all_issues: report.append_issue(issue) return report
def __init__(self, contracts=None, exceptions=None): """ :param contracts: :param exceptions: """ self.issues = {} self.solc_version = "" self.meta = {} self.source = Source() self.source.get_source_from_contracts_list(contracts) self.exceptions = exceptions or []
def __init__(self, verbose=False, contracts=None, exceptions=None): """ :param verbose: """ self.issues = {} self.verbose = verbose self.solc_version = "" self.meta = {} self.source = Source() self.source.get_source_from_contracts_list(contracts) self.exceptions = exceptions or []
def __init__(self, verbose=False, source=None): """ :param verbose: """ self.issues = {} self.verbose = verbose self.solc_version = "" self.meta = {} self.source = source or Source()
def fire_lasers( self, strategy, contracts=None, address=None, modules=None, verbose_report=False, max_depth=None, execution_timeout=None, create_timeout=None, transaction_count=None, enable_iprof=False, ): """ :param strategy: :param contracts: :param address: :param modules: :param verbose_report: :param max_depth: :param execution_timeout: :param create_timeout: :param transaction_count: :return: """ all_issues = [] for contract in contracts or self.contracts: try: sym = SymExecWrapper( contract, address, strategy, dynloader=DynLoader( self.eth, storage_loading=self.onchain_storage_access, contract_loading=self.dynld, ), max_depth=max_depth, execution_timeout=execution_timeout, create_timeout=create_timeout, transaction_count=transaction_count, modules=modules, compulsory_statespace=False, enable_iprof=enable_iprof, ) issues = fire_lasers(sym, modules) except KeyboardInterrupt: log.critical("Keyboard Interrupt") issues = retrieve_callback_issues(modules) except Exception: log.critical( "Exception occurred, aborting analysis. Please report this issue to the Mythril GitHub page.\n" + traceback.format_exc()) issues = retrieve_callback_issues(modules) for issue in issues: issue.add_code_info(contract) all_issues += issues source_data = Source() source_data.get_source_from_contracts_list(self.contracts) # Finally, output the results report = Report(verbose_report, source_data) for issue in all_issues: report.append_issue(issue) return report
class Report: """A report containing the content of multiple issues.""" environment = Environment(loader=PackageLoader("mythril.analysis"), trim_blocks=True) def __init__(self, contracts=None, exceptions=None): """ :param contracts: :param exceptions: """ self.issues = {} self.solc_version = "" self.meta = {} self.source = Source() self.source.get_source_from_contracts_list(contracts) self.exceptions = exceptions or [] def sorted_issues(self): """ :return: """ issue_list = [issue.as_dict for key, issue in self.issues.items()] return sorted(issue_list, key=operator.itemgetter("address", "title")) def append_issue(self, issue): """ :param issue: """ m = hashlib.md5() m.update((issue.contract + str(issue.address) + issue.title).encode("utf-8")) issue.resolve_function_names() self.issues[m.digest()] = issue def as_text(self): """ :return: """ name = self._file_name() template = Report.environment.get_template("report_as_text.jinja2") return template.render(filename=name, issues=self.sorted_issues()) def as_json(self): """ :return: """ result = { "success": True, "error": None, "issues": self.sorted_issues() } return json.dumps(result, sort_keys=True) def _get_exception_data(self) -> dict: if not self.exceptions: return {} logs = [] # type: List[Dict] for exception in self.exceptions: logs += [{"level": "error", "hidden": "true", "msg": exception}] return {"logs": logs} def as_swc_standard_format(self): """Format defined for integration and correlation. :return: """ _issues = [] for key, issue in self.issues.items(): idx = self.source.get_source_index(issue.bytecode_hash) try: title = SWC_TO_TITLE[issue.swc_id] except KeyError: title = "Unspecified Security Issue" extra = {"discoveryTime": int(issue.discovery_time * 10**9)} if issue.transaction_sequence_jsonv2: extra["testCases"] = [issue.transaction_sequence_jsonv2] _issues.append({ "swcID": "SWC-" + issue.swc_id, "swcTitle": title, "description": { "head": issue.description_head, "tail": issue.description_tail, }, "severity": issue.severity, "locations": [{ "sourceMap": "%d:1:%d" % (issue.address, idx) }], "extra": extra, }) meta_data = self._get_exception_data() result = [{ "issues": _issues, "sourceType": self.source.source_type, "sourceFormat": self.source.source_format, "sourceList": self.source.source_list, "meta": meta_data, }] return json.dumps(result, sort_keys=True) def as_markdown(self): """ :return: """ filename = self._file_name() template = Report.environment.get_template("report_as_markdown.jinja2") return template.render(filename=filename, issues=self.sorted_issues()) def _file_name(self): """ :return: """ if len(self.issues.values()) > 0: return list(self.issues.values())[0].filename