Пример #1
0
def as_paths(trace, path=None):
    assert type(trace) == list

    path = path or tuple()

    #    self.find_offsets()

    trace = replace_f(trace, make_fands)

    for line in trace:
        if opcode(line) == "if":
            # assumes 'ifs' end trace
            cond, if_true, if_false = line[1], line[2], line[3]
            return as_paths(if_true, path + (cond,)) + as_paths(
                if_false, path + (is_zero(cond),)
            )

        if opcode(line) == "LOOP":
            path += (("LOOP", line[2]),)
            return as_paths(line[1], path)

        path += (line,)

    #    pprint_logic()

    return (list(path),)
Пример #2
0
    def postprocess(self):
        try:
            self.stor_defs = sparser.rewrite_functions(self.functions)
        except Exception:
            # this is critical, because it causes full contract to display very
            # badly, and cannot be limited in scope to just one affected function
            logger.exception(
                "Storage postprocessing failed. This is very bad!")
            self.stor_defs = {}

        for func in self.functions:

            def replace_names(exp):
                if (m := match(exp,
                               ("cd", ":int:idx"))) and m.idx in func.params:
                    return ("param", func.params[m.idx][1])
                return exp

            func.trace = replace_f(func.trace, replace_names)
Пример #3
0
def meta_fold_paths(paths):
    for_merge = []
    for r in paths:
        assert type(r) in (tuple, list)
        if len(r) > 0:
            for_merge.append(r)

    output = fold_paths(for_merge)

    assert type(output) == list

    output = flatten(
        output
    )  # converts if-else statements into if statements, if possible
    output = cleanup_ors(output)
    output = make_ifs(output)
    output = merge_ifs(output)

    output = replace_f(output, unmake_fands)

    return output
Пример #4
0
        array is when you add to a loc

    """

    def add_to_arr(exp):
        if m := match(exp, ("add", ":left", ":right")):
            left, right = m.left, m.right
            if opcode(left) == "loc":
                right, left = left, right

            if opcode(right) == "loc":
                return ("array", left, right)

        return exp

    storages = replace_f(storages, add_to_arr)
    """

        (s 256 0 (add 3 (mul 0.125 idx)))

    """

    res = []
    for s in storages:
        op, size, offset, idx = s
        assert op == "stor"

        if m := match(idx, ("add", ":e")):
            idx = m.e

        if opcode(idx) == "add" and get_loc(idx) is None:
Пример #5
0
def make_ast(trace):
    def store_to_set(line):
        if m := match(line, ("store", ":size", ":off", ":idx", ":val")):
            return ("set", ("stor", m.size, m.off, m.idx), m.val)
        else:
            return line

    def mask_storage(exp):
        if m := match(exp, ("stor", ":size", ":off", ":idx")):
            return ("mask_shl", m.size, 0, 0, exp)
        else:
            return exp

    trace = replace_lines(trace, store_to_set)
    trace = replace_f(trace, mask_storage)

    return trace


def format_exp(exp):
    if type(exp) == str:
        return f'"{exp}"'
    if type(exp) == int:
        if exp > 10**6 and exp % 10**6 != 0:
            return hex(exp)
        else:
            return str(exp)
    elif type(exp) != list:
        return str(exp)
    else:
Пример #6
0
                idx = m.idx
                if idx in self.params and self.params[idx][0] == "bool":
                    return ("cd", idx)

            elif m := match(exp,
                            ("mask_shl", ":size", 0, 0, ("cd", ":int:idx"))):
                size, idx = m.size, m.idx
                if idx in self.params:
                    kind = self.params[idx][0]
                    def_size = type_to_mask(kind)
                    if size == def_size:
                        return ("cd", idx)

            return exp

        return replace_f(trace, rem_masks)

    def make_names(self):
        new_name = self.name.split("(")[0]

        self.name = "{}({})".format(
            new_name, ", ".join(
                (p[0] + " " + p[1]) for p in self.params.values()))
        self.color_name = "{}({})".format(
            new_name,
            ", ".join((p[0] + " " + COLOR_GREEN + p[1] + ENDC)
                      for p in self.params.values()),
        )

        self.abi_name = "{}({})".format(
            new_name, ",".join(p[0] for p in self.params.values()))
Пример #7
0
                for mask in stor_loc_to_masks[e_loc]:
                    if not match(mask,
                                 ("type", 256, ("field", 0,
                                                ("stor", ("length", Any))))):
                        assert (m :=
                                match(mask,
                                      ("type", Any, ("field", ":m_off", Any))))
                        if m.m_off != e_off:
                            return exp

                return stor

            return exp

        for f in self.functions:
            f.ast = replace_f(f.ast, cleanup)

    def make_ast(self, trace):
        trace = folder.fold(trace)

        def store_to_set(line):
            if m := match(line, ("store", ":size", ":off", ":idx", ":val")):
                return ("set", ("stor", m.size, m.off, m.idx), m.val)
            else:
                return line

        def loc_to_name(exp):
            if m := match(exp, ("loc", ":int:num")):
                num = m.num
                if num < 1000:
                    return ("name", "stor" + str(num), num)