Beispiel #1
0
def main():
    import argparse, sys
    arguments = argparse.ArgumentParser()
    arguments.add_argument('--file', '-f', required=True)
    arguments.add_argument('--output', '-o', default='__types')
    options = arguments.parse_args(sys.argv[1:])
    output = p.abspath(options.output)
    if not p.exists(output): os.makedirs(output)
    MONO_BEHAVIOUR_PERSISTENT_ID = 114

    stream = FileStream(file_path=options.file)
    stream.endian = '<'
    while stream.bytes_available:
        persistent_id = stream.read_uint32()
        script_hash = b'0' * 16
        if persistent_id == MONO_BEHAVIOUR_PERSISTENT_ID:
            script_hash = stream.read(16)
        type_hash = stream.read(16)
        size = stream.read_uint32()
        offset = stream.position
        print(persistent_id, uuid.UUID(bytes=script_hash),
              uuid.UUID(bytes=type_hash), size)
        type_tree = MetadataTypeTree(True)
        type_tree.persistent_type_id = persistent_id
        type_tree.type_hash = type_hash
        type_tree.mono_hash = script_hash
        type_tree.decode_type_tree(fs=stream)
        print(type_tree)
        assert stream.position == offset + size
Beispiel #2
0
 def decode(self, fs: FileStream):
     self.version = fs.read_sint16()
     self.level = fs.read_uint8()
     self.is_array = fs.read_boolean()
     self.type_str_offset = fs.read_uint32()
     self.name_str_offset = fs.read_uint32()
     self.byte_size = fs.read_sint32()
     self.index = fs.read_sint32()
     self.meta_flags = fs.read_uint32()
Beispiel #3
0
 def decode(self, fs: FileStream):
     offset = fs.position
     self.signature = fs.read_string()
     assert self.signature == UnitySignature.UnityFS
     self.version = fs.read_sint32()
     assert self.version != 5
     self.unity_web_bundle_version = fs.read_string()
     self.unity_web_minimum_revision = fs.read_string()
     self.size = fs.read_uint64()
     self.compressed_blocks_info_size = fs.read_uint32()
     self.uncompressed_blocks_info_size = fs.read_uint32()
     assert self.compressed_blocks_info_size < self.uncompressed_blocks_info_size, vars(
         self)
     self.flags = fs.read_uint32()
     self.header_size = fs.position - offset
Beispiel #4
0
 def decode_type_tree(self, fs: FileStream):
     type_index = -1
     node_count = fs.read_uint32()
     char_count = fs.read_uint32()
     for _ in range(node_count):
         node = TypeField()
         node.decode(fs)
         if type_index >= 0: assert node.index == type_index + 1
         self.nodes.append(node)
         type_index += 1
     if char_count > 0:
         string_offset = fs.position
         string_size = 0
         while string_size + 1 < char_count:
             offset = fs.position - string_offset
             position = fs.position
             self.strings[offset] = fs.read_string()
             string_size += fs.position - position
         assert fs.position - string_offset == char_count
     for node in self.nodes:  # type: TypeField
         node.name = get_caculate_string(offset=node.name_str_offset,
                                         strings=self.strings)
         node.type = get_caculate_string(offset=node.type_str_offset,
                                         strings=self.strings)
     self.name = self.nodes[0].type
Beispiel #5
0
    def decode(self, fs: FileStream):
        fs.seek(self.node.offset)
        header = self.header
        header.metadata_size = fs.read_sint32()
        header.file_size = fs.read_sint32()
        assert self.node.size == header.file_size, '{} != {}'.format(
            self.node.size, header.file_size)
        header.version = fs.read_sint32()
        header.data_offset = fs.read_sint32()
        header.endianess = fs.read_boolean()
        fs.read(3)  # reserved bytes
        fs.endian = '>' if header.endianess else '<'
        self.print(vars(header))
        self.version = fs.read_string()
        self.platform = fs.read_uint32()
        self.type_tree_enabled = fs.read_boolean()
        self.print('version={} platform={} type_tree_enabled={}'.format(
            self.version, self.platform, self.type_tree_enabled))
        self.type_trees = []
        type_count = fs.read_uint32()
        self.print('type', type_count)
        for _ in range(type_count):
            offset = fs.position
            type_tree = MetadataTypeTree(
                type_tree_enabled=self.type_tree_enabled)
            type_tree.decode(fs)
            if self.type_tree_enabled:
                position = fs.position
                fs.seek(offset)
                type_data = fs.read(position - offset)
                with open(type_tree.get_cache_path(auto_create=True),
                          'wb') as fp:
                    fp.write(type_data)
            self.type_trees.append(type_tree)
            self.register_type_tree(type_tree=type_tree)
            self.print(type_tree)

        object_count = fs.read_sint32()
        self.print('object', object_count)
        for _ in range(object_count):
            fs.align(4)
            obj = ObjectInfo()
            obj.decode(fs)
            type_tree = self.type_trees[obj.type_id]
            obj.name = type_tree.name
            self.objects.append(obj)
            self.print(vars(obj))

        script_type_count = fs.read_sint32()
        self.print('typeinfo', script_type_count)
        for _ in range(script_type_count):
            st = ScriptTypeInfo()
            st.decode(fs)
            self.typeinfos.append(st)
            self.print(vars(st))

        external_count = fs.read_sint32()
        self.print('external', external_count)
        for _ in range(external_count):
            ext = ExternalInfo()
            ext.decode(fs)
            self.externals.append(ext)
            self.print(ext)
        fs.read_string()
Beispiel #6
0
 def decode(self, fs: FileStream):
     self.local_identifier_in_file = fs.read_sint64()
     self.byte_start = fs.read_uint32()
     self.byte_size = fs.read_uint32()
     self.type_id = fs.read_uint32()
Beispiel #7
0
 def decode(self, fs: FileStream):
     for n in range(fs.read_uint32()):
         node = FileNode()
         node.decode(fs)
         node.index = n
         self.nodes.append(node)
Beispiel #8
0
 def decode(self, fs: FileStream):
     self.offset = fs.read_uint64()
     self.size = fs.read_uint64()
     self.flags = fs.read_uint32()
     self.path = fs.read_string()
Beispiel #9
0
 def decode(self, fs: FileStream):
     self.uncompressed_data_hash = fs.read(16)
     for _ in range(fs.read_uint32()):
         block = StorageBlock()
         block.decode(fs)
         self.blocks.append(block)
Beispiel #10
0
 def decode(self, fs: FileStream):
     self.uncompressed_size = fs.read_uint32()
     self.compressed_size = fs.read_uint32()
     self.flags = fs.read_uint16()