private void decompressButton_Click(object sender, System.EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();

            sfd.FileName = Path.GetFileName(bundleStream.Name) + ".unpacked";
            sfd.Filter   = "All types (*.*)|*.*";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                note.Text = "Decompressing...";
                decompressButton.Enabled = false;
                bundleFilename           = sfd.FileName;
                FileStream       fileStream = new FileStream(sfd.FileName, FileMode.Create);
                BackgroundWorker bw         = new BackgroundWorker();
                bw.DoWork += delegate
                {
                    bundle.Unpack(reader, new AssetsFileWriter(fileStream));
                    fileStream.Position = 0;
                    bundle = new AssetsBundleFile();
                    bundle.Read(new AssetsFileReader(fileStream), false);
                    fileStream.Close();
                };
                bw.RunWorkerCompleted += delegate
                {
                    note.Text = "Done. Click Load to open the file.";
                    decompressButton.Enabled = false;
                    loadButton.Enabled       = true;
                };
                bw.RunWorkerAsync();
            }
        }
示例#2
0
 //AssetsBundleFile
 public static void Write(this AssetsBundleFile file, AssetsFileWriter writer, byte[] assetsFileBinary /*AssetsFile assetsFile, AssetsReplacer[] replacers*/)
 {
     file.bundleHeader6.Write(writer, 0);
     file.bundleInf6.Write(writer, writer.Position);
     writer.Write(assetsFileBinary);
     //assetsFile.Write(writer, writer.Position, replacers, 0);
 }
示例#3
0
        public static AssetsBundleFile CreateBlankBundle(string engineVersion, int contentSize)
        {
            AssetsBundleHeader06 header = new AssetsBundleHeader06()
            {
                signature         = "UnityFS",
                fileVersion       = 6,
                minPlayerVersion  = "5.x.x",
                fileEngineVersion = engineVersion,
                totalFileSize     = (ulong)(0x82 + engineVersion.Length + contentSize),
                compressedSize    = 0x5B,
                decompressedSize  = 0x5B,
                flags             = 0x40
            };
            AssetsBundleBlockInfo06 blockInf = new AssetsBundleBlockInfo06
            {
                decompressedSize = (uint)contentSize,
                compressedSize   = (uint)contentSize,
                flags            = 0x0040
            };
            AssetsBundleDirectoryInfo06 dirInf = new AssetsBundleDirectoryInfo06
            {
                offset           = 0,
                decompressedSize = (uint)contentSize,
                flags            = 4,
                name             = GenerateCabName()
            };
            AssetsBundleBlockAndDirectoryList06 info = new AssetsBundleBlockAndDirectoryList06()
            {
                checksumLow  = 0,
                checksumHigh = 0,
                blockCount   = 1,
                blockInf     = new AssetsBundleBlockInfo06[]
                {
                    blockInf
                },
                directoryCount = 1,
                dirInf         = new AssetsBundleDirectoryInfo06[]
                {
                    dirInf
                }
            };
            AssetsBundleFile bundle = new AssetsBundleFile()
            {
                bundleHeader6 = header,
                bundleInf6    = info
            };

            return(bundle);
        }
示例#4
0
    private void DecompressBundle(string path)
    {
        //from uabe
        AssetsFileReader reader = new AssetsFileReader(new FileStream(path, FileMode.Open));
        AssetsBundleFile bundle = new AssetsBundleFile();

        bundle.Read(reader, true);
        reader.Position = 0;
        AssetsFileWriter writer = new AssetsFileWriter(new FileStream(path + ".up", FileMode.Create));

        bundle.Unpack(reader, writer);
        //writer.BaseStream.Position = 0;
        //bundle = new AssetsBundleFile();
        //bundle.Read(new AssetsFileReader(writer.BaseStream), false);
        reader.BaseStream.Close();
        writer.BaseStream.Close();
    }
示例#5
0
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "Unity content (*.unity3d;*.assets)|*.unity3d;*.assets|Bundle file (*.unity3d)|*.unity3d|Assets file (*.assets)|*.assets|All types (*.*)|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //try
                //{
                //todo, use using
                FileStream       stream     = new FileStream(ofd.FileName, FileMode.Open, FileAccess.ReadWrite);
                AssetsFileReader tempReader = new AssetsFileReader(stream);     //todo .assets sanity check
                if (tempReader.ReadStringLength(7) != "UnityFS")
                {
                    tempReader.Position = 0;
                    AssetViewer av = new AssetViewer(stream, Path.GetDirectoryName(stream.Name), Path.GetFileName(stream.Name));
                    av.ShowDialog();
                }
                else
                {
                    tempReader.Position = 0;
                    BundleLoader bl = new BundleLoader(stream);
                    bl.ShowDialog();
                    if (bl.loaded)
                    {
                        bundleContents.Enabled = true;
                        exportButton.Enabled   = true;
                        importButton.Enabled   = true;
                        infoButton.Enabled     = true;
                        foreach (AssetsBundleDirectoryInfo06 di in bl.bundle.bundleInf6.dirInf)
                        {
                            bundleContents.Items.Add(di.name);
                        }
                        bundleContents.SelectedIndex = 0;
                        bundlePath    = bl.bundleFilename;
                        fileName.Text = Path.GetFileName(bundlePath);
                        bundle        = bl.bundle;
                    }
                }
                tempReader = null;
                //} catch (Exception ex)
                //{
                //    MessageBox.Show("Unable to open the file!\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //}
            }
        }
示例#6
0
        private static byte[] GetBundleData(string bunPath, int index)
        {
            AssetsFileReader r   = new AssetsFileReader(File.Open(bunPath, FileMode.Open, FileAccess.Read, FileShare.Read));
            AssetsBundleFile bun = new AssetsBundleFile();

            bun.Read(r, true);

            //if the bundle doesn't have this section return empty
            if (index >= bun.bundleInf6.dirInf.Length)
            {
                return(new byte[0]);
            }

            AssetsBundleDirectoryInfo06 dirInf = bun.bundleInf6.dirInf[index];
            int start  = (int)(bun.bundleHeader6.GetFileDataOffset() + dirInf.offset);
            int length = (int)dirInf.decompressedSize;

            byte[] data;
            r.BaseStream.Position = start;
            data = r.ReadBytes(length);
            return(data);
        }
        private void ReadBundle(FileStream stream)
        {
            reader         = new AssetsFileReader(stream);
            bundle         = new AssetsBundleFile();
            bundleFilename = stream.Name;
            bundle.Read(reader, true);
            reader.Position = 0;
            switch (bundle.bundleHeader6.flags & 0x3F)
            {
            case 0:
                compressionMethod.Text = "Compression Method: None";
                break;

            case 1:
                compressionMethod.Text = "Compression Method: LZMA";
                break;

            case 2:
            case 3:
                compressionMethod.Text = "Compression Method: LZ4";
                break;

            default:
                compressionMethod.Text = "Compression Method: Unknown";
                break;
            }
            if ((bundle.bundleHeader6.flags & 0x3F) == 0)
            {
                note.Text = "Bundle is not compressed. You can load it or compress it.";
                compressButton.Enabled = true;
                loadButton.Enabled     = true;
            }
            else
            {
                note.Text = "Bundle is compressed. You must decompress the bundle to load.";
                decompressButton.Enabled = true;
            }
        }
示例#8
0
        public static AssetsBundleFile CreateBlankBundle(string engineVersion, int contentSize, int contentSizeSA, string sceneName)
        {
            uint infSize = (uint)(0x7B + sceneName.Length * 2);
            AssetsBundleHeader06 header = new AssetsBundleHeader06()
            {
                signature         = "UnityFS",
                fileVersion       = 6,
                minPlayerVersion  = "5.x.x",
                fileEngineVersion = engineVersion,
                totalFileSize     = (ulong)(0x82 + engineVersion.Length + contentSize + contentSizeSA),
                compressedSize    = infSize, //0x5B,
                decompressedSize  = infSize, //0x5B,
                flags             = 0x40
            };
            AssetsBundleBlockInfo06 blockInfSharedAssets = new AssetsBundleBlockInfo06
            {
                decompressedSize = (uint)contentSizeSA,
                compressedSize   = (uint)contentSizeSA,
                flags            = 0x0040
            };
            AssetsBundleDirectoryInfo06 dirInfSharedAssets = new AssetsBundleDirectoryInfo06
            {
                offset           = 0,
                decompressedSize = (uint)contentSizeSA,
                flags            = 4,
                name             = "BuildPlayer-" + sceneName + ".sharedAssets"
            };
            AssetsBundleBlockInfo06 blockInf = new AssetsBundleBlockInfo06
            {
                decompressedSize = (uint)contentSize,
                compressedSize   = (uint)contentSize,
                flags            = 0x0040
            };
            AssetsBundleDirectoryInfo06 dirInf = new AssetsBundleDirectoryInfo06
            {
                offset           = (ulong)contentSizeSA,
                decompressedSize = (uint)contentSize,
                flags            = 4,
                name             = "BuildPlayer-" + sceneName
            };
            AssetsBundleBlockAndDirectoryList06 info = new AssetsBundleBlockAndDirectoryList06()
            {
                checksumLow  = 0,
                checksumHigh = 0,
                blockCount   = 2,
                blockInf     = new AssetsBundleBlockInfo06[]
                {
                    blockInfSharedAssets,
                    blockInf
                },
                directoryCount = 2,
                dirInf         = new AssetsBundleDirectoryInfo06[]
                {
                    dirInfSharedAssets,
                    dirInf
                }
            };
            AssetsBundleFile bundle = new AssetsBundleFile()
            {
                bundleHeader6 = header,
                bundleInf6    = info
            };

            return(bundle);
        }
示例#9
0
        public static byte[] CreateBundleFromLevel(AssetsManager am, /*byte[] data,*/ AssetsFileInstance inst, string sceneName, DiffFile diffFile, string bunPath)
        {
            AssetsFile      file  = inst.file;
            AssetsFileTable table = inst.table;

            string folderName = Path.GetDirectoryName(inst.path);
            //string sceneName = Path.GetFileNameWithoutExtension(inst.path) + "_mod";

            List <AssetsReplacer> assetsSA = new List <AssetsReplacer>();

            List <AssetFileInfoEx> infos = table.pAssetFileInfo.ToList();

            //List<int> typeIds = new List<int>();
            //foreach (AssetFileInfoEx info in infos)
            //{
            //    int typeId = (int)info.curFileType;
            //    if (!typeIds.Contains(typeId) && typeId != 0x72)
            //        typeIds.Add(typeId);
            //}

            assetsSA.Add(PreloadData.CreatePreloadData(1));
            assetsSA.Add(BundleMeta.CreateBundleInformation(sceneName, 2));

            //todo: pull from original assets file, cldb is not always update to date
            List <Type_0D> types = new List <Type_0D>();
            //foreach (int typeId in typeIds)
            //{
            //    types.Add(C2T5.Cldb2TypeTree(am.classFile, typeId));
            //}

            List <Type_0D> typesSA = new List <Type_0D>
            {
                C2T5.Cldb2TypeTree(am.classFile, 0x96), //PreloadData
                C2T5.Cldb2TypeTree(am.classFile, 0x8E)  //AssetBundle
            };

            const string ver = "2017.4.10f1";

            List <AssetsReplacer> replacers = new List <AssetsReplacer>();

            //UnityEngine.Debug.Log("HKWE DM " + diffFile.magic);
            //UnityEngine.Debug.Log("HKWE GC " + diffFile.changes.Count + diffFile.adds.Count + diffFile.removes.Count);
            //AssetsReplacerFromMemory mem = MoveTest.RunMoveTest(table.getAssetInfo(2642), am.GetATI(file, table.getAssetInfo(2642)).GetBaseField(), 2642) as AssetsReplacerFromMemory;
            foreach (GameObjectChange goChange in diffFile.changes)
            {
                //UnityEngine.Debug.Log("HKWE GO " + goChange.pathId);
                foreach (ComponentChangeOrAdd compChange in goChange.changes)
                {
                    AssetFileInfoEx     goInfo      = table.getAssetInfo((ulong)goChange.pathId);
                    AssetTypeValueField goBaseField = am.GetATI(file, goInfo).GetBaseField();

                    AssetTypeValueField         compPptr = goBaseField.Get("m_Component").Get("Array")[(uint)compChange.componentIndex].Get("component");
                    AssetsManager.AssetExternal compExt  = am.GetExtAsset(inst, compPptr);

                    AssetFileInfoEx     compInfo      = compExt.info;
                    AssetTypeValueField compBaseField = compExt.instance.GetBaseField();

                    //UnityEngine.Debug.Log("HKWE LR " + compInfo.index);
                    AssetsReplacer imAlreadyReplacer = ComponentDiffReplacer.DiffComponent(compInfo, compBaseField, am.classFile, compChange, compInfo.index);
                    replacers.Add(imAlreadyReplacer);
                }
            }
            AssetsManager amBun = new AssetsManager();                                                                          //we create a new manager because the two filenames will probably conflict

            amBun.classFile = am.classFile;                                                                                     //we can just reuse the classfile which is kinda hacky
            AssetsFileInstance bunInst = amBun.LoadAssetsFile(new MemoryStream(GetBundleData(bunPath, 0)), "HKWEDiffs", false); //placeholder path since we have no deps

            //rearrange the pathids immediately after the
            //last one from the level to keep unity happy
            ulong levelLargestPathID = 0;

            foreach (AssetFileInfoEx inf in table.pAssetFileInfo)
            {
                if (inf.index > levelLargestPathID)
                {
                    levelLargestPathID = inf.index;
                }
            }
            ReferenceCrawler.ReorderIds(amBun, bunInst, levelLargestPathID + 1);

            byte[] bunSAInst = GetBundleData(bunPath, 1);
            //HashSet<ulong> addedDeps = new HashSet<ulong>();
            foreach (AssetFileInfoEx inf in bunInst.table.pAssetFileInfo)
            {
                replacers.Add(MakeReplacer(inf.index, am, bunInst, inst, inf, bunSAInst, types));
            }
            //foreach (GameObjectInfo inf in diffFile.infos)
            //{
            //    Debug.Log("7");
            //    ulong bunPathId = GetBundlePathId(amBun, bunInst, inf);
            //
            //    AssetFileInfoEx objInf = bunInst.table.getAssetInfo(bunPathId);
            //    replacers.Add(MakeReplacer(bunPathId, am, bunInst, inst, objInf, bunSAInst, types));
            //
            //    List<ulong> deps = ReferenceCrawler.CrawlPPtrs(amBun, bunInst, bunPathId);
            //    foreach (ulong dep in deps)
            //    {
            //        if (!addedDeps.Contains(dep))
            //        {
            //            addedDeps.Add(dep);
            //            AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep);
            //            //if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5)
            //            //{
            //            //    continue;
            //            //}
            //            replacers.Add(MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types));
            //        }
            //    }
            //    ////its possible to get a collision but very unlikely since unity already randomizes ids which are 8 bytes long
            //    ////there's nothing here to test if a collision would be created so just hope that you don't win the lottery
            //    //ulong bunPathId = GetBundlePathId(amBun, bunInst, inf);
            //    ////AssetFileInfoEx afInf = bunInst.table.getAssetInfo(bunPathId);
            //    ////replacers.Add(MakeReplacer(bunPathId, afInf, bunInst.stream));
            //    //List<ulong> deps = ReferenceCrawler.CrawlPPtrs(am, bunInst, bunPathId);
            //    ////if (info.curFileType == 0x01 || info.curFileType == 0x04 || info.curFileType == 0xD4)
            //    ////{
            //    ////    continue;
            //    ////}
            //    //foreach (ulong dep in deps)
            //    //{
            //    //    AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep);
            //    //    //MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types);
            //    //    AssetsReplacerFromMemory ar = MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types);
            //    //    //todo- I guess this was just for testing purposes to block out everything, remove this at some point
            //    //    if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5) //depInf.curFileType == 0x1C
            //    //    {
            //    //        continue;
            //    //    }
            //    //    replacers.Add(ar);
            //    //}
            //}

            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    //file.typeTree.hasTypeTree = true; //so we don't have to calculate hashes
                    //foreach (Type_0D type in file.typeTree.pTypes_Unity5)
                    //{
                    //    if (!types.Any(t => t.classId == type.classId))
                    //    {
                    //        types.Insert(0, C2T5.Cldb2TypeTree(am.classFile, type.classId));
                    //    }
                    //}
                    file.typeTree.pTypes_Unity5 = file.typeTree.pTypes_Unity5.Concat(types.ToArray()).ToArray();
                    //file.typeTree.pTypes_Unity5 = types.ToArray();
                    file.typeTree.fieldCount = (uint)file.typeTree.pTypes_Unity5.Length;
                    //file.typeTree.fieldCount = (uint)types.Count;
                    file.Write(writer, 0, replacers.ToArray(), 0);
                    data = ms.ToArray();
                }
            //File.WriteAllBytes("_bundlefinal1.unity3d", data);

            byte[]     blankDataSA = BundleCreator.CreateBlankAssets(ver, typesSA);
            AssetsFile blankFileSA = new AssetsFile(new AssetsFileReader(new MemoryStream(blankDataSA)));

            byte[] dataSA = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    blankFileSA.Write(writer, 0, assetsSA.ToArray(), 0);
                    dataSA = ms.ToArray();
                }

            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    AssetsBundleFile bundle = BundleCreator.CreateBlankBundle(ver, data.Length, dataSA.Length, sceneName);
                    bundle.Write(writer);
                    writer.Write(dataSA);
                    writer.Write(data);
                    return(ms.ToArray());
                }
        }