예제 #1
0
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))
예제 #2
0
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))
예제 #3
0
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)
예제 #4
0
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)