Beispiel #1
0
        /*
         * Outputs the specific XOR key for the given version.
         *
         * @param version The pack file version
         * @param key The outputted key block
         *
         */
        public static void GetXorKey(PackVersion version, out byte[] key)
        {
            switch (version)
            {
            case PackVersion.MS2F:
                key = MS2F_XOR.Value;
                break;

            case PackVersion.NS2F:
                key = NS2F_XOR.Value;
                break;

            case PackVersion.OS2F:
                key = OS2F_XOR.Value;
                break;

            case PackVersion.PS2F:
                key = PS2F_XOR.Value;
                break;

            default:
            {
                // Nexon always defaults to MS2F here.
                key = MS2F_XOR.Value;
                break;
            }
            }
        }
Beispiel #2
0
 public PackFileHeaderVer3(PackVersion version, BinaryReader reader) : this(version) {
     this.BufferFlag         = (Encryption)reader.ReadUInt32(); //[ecx+8]
     this.FileIndex          = reader.ReadInt32();              //[ecx+12]
     this.EncodedFileSize    = reader.ReadUInt32();             //[ecx+16]
     this.reserved[0]        = reader.ReadInt32();              //[ecx+20]
     this.CompressedFileSize = reader.ReadUInt64();             //[ecx+24] | [ecx+28]
     this.FileSize           = reader.ReadUInt64();             //[ecx+32] | [ecx+36]
     this.Offset             = reader.ReadUInt64();             //[ecx+40] | [ecx+44]
 }
 public static PackStreamVer3 ParseHeader(BinaryReader reader, PackVersion version)
 {
     return(new PackStreamVer3(version)
     {
         FileListCount = reader.ReadUInt32(),
         reserved = reader.ReadUInt32(),
         CompressedDataSize = reader.ReadUInt64(),
         EncodedDataSize = reader.ReadUInt64(),
         CompressedHeaderSize = reader.ReadUInt64(),
         EncodedHeaderSize = reader.ReadUInt64(),
         DataSize = reader.ReadUInt64(),
         HeaderSize = reader.ReadUInt64()
     });
 }
Beispiel #4
0
        public static PackFileHeaderVer3 CreateHeader(PackVersion version, int index, Encryption flag, ulong offset, byte[] data)
        {
            CryptoManager.Encrypt(version, data, flag, out uint size, out uint compressedSize, out uint encodedSize);

            return(new PackFileHeaderVer3(version)
            {
                BufferFlag = flag,
                FileIndex = index,
                EncodedFileSize = encodedSize,
                CompressedFileSize = compressedSize,
                FileSize = size,
                Offset = offset
            });
        }
Beispiel #5
0
        /*
         * Outputs the Key and IV blocks for the specified version.
         *
         * @param version The pack file version
         * @param uKeyOffset The key index to output (this is compressedSize)
         * @param userKey The outputted Key block
         * @param ivChain The outputted IV (CTR) block
         *
         */
        public static void GetKeyAndIV(PackVersion version, uint keyOffset, out byte[] userKey, out byte[] ivChain)
        {
            IMultiArray key;
            IMultiArray iv;

            switch (version)
            {
            case PackVersion.MS2F:
                key = MS2F_KEY;
                iv  = MS2F_IV;
                break;

            case PackVersion.NS2F:
                key = NS2F_KEY;
                iv  = NS2F_IV;
                break;

            case PackVersion.OS2F:
                key = OS2F_KEY;
                iv  = OS2F_IV;
                break;

            case PackVersion.PS2F:
                key = PS2F_KEY;
                iv  = PS2F_IV;
                break;

            default:
            {
                throw new Exception("ERROR generating Key/IV: the specified package version does not exist!");
            }
            }

            userKey = new byte[KEY_LEN];
            ivChain = new byte[IV_LEN];
            for (int i = 0; i < KEY_LEN; i++)
            {
                userKey[i] = key[(keyOffset & 0x7F)][i];

                if (i < IV_LEN)
                {
                    ivChain[i] = iv[(keyOffset & 0x7F)][i];
                }
            }
        }
Beispiel #6
0
        private static byte[] EncryptXor(PackVersion version, byte[] src, uint size, uint sizeCompressed)
        {
            CipherKeys.GetXorKey(version, out byte[] key);

            uint uBlock       = size >> 2;
            uint uBlockOffset = 0;
            int  nKeyOffset   = 0;

            if (uBlock != 0)
            {
                while (uBlockOffset < uBlock)
                {
                    uint pBlockData = BitConverter.ToUInt32(src, (int)(4 * uBlockOffset)) ^
                                      BitConverter.ToUInt32(key, 4 * nKeyOffset);
                    Buffer.BlockCopy(BitConverter.GetBytes(pBlockData), 0, src, (int)(4 * uBlockOffset),
                                     sizeof(uint));

                    nKeyOffset = ((ushort)nKeyOffset + 1) & 0x1FF;
                    uBlockOffset++;
                }
            }

            uBlock = (size & 3);
            if (uBlock != 0)
            {
                int nStart = (int)(4 * uBlockOffset);

                uBlockOffset = 0;
                nKeyOffset   = 0;

                while (uBlockOffset < uBlock)
                {
                    src[nStart + uBlockOffset++] ^= (byte)(key[nKeyOffset]);

                    nKeyOffset = ((ushort)nKeyOffset + 1) & 0x7FF;
                }
            }

            return(src);
        }
Beispiel #7
0
        // Decryption Routine: Base64 -> AES -> Zlib
        private static byte[] Decrypt(PackVersion version, uint size, uint sizeCompressed, Encryption flag, byte[] src)
        {
            if (flag.HasFlag(Encryption.Aes))
            {
                // Get the AES Key/IV for transformation
                CipherKeys.GetKeyAndIV(version, sizeCompressed, out byte[] key, out byte[] iv);

                // Decode the base64 encoded string
                src = Convert.FromBase64String(Encoding.UTF8.GetString(src));

                // Decrypt the AES encrypted block
                AESCipher pCipher = new AESCipher(key, iv);
                pCipher.TransformBlock(src, 0, size, src, 0);
            }
            else if (flag.HasFlag(Encryption.Xor))
            {
                // Decrypt the XOR encrypted block
                src = EncryptXor(version, src, size, sizeCompressed);
            }

            return(flag.HasFlag(Encryption.Zlib) ? ZlibStream.UncompressBuffer(src) : src);
        }
        // Encryption Routine: Zlib -> AES -> Base64
        public static byte[] Encrypt(PackVersion version, byte[] src, Encryption flag, out uint size,
                                     out uint sizeCompressed, out uint sizeEncoded)
        {
            byte[] pEncrypted;
            if (flag.HasFlag(Encryption.Zlib))
            {
                pEncrypted = ZlibStream.CompressBuffer(src);
            }
            else
            {
                pEncrypted = new byte[src.Length];
                Buffer.BlockCopy(src, 0, pEncrypted, 0, src.Length);
            }

            size           = (uint)src.Length;
            sizeCompressed = (uint)pEncrypted.Length;

            if (flag.HasFlag(Encryption.Aes))
            {
                // Get the AES Key/IV for transformation
                CipherKeys.GetKeyAndIV(version, sizeCompressed, out byte[] key, out byte[] iv);

                // Perform AES block encryption
                var pCipher = new AESCipher(key, iv);
                pCipher.TransformBlock(pEncrypted, 0, size, pEncrypted, 0);

                // Encode the encrypted data into a base64 encoded string
                pEncrypted = Encoding.UTF8.GetBytes(Convert.ToBase64String(pEncrypted));
            }
            else if (flag.HasFlag(Encryption.Xor))
            {
                // Perform XOR block encryption
                pEncrypted = EncryptXor(version, pEncrypted, size, sizeCompressed);
            }

            sizeEncoded = (uint)pEncrypted.Length;

            return(pEncrypted);
        }
Beispiel #9
0
 private PackFileHeaderVer3(PackVersion version)
 {
     this.Version  = version;
     this.reserved = new int[1];
 }
Beispiel #10
0
 private PackStreamVer3(PackVersion version)
 {
     this.Version  = version;
     this.FileList = new List <PackFileEntry>();
 }
Beispiel #11
0
 private PackFileHeaderVer3(PackVersion version)
 {
     Version  = version;
     Reserved = new int[1];
 }