Ejemplo n.º 1
0
Archivo: ssa.py Proyecto: gyDBD/slither
def update_lvalue(new_ir, node, local_variables_instances,
                  all_local_variables_instances, state_variables_instances,
                  all_state_variables_instances):
    if isinstance(new_ir, OperationWithLValue):
        lvalue = new_ir.lvalue
        update_through_ref = False
        if isinstance(new_ir, (Assignment, Binary)):
            if isinstance(lvalue, ReferenceVariable):
                update_through_ref = True
                while isinstance(lvalue, ReferenceVariable):
                    lvalue = lvalue.points_to
        if isinstance(lvalue, (LocalIRVariable, StateIRVariable)):
            if isinstance(lvalue, LocalIRVariable):
                new_var = LocalIRVariable(lvalue)
                new_var.index = all_local_variables_instances[
                    lvalue.name].index + 1
                all_local_variables_instances[lvalue.name] = new_var
                local_variables_instances[lvalue.name] = new_var
            else:
                new_var = StateIRVariable(lvalue)
                new_var.index = all_state_variables_instances[
                    lvalue.canonical_name].index + 1
                all_state_variables_instances[lvalue.canonical_name] = new_var
                state_variables_instances[lvalue.canonical_name] = new_var
            if update_through_ref:
                phi_operation = Phi(new_var, {node})
                phi_operation.rvalues = [lvalue]
                node.add_ssa_ir(phi_operation)
            if not isinstance(new_ir.lvalue, ReferenceVariable):
                new_ir.lvalue = new_var
            else:
                to_update = new_ir.lvalue
                while isinstance(to_update.points_to, ReferenceVariable):
                    to_update = to_update.points_to
                to_update.points_to = new_var
Ejemplo n.º 2
0
def initiate_all_local_variables_instances(nodes, local_variables_instances, all_local_variables_instances):
    for node in nodes:
        if node.variable_declaration:
            new_var = LocalIRVariable(node.variable_declaration)
            if new_var.name in all_local_variables_instances:
                new_var.index = all_local_variables_instances[new_var.name].index + 1
            local_variables_instances[node.variable_declaration.name] = new_var
            all_local_variables_instances[node.variable_declaration.name] = new_var
Ejemplo n.º 3
0
Archivo: ssa.py Proyecto: gyDBD/slither
 def get(variable):
     if isinstance(variable, LocalVariable):
         if variable.name in local_variables_instances:
             return local_variables_instances[variable.name]
         new_var = LocalIRVariable(variable)
         local_variables_instances[variable.name] = new_var
         all_local_variables_instances[variable.name] = new_var
         return new_var
     if isinstance(
             variable, StateVariable
     ) and variable.canonical_name in state_variables_instances:
         return state_variables_instances[variable.canonical_name]
     elif isinstance(variable, ReferenceVariable):
         if not variable.index in reference_variables_instances:
             new_variable = ReferenceVariable(variable.node,
                                              index=variable.index)
             if variable.points_to:
                 new_variable.points_to = get(variable.points_to)
             new_variable.set_type(variable.type)
             reference_variables_instances[variable.index] = new_variable
         return reference_variables_instances[variable.index]
     elif isinstance(variable, TemporaryVariable):
         if not variable.index in temporary_variables_instances:
             new_variable = TemporaryVariable(variable.node,
                                              index=variable.index)
             new_variable.set_type(variable.type)
             temporary_variables_instances[variable.index] = new_variable
         return temporary_variables_instances[variable.index]
     return variable
Ejemplo n.º 4
0
def get(variable, local_variables_instances, state_variables_instances, temporary_variables_instances, reference_variables_instances, tuple_variables_instances, all_local_variables_instances):
    # variable can be None
    # for example, on LowLevelCall, ir.lvalue can be none
    if variable is None:
        return None
    if isinstance(variable, LocalVariable):
        if variable.name in local_variables_instances:
            return local_variables_instances[variable.name]
        new_var = LocalIRVariable(variable)
        local_variables_instances[variable.name] = new_var
        all_local_variables_instances[variable.name] = new_var
        return new_var
    if isinstance(variable, StateVariable) and variable.canonical_name in state_variables_instances:
        return state_variables_instances[variable.canonical_name]
    elif isinstance(variable, ReferenceVariable):
        if not variable.index in reference_variables_instances:
            new_variable = ReferenceVariableSSA(variable)
            if variable.points_to:
                new_variable.points_to = get(variable.points_to,
                                             local_variables_instances,
                                             state_variables_instances,
                                             temporary_variables_instances,
                                             reference_variables_instances,
                                             tuple_variables_instances,
                                             all_local_variables_instances)
            new_variable.set_type(variable.type)
            reference_variables_instances[variable.index] = new_variable
        return reference_variables_instances[variable.index]
    elif isinstance(variable, TemporaryVariable):
        if not variable.index in temporary_variables_instances:
            new_variable = TemporaryVariableSSA(variable)
            new_variable.set_type(variable.type)
            temporary_variables_instances[variable.index] = new_variable
        return temporary_variables_instances[variable.index]
    elif isinstance(variable, TupleVariable):
        if not variable.index in tuple_variables_instances:
            new_variable = TupleVariableSSA(variable)
            new_variable.set_type(variable.type)
            tuple_variables_instances[variable.index] = new_variable
        return tuple_variables_instances[variable.index]
    assert isinstance(variable, (Constant,
                                 SolidityVariable,
                                 Contract,
                                 Enum,
                                 SolidityFunction,
                                 Structure,
                                 Function,
                                 Type)) # type for abi.decode(.., t)
    return variable
Ejemplo n.º 5
0
Archivo: ssa.py Proyecto: gyDBD/slither
def last_name(n, var, init_vars):
    candidates = []
    # Todo optimize by creating a variables_ssa_written attribute
    for ir_ssa in n.irs_ssa:
        if isinstance(ir_ssa, OperationWithLValue):
            lvalue = ir_ssa.lvalue
            while isinstance(lvalue, ReferenceVariable):
                lvalue = lvalue.points_to
            if lvalue and lvalue.name == var.name:
                candidates.append(lvalue)
    if n.variable_declaration and n.variable_declaration.name == var.name:
        candidates.append(LocalIRVariable(n.variable_declaration))
    if n.type == NodeType.ENTRYPOINT:
        if var.name in init_vars:
            candidates.append(init_vars[var.name])
    assert candidates
    return max(candidates, key=lambda v: v.index)
Ejemplo n.º 6
0
Archivo: ssa.py Proyecto: gyDBD/slither
def add_ssa_ir(function, all_state_variables_instances):
    '''
        Add SSA version of the IR
    Args:
        function
        all_state_variables_instances
    '''

    if not function.is_implemented:
        return

    init_definition = dict()
    for v in function.parameters + function.returns:
        if v.name:
            init_definition[v.name] = (v, function.entry_point)

    # We only add phi function for state variable at entry node if
    # The state variable is used
    # And if the state variables is written in another function (otherwise its stay at index 0)
    for (_, variable_instance) in all_state_variables_instances.items():
        if is_used_later(function.entry_point, variable_instance):
            # rvalues are fixed in solc_parsing.declaration.function
            function.entry_point.add_ssa_ir(
                Phi(StateIRVariable(variable_instance), set()))

    add_phi_origins(function.entry_point, init_definition, dict())

    for node in function.nodes:
        for (variable, nodes) in node.phi_origins_local_variables.values():
            if len(nodes) < 2:
                continue
            if not is_used_later(node, variable):
                continue
            node.add_ssa_ir(Phi(LocalIRVariable(variable), nodes))
        for (variable, nodes) in node.phi_origins_state_variables.values():
            if len(nodes) < 2:
                continue
            #if not is_used_later(node, variable.name, []):
            #    continue
            node.add_ssa_ir(Phi(StateIRVariable(variable), nodes))

    init_local_variables_instances = dict()
    for v in function.parameters:
        if v.name:
            new_var = LocalIRVariable(v)
            function.add_parameter_ssa(new_var)
            if new_var.is_storage:
                fake_variable = LocalIRVariable(v)
                fake_variable.name = 'STORAGE_' + fake_variable.name
                fake_variable.set_location('reference_to_storage')
                new_var.refers_to = {fake_variable}
                init_local_variables_instances[
                    fake_variable.name] = fake_variable
            init_local_variables_instances[v.name] = new_var

    for v in function.returns:
        if v.name:
            new_var = LocalIRVariable(v)
            function.add_return_ssa(new_var)
            if new_var.is_storage:
                fake_variable = LocalIRVariable(v)
                fake_variable.name = 'STORAGE_' + fake_variable.name
                fake_variable.set_location('reference_to_storage')
                new_var.refers_to = {fake_variable}
                init_local_variables_instances[
                    fake_variable.name] = fake_variable
            init_local_variables_instances[v.name] = new_var

    all_init_local_variables_instances = dict(init_local_variables_instances)

    init_state_variables_instances = dict(all_state_variables_instances)

    initiate_all_local_variables_instances(function.nodes,
                                           init_local_variables_instances,
                                           all_init_local_variables_instances)

    generate_ssa_irs(function.entry_point,
                     dict(init_local_variables_instances),
                     all_init_local_variables_instances,
                     dict(init_state_variables_instances),
                     all_state_variables_instances,
                     init_local_variables_instances, [])

    fix_phi_rvalues_and_storage_ref(function.entry_point,
                                    dict(init_local_variables_instances),
                                    all_init_local_variables_instances,
                                    dict(init_state_variables_instances),
                                    all_state_variables_instances,
                                    init_local_variables_instances)