public byte[] Decipher(byte[] data, bool compressed) { int length = (data.Length - 4) / 8; byte[] enc = new byte[length * 8]; for (int i = 0; i < length; i++) { int os1 = (i * 8) + 4; int os2 = i * 8; Buffer.BlockCopy(data, os1, enc, os2, 8); } enc = Utility.byteSwap(enc); enc = blowfish.Decrypt_ECB(enc); enc = Utility.byteSwap(enc); Buffer.BlockCopy(enc, 0, data, 4, enc.Length); if (compressed) { byte[] xor = Utility.xor(Utility.dStrip(data)); xor = PRS.Decompress(xor); xor = Utility.dReplace(data, xor); return(xor); } return(data); }
internal static byte[] DecompressPRC(byte[] data, bool big_endian) { ByteArray ba = new ByteArray(data); if (big_endian) { ba.Endianess = Endianess.BigEndian; } int size = ba.ReadI32(); uint key = ba.ReadU32(); byte[] result = new byte[(int)((ba.Length - 8 + 3) & 0xFFFFFFFC)]; ba.Read(result, 0, ba.Length - 8); PRC prc = new PRC(key); prc.CryptData(result, 0, result.Length, big_endian); Array.Resize(ref result, size); result = PRS.Decompress(result); return(result); }
/* To simplify the process greatly, we are going to convert * the Storybook Archive to a new format */ public override MemoryStream TranslateData(ref Stream stream) { try { /* Get the number of files */ uint files = stream.ReadUInt(0x0).SwapEndian(); /* Now create the header */ MemoryStream data = new MemoryStream(); data.Write(files); /* Write each file in the header */ uint offset = 0xC + (files * 0x2C); for (int i = 0; i < files; i++) { uint length = stream.ReadUInt(0x3C + (i * 0x30)).SwapEndian(); data.Write(offset); // Offset data.Write(length); // Length data.Write(stream.ReadString(0x10 + (i * 0x30), 36), 36); // Filename /* Let's write the decompressed data */ uint sourceOffset = stream.ReadUInt(0x34 + (i * 0x30)).SwapEndian(); uint sourceLength = stream.ReadUInt(0x38 + (i * 0x30)).SwapEndian(); Stream compressedData = stream.Copy(sourceOffset, sourceLength); /* Decompress the data */ PRS decompressor = new PRS(); MemoryStream decompressedData = decompressor.Decompress(ref compressedData, length); if (decompressedData == null) throw new Exception(); /* Write the data */ data.Position = offset; data.Write(decompressedData); data.Position = 0x30 + (i * 0x2C); decompressedData.Close(); offset += length; } return data; } catch { return new MemoryStream(); } }