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); }
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); }
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); } }