예제 #1
0
def _search_children(statespace, node, expression, taint_result=None, constraint=[], index=0, depth=0, max_depth=64):
    """
    Checks the statespace for children states, with JUMPI or SSTORE instuctions,
    for dependency on expression
    :param statespace: The statespace to explore
    :param node: Current node to explore from
    :param expression: Expression to look for
    :param taint_result: Result of taint analysis
    :param index: Current state index node.states[index] == current_state
    :param depth: Current depth level
    :param max_depth: Max depth to explore
    :return: List of states that match the opcodes and are dependent on expression
    """
    logging.debug("SEARCHING NODE for usage of an overflowed variable %d", node.uid)

    if taint_result is None:
        state = node.states[index]
        taint_stack = [False for _ in state.mstate.stack]
        taint_stack[-1] = True
        taint_result = TaintRunner.execute(statespace, node, state, initial_stack=taint_stack)

    results = []

    if depth >= max_depth:
        return []

    # Explore current node from index
    for j in range(index, len(node.states)):
        current_state = node.states[j]
        current_instruction = current_state.get_current_instruction()
        if current_instruction['opcode'] in ('JUMPI', 'SSTORE'):
            element = _check_usage(current_state, taint_result)
            if len(element) < 1:
                continue
            if _check_requires(element[0], node, statespace, constraint):
                 continue
            results += element

    # Recursively search children
    children = \
        [
            statespace.nodes[edge.node_to]
            for edge in statespace.edges
            if edge.node_from == node.uid
            # and _try_constraints(statespace.nodes[edge.node_to].constraints, constraint) is not None
        ]

    for child in children:
        results += _search_children(statespace, child, expression, taint_result, depth=depth + 1, max_depth=max_depth)

    return results
예제 #2
0
def execute(statespace):
    """ Executes the analysis module"""
    #logging.debug("Executing module: TOKEN2")

    issues = []
    taints = []

    for state, node in _get_states_with_opcode(statespace, "CALLDATALOAD"):
        #state = node.states[index]
        taint_stack = [False for _ in state.mstate.stack]
        taint_stack[-1] = True
        taints.append(TaintRunner.execute(statespace, node, state, initial_stack=taint_stack))

    for state, node in _get_tainted_sstores(statespace, taints):
        funtcion_we_are_in = node.contract_name + "." + node.function_name
        following_sstores = _get_sstore_along_the_line(statespace, node)

        if len(following_sstores) > 0:
            # logging.debug("SSTORE"*10)
            # logging.info("Found SSTORE %s following an SSTORE in (%s)"%(len(following_sstores), funtcion_we_are_in))
            # logging.debug("%s: BEGIN Contraints of first SSTORE"%(funtcion_we_are_in))

            #print("%s found following stores (%s)"%(funtcion_we_are_in, len(following_sstores)))

            r_n_constraints = list(map(_normalize_constraint, filter(_relevant_constraint, node.constraints)))

            # for c in r_n_constraints:
            #     logging.info(c)


            matches = check_for_token_pattern(state, following_sstores, r_n_constraints, funtcion_we_are_in)

            if len(matches) > 0:
                issues.append(Issue(node.contract_name, node.function_name, None,
                           "Found a transfer like function",
                           "WUPI"))
            else:
                pass
                #logging.info("Found no matching sstores")

            # logging.debug("%s: END Contraints, those where the relevant constraints"%(funtcion_we_are_in))

            # logging.debug("%s: Leading value =\n%s"%(funtcion_we_are_in, _get_value_sstore(state)))
            # logging.debug("%s: Following value =\n%s"%(funtcion_we_are_in, _get_value_sstore(following_sstores[0])))
            # logging.debug("SSTORE"*10)
        else:
            pass 
            #logging.info("%s: FOUND SSTORE (%s), but nothing followed"%(funtcion_we_are_in, _get_value_sstore(state)))

    return issues