예제 #1
0
    internal void Write(EndiannessWriter writer, UInt32 serializationVersion)
    {
        writer.WriteAlignedString(Name);

        writer.WritePPtrArray(PreloadTable, serializationVersion);
        writer.WriteInt32(Container.Length);
        foreach (var container in Container)
        {
            writer.WriteAlignedString(container.Key);
            writer.WriteAssetInfo(container.Value, serializationVersion);
        }

        writer.WriteAssetInfo(MainAsset, serializationVersion);

        writer.WriteUInt32(RuntimeCompatibility);

        writer.WriteAlignedString(AssetBundleName);
        writer.WriteInt32(DependencyAssetBundleNames.Length);
        foreach (var dependencyAssetBundleName in DependencyAssetBundleNames)
        {
            writer.WriteAlignedString(dependencyAssetBundleName);
        }

        writer.WriteBoolean(IsStreamedSceneAssetBundle);
        writer.Align(4);
        writer.WriteInt32(ExplicitDataLayout);
        writer.WriteInt32(PathFlags);

        writer.WriteInt32(SceneHashes.Count);
        foreach (var sceneHash in SceneHashes)
        {
            writer.WriteString(sceneHash.Key);
            writer.WriteString(sceneHash.Value);
        }
    }
    internal void Write(EndiannessWriter writer)
    {
        writer.WriteUInt32(MetadataSize);
        writer.WriteUInt32((UInt32)FileSize);
        writer.WriteUInt32(Version);
        writer.WriteUInt32((UInt32)DataOffset);

        writer.Write(new[] { (byte)Endianness });
        // Writing endianness changes from here
        // What the actual f**k?
        writer.Endianness = Endianness;

        writer.Write(Reserved);
        writer.WriteString(UnityVersion);
        writer.WriteInt32((Int32)BuildTarget);
        writer.WriteBoolean(IsTypeTreeEnabled);

        writer.WriteInt32(SerializedTypes.Length);
        foreach (var serializedType in SerializedTypes)
        {
            writer.WriteInt32(serializedType.ClassID);
            writer.WriteBoolean(serializedType.IsStrippedType);
            writer.WriteInt16(serializedType.ScriptTypeIndex);
            if ((Version < 16 && serializedType.ClassID < 0) ||
                (Version >= 16 && serializedType.ClassID == 114))
            {
                writer.Write(serializedType.ScriptID); //Hash128
            }
            writer.Write(serializedType.OldTypeHash);
        }

        writer.WriteInt32(ObjectInfos.Length);
        foreach (var objectInfo in ObjectInfos)
        {
            writer.Align(4);
            writer.WriteInt64(objectInfo.PathID);
            writer.WriteInt32((Int32)objectInfo.ByteStart);
            writer.WriteUInt32(objectInfo.ByteSize);
            writer.WriteInt32(objectInfo.TypeID);
        }

        // Script
        int scriptCount = 0;

        writer.WriteInt32(scriptCount);

        // Externals
        int externalCount = 0;

        writer.WriteInt32(externalCount);

        string userInformation = "";

        writer.WriteString(userInformation);
    }
예제 #3
0
 internal void Write(EndiannessWriter writer)
 {
     writer.WriteString(Signature);
     writer.WriteInt32(Version);
     writer.WriteString(UnityVersion);
     writer.WriteString(UnityRevision);
     writer.WriteInt64(Size);
     writer.WriteInt32(CompressedBlocksInfoSize);
     writer.WriteInt32(UncompressedBlocksInfoSize);
     writer.WriteInt32(Flags);
 }
예제 #4
0
    internal void Write(EndiannessWriter writer)
    {
        writer.Write(UncompressedDataHash);

        writer.WriteInt32(StorageBlocks.Length);
        foreach (var storageBlock in StorageBlocks)
        {
            writer.WriteUInt32(storageBlock.CompressedSize);
            writer.WriteUInt32(storageBlock.UncompressedSize);
            writer.WriteUInt16(storageBlock.Flags);
        }

        writer.WriteInt32(Nodes.Length);
        foreach (var node in Nodes)
        {
            writer.WriteInt64(node.Offset);
            writer.WriteInt64(node.Size);
            writer.WriteUInt32(node.Flags);
            writer.WriteString(node.Path);
        }
    }
예제 #5
0
    internal void Write(EndiannessWriter writer)
    {
        writer.WriteAlignedString(Name);

        writer.WriteInt32(ForcedFallbackFormat);
        writer.WriteBoolean(DownscaleFallback);
        writer.Align(4);

        writer.WriteInt32(Width);
        writer.WriteInt32(Height);
        writer.WriteInt32(CompleteImageSize);
        writer.WriteInt32((Int32)TextureFormat);
        writer.WriteInt32(MipCount);

        writer.WriteBoolean(IsReadable);
        writer.WriteBoolean(IsReadAllowed);
        writer.Align(4);

        writer.WriteInt32(StreamingMipmapsPriority);
        writer.WriteInt32(ImageCount);
        writer.WriteInt32(TextureDimension);

        writer.WriteInt32(TextureSettings.FilterMode);
        writer.WriteInt32(TextureSettings.Aniso);
        writer.WriteSingle(TextureSettings.MipBias);
        writer.WriteInt32(TextureSettings.WrapMode);
        writer.WriteInt32(TextureSettings.WrapV);
        writer.WriteInt32(TextureSettings.WrapW);

        writer.WriteInt32(LightmapFormat);
        writer.WriteInt32(ColorSpace);
        writer.WriteInt32(ImageDataSize);

        writer.WriteUInt32(StreamData.Offset);
        writer.WriteUInt32(StreamData.Size);
        writer.WriteAlignedString(StreamData.Path);
    }
예제 #6
0
    public static void BuildCounterfeit()
    {
        const string texturePath     = "Assets/Turtle.jpg";
        const string textureMetaPath = texturePath + ".meta";

        var metaContent = new StringReader(File.ReadAllText(textureMetaPath));
        var yaml        = new YamlStream();

        yaml.Load(metaContent);

        var    rootNode            = yaml.Documents[0].RootNode;
        var    guidNode            = Utility.FindYamlChildNode((YamlMappingNode)rootNode, "guid");
        string guid                = ((YamlScalarNode)guidNode).Value;
        var    textureImporterNode = Utility.FindYamlChildNode((YamlMappingNode)rootNode, "TextureImporter");
        var    assetBundleNameNode = Utility.FindYamlChildNode((YamlMappingNode)textureImporterNode, "assetBundleName");
        string assetBundleName     = ((YamlScalarNode)assetBundleNameNode).Value;
        string cabFilename         = Utility.GetCabFilename(assetBundleName);
        string cabRessFilename     = Utility.GetCabRessFilename(cabFilename);
        string archivePath         = Utility.GetArchivePath(cabFilename, cabRessFilename);

        // TODO: Replace jpeg loading library
        var unityTexture2D = AssetDatabase.LoadAssetAtPath <UnityEngine.Texture2D>(texturePath);

        byte[] textureRawData = unityTexture2D.GetRawTextureData();
        int    width          = unityTexture2D.width;
        int    height         = unityTexture2D.height;

        int   textureFileId = 2800000;
        Int64 texturePathId = Utility.GetPathId(guid, textureFileId);

        var blocksInfoAndDirectory = new BlocksInfoAndDirectory
        {
            UncompressedDataHash = new byte[16] {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            },
            StorageBlocks = new[]
            {
                new StorageBlock
                {
                    CompressedSize   = 302100,
                    UncompressedSize = 302100,
                    Flags            = 64
                }
            },
            Nodes = new[]
            {
                new Node
                {
                    Offset = 0,
                    Size   = 4424,
                    Flags  = 4,
                    Path   = cabFilename
                },
                new Node
                {
                    Offset = 4424,
                    Size   = 297676,
                    Flags  = 0,
                    Path   = cabRessFilename
                }
            }
        };

        byte[] compressedBuffer;
        int    uncompressedSize;
        int    compressedSize;

        using (var memoryStream = new MemoryStream())
            using (var memoryBinaryWriter = new BinaryWriter(memoryStream))
                using (var endiannessWriterCompressed = new EndiannessWriter(memoryBinaryWriter, Endianness.Big))
                {
                    blocksInfoAndDirectory.Write(endiannessWriterCompressed);

                    byte[] uncompressedBuffer = memoryStream.ToArray();
                    uncompressedSize = uncompressedBuffer.Length;
                    // Assume compressed buffer always smaller than uncompressed
                    compressedBuffer = new byte[uncompressedSize];

                    compressedSize = LZ4Codec.Encode
                                     (
                        uncompressedBuffer,
                        0,
                        uncompressedSize,
                        compressedBuffer,
                        0,
                        uncompressedSize,
                        LZ4Level.L11_OPT
                                     );

                    compressedBuffer = compressedBuffer.Take(compressedSize).ToArray();
                }

        var serializedFileHeader = new SerializedFileHeader
        {
            MetadataSize      = 125,
            FileSize          = 4424,
            Version           = 17,
            DataOffset        = 4096,
            Endianness        = Endianness.Little,
            Reserved          = new byte[] { 0, 0, 0 },
            UnityVersion      = "2018.4.20f1\n2",
            BuildTarget       = BuildTarget.Android,
            IsTypeTreeEnabled = false,
            SerializedTypes   = new[]
            {
                new SerializedType
                {
                    // https://docs.unity3d.com/Manual/ClassIDReference.html
                    ClassID         = 142,
                    IsStrippedType  = false,
                    ScriptTypeIndex = -1,
                    OldTypeHash     = new byte[]
                    { 151, 218, 95, 70, 136, 228, 90, 87, 200, 180, 45, 79, 66, 73, 114, 151 }
                },
                new SerializedType
                {
                    ClassID         = 28,
                    IsStrippedType  = false,
                    ScriptTypeIndex = -1,
                    OldTypeHash     = new byte[]
                    { 238, 108, 64, 129, 125, 41, 81, 146, 156, 219, 79, 90, 96, 135, 79, 93 }
                }
            },
            ObjectInfos = new[]
            {
                new ObjectInfo
                {
                    PathID    = 1,
                    ByteStart = 0,
                    ByteSize  = 132,
                    TypeID    = 0
                },
                new ObjectInfo
                {
                    PathID    = texturePathId,
                    ByteStart = 136,
                    ByteSize  = 192,
                    TypeID    = 1
                }
            }
        };

        var assetBundle = new AssetBundle
        {
            Name         = assetBundleName,
            PreloadTable = new[]
            {
                new PPtr {
                    FileID = 0, PathID = texturePathId
                }
            },
            Container = new[]
            {
                new KeyValuePair <string, AssetInfo>
                (
                    texturePath.ToLower(),
                    new AssetInfo
                {
                    PreloadIndex = 0,
                    PreloadSize  = 1,
                    Asset        = new PPtr
                    {
                        FileID = 0,
                        PathID = texturePathId
                    }
                }
                )
            },
            MainAsset = new AssetInfo
            {
                PreloadIndex = 0,
                PreloadSize  = 0,
                Asset        = new PPtr
                {
                    FileID = 0,
                    PathID = 0
                }
            },
            RuntimeCompatibility       = 1,
            AssetBundleName            = assetBundleName,
            DependencyAssetBundleNames = new string[0],
            IsStreamedSceneAssetBundle = false,
            ExplicitDataLayout         = 0,
            PathFlags   = 7,
            SceneHashes = new Dictionary <string, string>()
        };

        var texture2D = new Texture2D
        {
            Name = Path.GetFileNameWithoutExtension(texturePath),

            ForcedFallbackFormat = (int)TextureFormat.RGBA32,
            DownscaleFallback    = false,

            Width             = width,
            Height            = height,
            CompleteImageSize = textureRawData.Length,

            TextureFormat = TextureFormat.RGB24,

            MipCount                 = 1,
            IsReadable               = false,
            IsReadAllowed            = false,
            StreamingMipmapsPriority = 0,
            ImageCount               = 1,
            TextureDimension         = 2,
            TextureSettings          = new GLTextureSettings
            {
                FilterMode = 1,
                Aniso      = 1,
                MipBias    = 0,
                WrapMode   = 0,
                WrapV      = 0,
                WrapW      = 0
            },
            LightmapFormat = 0,
            ColorSpace     = 1,
            ImageDataSize  = 0,
            StreamData     = new StreamingInfo
            {
                Offset = 0,
                Size   = (UInt32)textureRawData.Length,
                Path   = archivePath
            }
        };

        byte[] serializeFileBuffer;
        int    metadataSize;
        int    assetBundleObjectPosition;
        int    assetBundleObjectOffset;
        int    assetBundleObjectSize;
        int    texture2DPosition;
        int    texture2DOffset;
        int    texture2DObjectSize;

        using (var memoryStream = new MemoryStream())
            using (var memoryBinaryWriter = new BinaryWriter(memoryStream))
                using (var endiannessWriterStorage = new EndiannessWriter(memoryBinaryWriter, Endianness.Big))
                {
                    serializedFileHeader.Write(endiannessWriterStorage);
                    metadataSize = (Int32)endiannessWriterStorage.Position;

                    endiannessWriterStorage.Align((int)serializedFileHeader.DataOffset);
                    assetBundleObjectPosition = (Int32)endiannessWriterStorage.Position;
                    assetBundleObjectOffset   = (Int32)(assetBundleObjectPosition - serializedFileHeader.DataOffset);
                    assetBundle.Write(endiannessWriterStorage, serializedFileHeader.Version);
                    assetBundleObjectSize = (Int32)(endiannessWriterStorage.Position - assetBundleObjectPosition);

                    // TODO: What is this padding?
                    endiannessWriterStorage.WriteUInt32(0);

                    texture2DPosition = (Int32)endiannessWriterStorage.Position;
                    texture2DOffset   = (Int32)(texture2DPosition - serializedFileHeader.DataOffset);
                    texture2D.Write(endiannessWriterStorage);
                    texture2DObjectSize = (Int32)(endiannessWriterStorage.Position - texture2DPosition);

                    endiannessWriterStorage.WriteWithoutEndianness(textureRawData);

                    // TODO: What is this padding?
                    endiannessWriterStorage.Write(0);

                    serializeFileBuffer = memoryStream.ToArray();
                }

        var header = new UnityHeader
        {
            Signature                  = "UnityFS",
            Version                    = 6,
            UnityVersion               = "5.x.x",
            UnityRevision              = "2018.4.20f1",
            Size                       = 302235,
            CompressedBlocksInfoSize   = compressedSize,
            UncompressedBlocksInfoSize = uncompressedSize,
            Flags                      = 67
        };

        using (var fileStream = File.Create("Counterfeit/texture"))
            using (var binaryWriter = new BinaryWriter(fileStream))
                using (var endiannessWriter = new EndiannessWriter(binaryWriter, Endianness.Big))
                {
                    header.Write(endiannessWriter);
                    endiannessWriter.WriteWithoutEndianness(compressedBuffer);
                    endiannessWriter.WriteWithoutEndianness(serializeFileBuffer);
                }
    }