public static InstallEntry Read(ref SpanReader sr) { InstallEntry entry = new InstallEntry(); entry.FileSize = sr.ReadInt64(); entry.BlockIndex = sr.ReadInt32(); entry.PathNameOffset = sr.ReadInt32(); sr.Position = entry.PathNameOffset; entry.Path = sr.ReadString0(); return(entry); }
public void Unpack(string outPath) { using var fs = new FileStream(_file, FileMode.Open); var crypto = new VolumeCryptoOld(_keys); for (int i = 0; i < Entries.Count; i++) { InstallEntry entry = Entries[i]; string outFileName = Path.Combine(outPath, entry.Path); Directory.CreateDirectory(Path.GetDirectoryName(outFileName)); Program.Log($"[:] Unpacking: {entry.Path}.. ({i + 1}/{Entries.Count})"); // Decrypt it from offset using (FileStream tempOutDecrypt = new FileStream(outFileName + ".in", FileMode.Create)) crypto.Decrypt(fs, tempOutDecrypt, DefaultSeed, (ulong)entry.FileSize, (ulong)entry.BlockIndex * BlockSize); // Decompress if needed bool isCompressed = true; using (FileStream inStream = new FileStream(outFileName + ".in", FileMode.Open)) { if (inStream.ReadUInt32() == 0xFFF7EEC5) { int size = -inStream.ReadInt32(); inStream.Position = 8; using var outDecompressStream = new FileStream(outFileName, FileMode.Create); using var ds = new DeflateStream(inStream, CompressionMode.Decompress); ds.CopyTo(outDecompressStream); } else { isCompressed = false; } } if (isCompressed) { File.Delete(outFileName + ".in"); } else { File.Move(outFileName + ".in", outFileName); } } Program.Log($"[:] Install unpack finished."); }
private void LoadToC(uint tocSize, uint fileCount, bool saveHeaderToc = false) { using var fs = new FileStream(_file, FileMode.Open); byte[] tocBuffer = new byte[tocSize]; fs.Read(tocBuffer); _keys.CryptData(tocBuffer, DefaultSeed); if (saveHeaderToc) { File.WriteAllBytes("InstallerHeaderTOC.bin", tocBuffer); } SpanReader sr = new SpanReader(tocBuffer, Endian.Big); sr.Position = 0x10; for (int i = 0; i < fileCount; i++) { sr.Position = 0x10 + (i * 0x10); var entry = InstallEntry.Read(ref sr); Entries.Add(entry); } }