Example #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), )
Example #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 (exp ~ ('cd', int:idx)) and idx in func.params:
                    return ('param', func.params[idx][1])
                return exp

            func.trace = replace_f(func.trace, replace_names)
Example #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
Example #4
0
                for m in mlist:
                    if m ~ ('type', 256, ('field', 0, ('stor', ('length', _)))):
                        continue

                    if get_loc(m) == e_loc:
                        assert m ~ ('type', _, ('field', :m_off, _))
                        if m_off != e_off:
                            return exp
                else:
                    return stor

            else:
                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 line ~ ('store', :size, :off, :idx, :val):
                return ('set', ('stor', size, off, idx), val)
            else:
                return line

        def loc_to_name(exp):
            if exp ~ ('loc', int:num):
                if num < 1000:
                    return ('name', 'stor' + str(num), num)
Example #5
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:
Example #6
0
        def rem_masks(exp):
            if exp ~ ('bool', ('cd', int:idx)):
                if idx in self.params and \
                   self.params[idx][0] == 'bool':
                        return ('cd', idx)

            elif exp ~ ('mask_shl', :size, 0, 0, ('cd', int: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()))


    def ast_length(self):
Example #7
0
def make_ast(trace):
    def store_to_set(line):
        if line ~ ('store', :size, :off, :idx, :val):
            return ('set', ('stor', size, off, idx), val)
        else:
            return line

    def mask_storage(exp):
        if exp ~ ('stor', :size, :off, :idx):
            return ('mask_shl', 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)