Example #1
0
 def __init__(self, class_file, stream: Stream):
     self.max_stack = stream.read_u2()
     self.max_locals = stream.read_u2()
     code_length = stream.read_u4()
     code = stream.read_bytes(code_length)
     # noinspection PyTypeChecker
     self.instructions: List[Instruction] = self.read_bytecode(
         code_length, Stream(BytesIO(code)))
     self.exception_table = [
         ExceptionTableEntry(stream) for _ in range(stream.read_u2())
     ]
     self.attributes = [
         Attribute.read(class_file, stream) for _ in range(stream.read_u2())
     ]
Example #2
0
    def decode(self, obj, debug=False):
        object_id, data, type_tree = obj
        queue = list(type_tree[3])

        if debug:
            print('-' * 50)

        stream = Stream(data)
        stream.enidan = self.stream.enidan

        structure = {}
        current, align = [structure], [False]
        prev = None
        while queue:
            i = queue.pop(0)
            while i[0] != 0 and i[0] < len(current):
                current.pop(-1)
                if align.pop(-1):
                    t = (4 - (stream.tell() % 4)) % 4
                    assert stream.read_bytes(t) == b'\x00' * t

            multi = False
            if i[2] == b'int':
                d = stream.read_sint()
            elif i[2] == b'unsigned int':
                d = stream.read_int()
            elif i[2] == b'float':
                d = stream.read_float()
            elif i[2] == b'bool':
                d = stream.read_bool()
            elif i[2] == b'char':
                if isinstance(current[-1], list) and len(current[-1]) == 1:
                    multi = True
                    d = stream.read_bytes(current[-1][0])
                else:
                    d = stream.read_bytes(1)
            elif i[2] == b'UInt8':
                if isinstance(current[-1], list) and len(current[-1]) == 1:
                    multi = True
                    d = stream.read_bytes(current[-1][0])
                else:
                    d = stream.read_byte()
            elif i[1]:
                d = []
            else:
                d = None

            if debug:
                print(len(current),
                      str(stream.tell()).rjust(3),
                      ('  ' * i[0] + i[2].decode() + ': ').ljust(23) +
                      i[3].decode().ljust(25), hex(i[-1]),
                      str(d)[:30] + ('' if len(str(d)) <= 30 else '...'))

            if i[0] > len(current) and isinstance(current[-1], dict):
                current.append({})
                current[-2][prev[3].decode()] = current[-1]
                align.append(i[-1] & 0x4000)
            elif i[-1] & 0x4000 and not i[1]:
                t = (4 - (stream.tell() % 4)) % 4
                assert stream.read_bytes(t) == b'\x00' * t

            if isinstance(current[-1], list):
                if multi:
                    current[-1].extend(d)
                else:
                    current[-1].append(d)

                if current[-1] and len(current[-1]) == current[-1][0] + 1:
                    if not current[-1].pop(0):
                        queue.pop(0)
                    current.pop(-1)
                    if align.pop(-1):
                        t = (4 - (stream.tell() % 4)) % 4
                        assert stream.read_bytes(t) == b'\x00' * t
                elif len(current[-1]) > 1:
                    queue.insert(0, i)

            elif d is not None:
                current[-1][i[3].decode()] = d

            if isinstance(d, list):
                current.append(d)
                align.append(i[-1] & 0x4000)

            prev = i
        return structure
Example #3
0
 def __init__(self, stream: Stream):
     # self.length = 0
     length = stream.read_u2()
     self.bytes = stream.read_bytes(length)
Example #4
0
 def __init__(self, _, stream: Stream):
     self.debug_extension = stream.read_bytes(stream.read_u4())
Example #5
0
 def read(class_file, stream: Stream):
     name_index = stream.read_u2()
     name: Utf8Info = class_file.constants[name_index]
     # noinspection PyTypeChecker
     s = Stream(BytesIO(stream.read_bytes(stream.read_u4())))
     return ATTRIBUTES[name.bytes](class_file, s)