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()) ]
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
def __init__(self, stream: Stream): # self.length = 0 length = stream.read_u2() self.bytes = stream.read_bytes(length)
def __init__(self, _, stream: Stream): self.debug_extension = stream.read_bytes(stream.read_u4())
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)