Beispiel #1
0
    def load_binary(self, source):
        stack = []
        self.binary = []

        if source[:2] == "0x":
            source = source[2:]

        while len(source[:2]) > 0:
            num = int("0x" + source[:2], 16)
            self.binary.append(num)
            stack = [num] + stack
            source = source[2:]

        line = 0

        parsed_lines = []

        while len(stack) > 0:
            popped = stack.pop()

            orig_line = line

            if popped not in opcode_dict:
                op = "UNKNOWN"
                param = popped

            else:
                param = None
                op = opcode_dict[popped]

                if op == "jumpdest":
                    self.jump_dests.append(line)

                if op[:4] == "push":
                    num_words = int(op[4:])

                    param = 0
                    for i in range(num_words):
                        try:
                            param = param * 0x100 + stack.pop()
                            line += 1
                        except Exception:
                            break

            parsed_lines.append((orig_line, op, param))
            line += 1

        self.parsed_lines = parsed_lines
        self.last_line = line
        self.lines = {}

        for line_no, op, param in parsed_lines:
            if op[:4] == "push" and param > 1000000000000000:
                param = pretty_bignum(
                    param)  # convert big numbers into strings if possibble
                # should be moved to prettify really

            if op[:3] == "dup":
                param = int(op[3:])
                op = "dup"

            if op[:4] == "swap":
                param = int(op[4:])
                op = "swap"

            self.lines[line_no] = (line_no, op, param)

        return self.lines
Beispiel #2
0
def pretty_memory(exp, add_color=False):
    if exp is None:
        return tuple()

    if exp == 'mem':
        return prettify(exp, add_color=add_color)

    if opcode(exp) != 'data':
        return (prettify(exp, add_color=add_color), )

    exp = exp[1:]

    if len(exp) == 0:
        return 'empty()'
    assert len(exp) > 0, exp

    res = []

    idx = 0

    def unmask(exp):
        if opcode(exp) == 'mask_shl':
            return exp[4]

        return exp

    # merge things that look like string into a string

    while idx < len(exp):

        if idx == 0 and type(exp[0]) == tuple and exp[0][:4] == ('mask_shl', 32, 224, 0) and type(exp[0][4]) == int:
            # This happens often in Log and Revert, first
            # memory result being an 8-byte identifier.
            # Definitely deserves a more generic solution.
            #
            # example: 0xd883209C4DCd497f24633C627a4E451013424841, sendFoods function
            v = exp[0][4] >> 224
            res.append( pretty_fname(v, add_color) )
            idx += 1
            continue

        el = exp[idx]

        # detect a potential string

        out_str = None

        if unmask(el) == 32 and len(exp)>idx+1:

            length = unmask(exp[idx+1])
            if type(length) == int:
                byte_length = ((length-1) >> 5) +1
                out_str = ''

                if type(length) == int and len(exp) > idx + 1 + byte_length:
                    for i in range(byte_length):
                        if type(unmask(exp[idx+2+i])) == str:
                            out_str += unmask(exp[idx+2+i])[1:-1]
                        elif type(pretty_bignum(unmask(exp[idx+2+i]))) == str:
                            # could also make sure that the length of string is the same
                            # as expected
                            out_str += pretty_bignum(unmask(exp[idx+2+i]))[1:-1]
                        else:
                            out_str = None
                            break

                    if out_str != None:
                        idx = idx + 1 + byte_length
                else:
                    out_str = None
            else:
                out_str = None

        if out_str != None:
            res.append("'"+out_str+"'")
        else:
            res.append(prettify(el, add_color=add_color, parentheses=False))

        idx = idx+1


    return tuple(res)