import sys from slither.slither import Slither if len(sys.argv) != 2: print("python functions_called.py functions_called.sol") sys.exit(-1) # Init slither slither = Slither(sys.argv[1]) # Get the contract contract = slither.get_contract_from_name("Contract") # Get the variable entry_point = contract.get_function_from_signature("entry_point()") all_calls = entry_point.all_internal_calls() all_calls_formated = [f.canonical_name for f in all_calls] # Print the result print( "From entry_point the functions reached are {}".format(all_calls_formated))
def check_call(func, taints): for node in func.nodes: for ir in node.irs: if isinstance(ir, HighLevelCall): if ir.destination in taints: print('Call to tainted address found in {}'.format( function.name)) if __name__ == "__main__": if len(sys.argv) != 2: print('python.py taint.py taint.sol') exit(-1) # Init slither slither = Slither(sys.argv[1]) initial_taint = [SolidityVariableComposed('msg.sender')] initial_taint += [SolidityVariableComposed('msg.value')] KEY = 'TAINT' prev_taints = [] slither.context[KEY] = initial_taint while (set(prev_taints) != set(slither.context[KEY])): prev_taints = slither.context[KEY] for contract in slither.contracts: for function in contract.functions: print('Function {}'.format(function.name)) slither.context[KEY] = list( set(slither.context[KEY] + function.parameters))
import sys from slither.slither import Slither if len(sys.argv) != 2: print("python export_dominator_tree_to_dot.py contract.sol") sys.exit(-1) # Init slither slither = Slither(sys.argv[1]) for contract in slither.contracts: for function in list(contract.functions) + list(contract.modifiers): filename = f"{sys.argv[1]}-{contract.name}-{function.full_name}_dom.dot" print(f"Export {filename}") function.dominator_tree_to_dot(filename)
def analyze(fname): res = { 'fname': fname, 'external_func': Counter(), 'external_call': Counter(), 'internal_func': Counter(), 'internal_call': Counter(), 'library_func': Counter(), 'library_call': Counter(), 'internal_state_change_call': Counter(), 'internal_state_change_func': Counter(), 'writes_after_internal_call': False, 'writes_after_internal_state_change_call': False, 'writes_after_external_call': False, 'writes_after_non_library_call': False, 'reads_after_internal_call': False, 'reads_after_internal_state_change_call': False, 'reads_after_external_call': False, 'reads_after_non_library_call': False, 'external_call_num': 0, 'external_call_checked_num': 0, 'call_graph': {}, 'success': False } try: slither = Slither(fname, disable_solc_warnings=True) for c in slither.contracts: # print('Contract: {}'.format(c.name)) state_changing_func_names = set(func.name for func in c.functions if len(func.all_state_variables_written()) > 0) for function in c.functions: record_call_set(res, 'external', function.all_high_level_calls()) record_call_set(res, 'internal', [(declarer(c, f), f) for f in function.all_internal_calls()]) record_call_set(res, 'internal_state_change', [(declarer(c, f), f) for f in function.all_internal_calls() if f.name in state_changing_func_names]) record_call_set(res, 'library', function.all_library_calls()) this_func = (c.name, signature(function)) res['call_graph'][this_func] = set() for con, func in function.all_high_level_calls(): if func is not None: res['call_graph'][this_func].add((str(con), signature(func))) for func in function.all_internal_calls(): if func is not None and isinstance(func, Function): res['call_graph'][this_func].add((str(func.contract_declarer), signature(func))) res['writes_after_internal_call'] |= do_explore(internal_calls, lambda n: n.state_variables_written, function.entry_point) res['writes_after_internal_state_change_call'] |= do_explore(internal_state_change_calls(state_changing_func_names), lambda n: n.state_variables_written, function.entry_point) res['writes_after_external_call'] |= do_explore(external_calls, lambda n: n.state_variables_written, function.entry_point) res['writes_after_non_library_call'] |= do_explore(non_library_calls, lambda n: n.state_variables_written, function.entry_point) res['reads_after_internal_call'] |= do_explore(internal_calls, lambda n: n.state_variables_read, function.entry_point) res['reads_after_internal_state_change_call'] |= do_explore(internal_state_change_calls(state_changing_func_names), lambda n: n.state_variables_read, function.entry_point) res['reads_after_external_call'] |= do_explore(external_calls, lambda n: n.state_variables_read, function.entry_point) res['reads_after_non_library_call'] |= do_explore(non_library_calls, lambda n: n.state_variables_read, function.entry_point) for node in function.nodes: num = len(node.high_level_calls) if num > 0: res['external_call_num'] += num if node.is_conditional(): res['external_call_checked_num'] += num # print('External calls: {}'.format(external_calls)) res['success'] = True except SlitherError as e: # raise e pass for k in res: if isinstance(res[k], Counter): res[k] = dict(res[k]) print(res)