mirror of https://github.com/crytic/slither
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.5 KiB
73 lines
2.5 KiB
import os
|
|
import argparse
|
|
from slither import Slither
|
|
from slither.utils.colors import red
|
|
import logging
|
|
from .possible_paths import find_target_paths, resolve_functions, ResolveFunctionException
|
|
from crytic_compile import cryticparser
|
|
|
|
logging.basicConfig()
|
|
logging.getLogger("Slither").setLevel(logging.INFO)
|
|
|
|
def parse_args():
|
|
"""
|
|
Parse the underlying arguments for the program.
|
|
:return: Returns the arguments for the program.
|
|
"""
|
|
parser = argparse.ArgumentParser(description='PossiblePaths',
|
|
usage='possible_paths.py filename [contract.function targets]')
|
|
|
|
parser.add_argument('filename',
|
|
help='The filename of the contract or truffle directory to analyze.')
|
|
|
|
parser.add_argument('targets', nargs='+')
|
|
|
|
cryticparser.init(parser)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
# ------------------------------
|
|
# PossiblePaths.py
|
|
# Usage: python3 possible_paths.py filename targets
|
|
# Example: python3 possible_paths.py contract.sol contract1.function1 contract2.function2 contract3.function3
|
|
# ------------------------------
|
|
# Parse all arguments
|
|
args = parse_args()
|
|
|
|
# Perform slither analysis on the given filename
|
|
slither = Slither(args.filename, **vars(args))
|
|
|
|
try:
|
|
targets = resolve_functions(slither, args.targets)
|
|
except ResolveFunctionException as r:
|
|
print(red(r))
|
|
exit(-1)
|
|
|
|
# Print out all target functions.
|
|
print(f"Target functions:")
|
|
for target in targets:
|
|
print(f"- {target.contract.name}.{target.full_name}")
|
|
print("\n")
|
|
|
|
# Obtain all paths which reach the target functions.
|
|
reaching_paths = find_target_paths(slither, targets)
|
|
reaching_functions = set([y for x in reaching_paths for y in x if y not in targets])
|
|
|
|
# Print out all function names which can reach the targets.
|
|
print(f"The following functions reach the specified targets:")
|
|
for function_desc in sorted([f"{f.contract.name}.{f.full_name}" for f in reaching_functions]):
|
|
print(f"- {function_desc}")
|
|
print("\n")
|
|
|
|
# Format all function paths.
|
|
reaching_paths_str = [' -> '.join([f"{f.contract.name}.{f.full_name}" for f in reaching_path]) for reaching_path in reaching_paths]
|
|
|
|
# Print a sorted list of all function paths which can reach the targets.
|
|
print(f"The following paths reach the specified targets:")
|
|
for reaching_path in sorted(reaching_paths_str):
|
|
print(f"{reaching_path}\n")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|