Ejemplo n.º 1
0
 private static string SwapNibbles(IntPtrEx src, int len)
 {
     using (IntPtrEx pBuffer = new IntPtrEx(new byte[len]))
     {
         return(SwapNibbles(pBuffer, src, len).Read <string>());
     }
 }
Ejemplo n.º 2
0
 private static IntPtrEx SwapNibbles(IntPtrEx dst, string src, int len)
 {
     using (IntPtrEx pSrc = new IntPtrEx(src))
     {
         return(SwapNibbles(dst, pSrc, len));
     }
 }
Ejemplo n.º 3
0
        private static IntPtr DESProcessBlock(byte rounds, IntPtrEx dst, IntPtrEx src, byte[] ks, CryptoType dir)
        {
            byte[] tmp = new byte[4];

            MemCpy(src, dst, 8);

            DESPermutation(dst, DES_IP);

            if (rounds > 0)
            {
                for (int i = 0; i < rounds; i++)
                {
                    //DES_RawProcessBlock(dst, ks + (dir == CryptoType.Decrypt ? 0xF - i : i) * 8);
                    DESRawProcessBlock(dst, ks);

                    MemCpy(dst, tmp, 4);
                    MemCpy(dst + 4, dst, 4);
                    MemCpy(tmp, dst + 4, 4);
                }
            }

            MemCpy(dst, tmp, 4);
            MemCpy(dst + 4, dst, 4);
            MemCpy(tmp, dst + 4, 4);

            DESPermutation(dst, DES_IP_INV);

            return(dst);
        }
Ejemplo n.º 4
0
        private static IntPtr GRFProcess(IntPtrEx dst, IntPtrEx src, int len, byte flags, int digitsGen, byte[] ks, CryptoType dir)
        {
            int digits, i;

            if ((flags & GRFFILE_FLAG_MIXCRYPT) == GRFFILE_FLAG_MIXCRYPT)
            {
                for (i = digitsGen, digits = 0; i > 0; i /= 0xA, digits++)
                {
                    ;
                }
                if (digits < 1)
                {
                    digits = 1;
                }

                GRFMixedProcess(dst, src, len, (byte)digits, ks, dir);
            }
            else if ((flags & GRFFILE_FLAG_0x14_DES) == GRFFILE_FLAG_0x14_DES)
            {
                i = len / 8;
                if (i > 0x14)
                {
                    i = 0x14;
                    MemCpy(src + 0x14 * 8, dst + 0x14 * 8, len - 0x14 * 8);
                }

                DESProcess(dst, src, i * 8, ks, dir);
            }
            else
            {
                MemCpy(src, dst, len);
            }

            return(dst);
        }
Ejemplo n.º 5
0
        private void ReadVer2Info()
        {
            if (m_IntVersion != 0x200)
            {
                throw new GrfException();
            }

            byte[] buf = new byte[8], zbuf;
            int    len, len2;

            FileStream.Read(buf, 0, 8);
            len = EndianConverter.LittleEndian(BitConverter.ToInt32(buf, 0));

            if (0 == (len2 = EndianConverter.LittleEndian(BitConverter.ToInt32(buf, 4))))
            {
                return;
            }

            zbuf = new byte[len];
            FileStream.Read(zbuf, 0, len);

            using (IntPtrEx pBuffer = new IntPtrEx(ZlibStream.UncompressBuffer(zbuf)))
            {
                string  name = null;
                GrfItem item;

                try
                {
                    for (int i = 0, offset = 0; i < m_Items.Capacity; i++, offset += 0x11)
                    {
                        name = pBuffer.Read <string>(offset);
                        len  = name.Length + 1;

                        if (len >= GRF_NAMELEN)
                        {
                            throw new GrfException();
                        }

                        offset += len;

                        item = GrfItem.CreateV2
                               (
                            this,
                            name,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset)),
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 4)),
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 8)),
                            (GrfFileFlags)pBuffer[offset + 0xC],
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 0xD)) + GRF_HEADER_FULL_LEN
                               );

                        m_Items.GrfAdd(item);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Decrypts a filename in a <see cref="GrfArchive"/> that has a version major of 1.
 /// </summary>
 /// <param name="buffer">The input buffer of the filename.</param>
 /// <param name="len">The length of the filename.</param>
 /// <returns>A <see cref="String"/> with the decrypted filename.</returns>
 public static string DecryptNameVer1(byte[] buffer, int len)
 {
     using (IntPtrEx pBuffer = new IntPtrEx(buffer),
            pNamebuf = new IntPtrEx(new byte[len]))
     {
         GRFMixedProcess(pNamebuf, pBuffer, len, 1, KeySchedule, CryptoType.Decrypt);
         return(pNamebuf);
     }
 }
Ejemplo n.º 7
0
        private static IntPtrEx SwapNibbles(IntPtrEx dst, IntPtrEx src, int len)
        {
            for (int i = 0; i < len; i++)
            {
                dst[i] = (byte)((src[i] << 4) | (src[i] >> 4));
            }

            return(dst);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Encodes the name with the proper encoding.
 /// </summary>
 /// <param name="name">The name to encode.</param>
 /// <returns>A <see cref="String"/> with the properly encoded filename.</returns>
 public static string Encode(string name)
 {
     byte[] buffer = new byte[name.Length];
     using (IntPtrEx pName = new IntPtrEx(name))
     {
         Marshal.Copy(pName, buffer, 0, name.Length);
     }
     return Encode(buffer);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Encodes the name with the proper encoding.
 /// </summary>
 /// <param name="name">The name to encode.</param>
 /// <returns>A <see cref="String"/> with the properly encoded filename.</returns>
 public static string Encode(string name)
 {
     byte[] buffer = new byte[name.Length];
     using (IntPtrEx pName = new IntPtrEx(name))
     {
         Marshal.Copy(pName, buffer, 0, name.Length);
     }
     return(Encode(buffer));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Encrypts a filename in a <see cref="GrfArchive"/> that has a version major of 1.
 /// </summary>
 /// <param name="name">The name to encrypt.</param>
 /// <param name="len">The length of the name.</param>
 /// <returns>A <see cref="Byte"/> array containing the encrypted filename.</returns>
 public static byte[] EncryptNameVer1(string name, int len)
 {
     byte[] namebuf = new byte[len];
     using (IntPtrEx pName = new IntPtrEx(name),
            pNamebuf = new IntPtrEx(namebuf))
     {
         GRFMixedProcess(pNamebuf, pName, len, 1, KeySchedule, CryptoType.Encrypt);
         return(namebuf);
     }
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Encrypts the contents of a file inside the <see cref="GrfArchive"/>.
 /// </summary>
 /// <param name="buffer">The unencrypted contents.</param>
 /// <param name="len">The length of the contents.
 /// (Note: this is the AlignedCompressedLength, not the CompressedLength)</param>
 /// <param name="flags">The <see cref="GrfFileFlags"/> of the file.</param>
 /// <returns>A <see cref="Byte"/> array containing the encrypted contents of the file.</returns>
 public static byte[] EncryptFileBuffer(byte[] buffer, int len, GrfFileFlags flags)
 {
     byte[] dst = new byte[buffer.Length];
     using (IntPtrEx pDst = new IntPtrEx(dst),
            pBuffer = new IntPtrEx(buffer))
     {
         GRFProcess(pDst, pBuffer, buffer.Length, (byte)flags, len, m_KeySchedule, CryptoType.Encrypt);
         return(dst);
     }
 }
Ejemplo n.º 12
0
        private static IntPtr DESProcess(IntPtrEx dst, IntPtrEx src, int len, byte[] ks, CryptoType dir)
        {
            IntPtr orig = dst;

            for (int i = 0; i < len / 8; i++, dst += 8, src += 8)
            {
                DESProcessBlock(1, dst, src, ks, dir);
            }

            return(orig);
        }
Ejemplo n.º 13
0
        private static IntPtr DESRawProcessBlock(IntPtrEx block, byte[] ks)
        {
            int tmp;

            byte[][] tmpblock = new byte[2][];
            tmpblock[0] = new byte[8];
            tmpblock[1] = new byte[8];

            for (int i = 0; i < 0x30; i++)
            {
                tmp = DES_E[i] + 0x1F;
                if ((block[tmp >> 3] & BitMap[tmp & 7]) > 0)
                {
                    tmpblock[0][i / 6] |= BitMap[i % 6];
                }
            }

            for (int i = 0; i < 8; i++)
            {
                tmpblock[0][i] ^= ks[i];
            }

            for (int i = 0; i < 8; i++)
            {
                if (i % 2 > 0)
                {
                    tmpblock[1][i >> 1] += DES_S(i)[tmpblock[0][i] >> 2];
                }
                else
                {
                    tmpblock[1][i >> 1] = (byte)(DES_S(i)[tmpblock[0][i] >> 2] << 4);
                }
            }

            tmpblock[0] = new byte[8];

            for (int i = 0; i < 0x20; i++)
            {
                tmp = DES_P[i] - 1;
                if ((tmpblock[1][tmp >> 3] & BitMap[tmp & 7]) > 0)
                {
                    tmpblock[0][i >> 3] |= BitMap[i & 7];
                }
            }

            block[0] ^= tmpblock[0][0];
            block[1] ^= tmpblock[0][1];
            block[2] ^= tmpblock[0][2];
            block[3] ^= tmpblock[0][3];

            return(block);
        }
Ejemplo n.º 14
0
        private static IntPtr DESPermutation(IntPtrEx block, byte[] table)
        {
            byte[] tmpblock = new byte[8];
            byte   tmp;

            for (int i = 0; i < 0x40; i++)
            {
                tmp = (byte)(table[i] - 1);
                if ((block[tmp >> 3] & BitMap[tmp & 7]) > 0)
                {
                    tmpblock[i >> 3] |= BitMap[i & 7];
                }
            }

            MemCpy(tmpblock, block, 8);

            return(block);
        }
Ejemplo n.º 15
0
        public void IntPtrSubtractTest()
        {
            int[] arr = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            unsafe
            {
                fixed(int *parr = arr)
                {
                    // Get the size of an array element.
                    const int Size  = sizeof(int);
                    var       ptr   = IntPtrEx.Add(new IntPtr(parr), Size * (arr.Length - 1));
                    var       index = arr.Length - 1;

                    for (var ctr = 0; ctr < arr.Length; ctr++)
                    {
                        var newPtr = IntPtrEx.Subtract(ptr, ctr * Size);
                        Assert.AreEqual(arr[index], Marshal.ReadInt32(newPtr));
                        index--;
                    }
                }
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Decrypts a filename in a <see cref="GrfArchive"/> that has a version major of 1.
 /// </summary>
 /// <param name="buffer">The input buffer of the filename.</param>
 /// <param name="len">The length of the filename.</param>
 /// <returns>A <see cref="String"/> with the decrypted filename.</returns>
 public static string DecryptNameVer1(byte[] buffer, int len)
 {
     using (IntPtrEx pBuffer = new IntPtrEx(buffer),
                     pNamebuf = new IntPtrEx(new byte[len]))
     {
         GRFMixedProcess(pNamebuf, pBuffer, len, 1, KeySchedule, CryptoType.Decrypt);
         return pNamebuf;
     }
 }
Ejemplo n.º 17
0
 private static void MemCpy(IntPtrEx src, byte[] dst, int len)
 {
     Marshal.Copy(src, dst, 0, len);
 }
Ejemplo n.º 18
0
        private void FlushVer2()
        {
            byte[]      buffer = new byte[m_Items.Count * GRF_ITEM_SIZE];
            IntPtrEx    pName;
            int         i, offset, len;
            GrfFileInfo gfile = null;

            try
            {
                m_Items.SortToPosition();

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (i = offset = 0; i < Items.Count; i++)
                    {
                        len = m_Items[i].FullName.Length + 1;
                        using (pName = new IntPtrEx(m_Items[i].FullName))
                        {
                            Marshal.Copy(pName, buffer, offset, len);
                        }

                        offset += len;

                        if (m_Items[i] is GrfFileInfo)
                        {
                            gfile = (GrfFileInfo)m_Items[i];

                            if (m_ForceRepack)
                            {
                                gfile.CompressedLength        = 0;
                                gfile.AlignedCompressedLength = 0;
                                gfile.Position = 0;
                            }

                            if (gfile.CompressedLength == 0 &&
                                gfile.AlignedCompressedLength == 0 &&
                                gfile.Position == 0 &&
                                gfile.Length != 0)
                            {
                                if (!m_AllowCrypt)
                                {
                                    gfile.Flags &= ~(GrfFileFlags.MixCrypt | GrfFileFlags.Des_0x14);
                                }

                                FlushFile(i);
                            }

                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(gfile.CompressedLength));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(gfile.AlignedCompressedLength));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(gfile.Length));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(gfile.Position - GRF_HEADER_FULL_LEN));
                        }
                        else
                        {
                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZSMALL));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZFILE));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZORIG));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_OFFSET - GRF_HEADER_FULL_LEN));
                        }

                        pBuffer.Write <byte>(offset + 0xC, (byte)m_Items[i].Flags);

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            Array.Resize <byte>(ref buffer, offset);
            buffer = ZlibStream.CompressBuffer(buffer);

            m_Items.SortToPosition();

            int writeOffset = m_Items.FindUnused(8 + buffer.Length);

            if (writeOffset == 0)
            {
                FileStream.Seek(0, SeekOrigin.End);
                writeOffset = (int)FileStream.Position;
            }
            else
            {
                FileStream.Seek(writeOffset, SeekOrigin.Begin);
            }

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(buffer.Length)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(offset)), 0, 4);
            FileStream.Write(buffer, 0, buffer.Length);

            FileStream.Seek(GRF_HEADER_MID_LEN, SeekOrigin.Begin);

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(writeOffset - GRF_HEADER_FULL_LEN)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(0), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(i + 7)), 0, 4);
        }
Ejemplo n.º 19
0
        private static IntPtr GRFMixedProcess(IntPtrEx dst, IntPtrEx src, int len, byte cycle, byte[] ks, CryptoType dir)
        {
            IntPtr orig = dst;
            byte j = 0, tmp;

            if (cycle < 3)
                cycle = 1;
            else if (cycle < 5)
                cycle++;
            else if (cycle < 7)
                cycle += 9;
            else
                cycle += 0xF;

            for (int i = 0; i < len / 8; i++, dst += 8, src += 8)
            {
                if (i < 0x14 || i % cycle == 0)
                {
                    DESProcessBlock(1, dst, src, ks, dir);
                }
                else
                {
                    if (j == 7)
                    {
                        if (dir == CryptoType.Decrypt)
                        {
                            // 3450162
                            MemCpy(src + 3, dst, 2);
                            // 01_____
                            dst[2] = src[6];
                            // 012____
                            MemCpy(src, dst + 3, 3);
                            // 012345_
                            dst[6] = src[5];
                        }
                        else
                        {
                            // 0123456
                            MemCpy(src, dst + 3, 2);
                            // ___01__
                            dst[6] = src[2];
                            // ___01_2
                            MemCpy(src + 3, dst, 3);
                            // 34501_2
                            dst[5] = src[6];
                            // 3450162
                        }

                        // Modify byte 7
                        if ((tmp = src[7]) <= 0x77)
                        {
                            if (tmp == 0x77)                // 0x77
                                dst[7] = 0x48;
                            else if (tmp == 0)              // 0x00
                                dst[7] = 0x2B;
                            else if ((--tmp) == 0)          // 0x01
                                dst[7] = 0x68;
                            else if ((tmp -= 0x2A) == 0)    // 0x2B
                                dst[7] = 0x00;
                            else if ((tmp -= 0x1D) == 0)    // 0x48
                                dst[7] = 0x77;
                            else if ((tmp -= 0x18) == 0)    // 0x60
                                dst[7] = 0xFF;
                            else if ((tmp -= 0x08) == 0)    // 0x68
                                dst[7] = 0x01;
                            else if ((tmp -= 0x04) == 0)    // 0x6C
                                dst[7] = 0x80;
                            else
                                dst[7] = src[7];
                        }
                        else
                        {
                            if ((tmp -= 0x80) == 0)         // 0x80
                                dst[7] = 0x6C;
                            else if ((tmp -= 0x39) == 0)      // 0xB9
                                dst[7] = 0xC0;
                            else if ((tmp -= 0x07) == 0)      // 0xC0
                                dst[7] = 0xB9;
                            else if ((tmp -= 0x2B) == 0)      // 0xEB
                                dst[7] = 0xFE;
                            else if ((tmp -= 0x13) == 0)      // 0xFE
                                dst[7] = 0xEB;
                            else if ((--tmp) == 0)          // 0xFF
                                dst[7] = 0x60;
                            else
                                dst[7] = src[7];
                        }
                        j = 0;
                    }
                    else
                    {
                        MemCpy(src, dst, 8);
                    }
                    j++;
                }
            }

            return orig;
        }
Ejemplo n.º 20
0
 private static void MemCpy(IntPtrEx src, IntPtrEx dst, int len)
 {
     byte[] buffer = new byte[len];
     Marshal.Copy(src, buffer, 0, len);
     Marshal.Copy(buffer, 0, dst, len);
 }
Ejemplo n.º 21
0
        private static IntPtr DESPermutation(IntPtrEx block, byte[] table)
        {
            byte[] tmpblock = new byte[8];
            byte tmp;

            for (int i = 0; i < 0x40; i++)
            {
                tmp = (byte)(table[i] - 1);
                if ((block[tmp >> 3] & BitMap[tmp & 7]) > 0)
                    tmpblock[i >> 3] |= BitMap[i & 7];
            }

            MemCpy(tmpblock, block, 8);

            return block;
        }
Ejemplo n.º 22
0
        private static IntPtr DESProcessBlock(byte rounds, IntPtrEx dst, IntPtrEx src, byte[] ks, CryptoType dir)
        {
            byte[] tmp = new byte[4];

            MemCpy(src, dst, 8);

            DESPermutation(dst, DES_IP);

            if (rounds > 0)
            {
                for (int i = 0; i < rounds; i++)
                {
                    //DES_RawProcessBlock(dst, ks + (dir == CryptoType.Decrypt ? 0xF - i : i) * 8);
                    DESRawProcessBlock(dst, ks);

                    MemCpy(dst, tmp, 4);
                    MemCpy(dst + 4, dst, 4);
                    MemCpy(tmp, dst + 4, 4);
                }
            }

            MemCpy(dst, tmp, 4);
            MemCpy(dst + 4, dst, 4);
            MemCpy(tmp, dst + 4, 4);

            DESPermutation(dst, DES_IP_INV);

            return dst;
        }
Ejemplo n.º 23
0
 private static void MemCpy(IntPtrEx src, byte[] dst, int len)
 {
     Marshal.Copy(src, dst, 0, len);
 }
Ejemplo n.º 24
0
        private void ReadVer1Info()
        {
            if (m_IntVersion > 0x103)
                throw new GrfException();

            int offset = (int)FileStream.Position;
            int len2, len = (int)FileStream.Length - offset;
            byte[] buffer = new byte[len], namebuf = new byte[GRF_NAMELEN];

            try
            {
                FileStream.Read(buffer, 0, len);

                string name = null;
                GrfItem item;

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (int i = offset = 0; i < m_Items.Capacity; i++)
                    {
                        len = EndianConverter.LittleEndian(pBuffer.Read<int>(offset));
                        offset += 4;

                        if (m_IntVersion < 0x101)
                        {
                            len2 = pBuffer.Read<string>(offset).Length;
                            if (len2 >= GRF_NAMELEN)
                                throw new GrfException();

                            name = SwapNibbles(pBuffer + offset, len2);
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            offset += 2;
                            len2 = len - 6;
                            if (len2 >= GRF_NAMELEN)
                                throw new GrfException();

                            SwapNibbles(namebuf, pBuffer + offset, len2);
                            name = GrfCrypt.DecryptNameVer1(namebuf, len2);

                            len -= 2;
                        }

                        offset += len;

                        item = GrfItem.CreateV1
                        (
                            this,
                            name,
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset)) - EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 8)) - 0x02CB,
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 4)) - 0x92CB,
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 8)),
                            (GrfFileFlags)pBuffer[offset + 0xC],
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 0xD)) + GRF_HEADER_FULL_LEN
                        );

                        m_Items.GrfAdd(item);

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
Ejemplo n.º 25
0
 private static void MemCpy(IntPtrEx src, IntPtrEx dst, int len)
 {
     byte[] buffer = new byte[len];
     Marshal.Copy(src, buffer, 0, len);
     Marshal.Copy(buffer, 0, dst, len);
 }
Ejemplo n.º 26
0
 private static string SwapNibbles(IntPtrEx src, int len)
 {
     using (IntPtrEx pBuffer = new IntPtrEx(new byte[len]))
     {
         return SwapNibbles(pBuffer, src, len).Read<string>();
     }
 }
Ejemplo n.º 27
0
        private void ReadVer2Info()
        {
            if (m_IntVersion != 0x200)
                throw new GrfException();

            byte[] buf = new byte[8], zbuf;
            int len, len2;

            FileStream.Read(buf, 0, 8);
            len = EndianConverter.LittleEndian(BitConverter.ToInt32(buf, 0));

            if (0 == (len2 = EndianConverter.LittleEndian(BitConverter.ToInt32(buf, 4))))
                return;

            zbuf = new byte[len];
            FileStream.Read(zbuf, 0, len);

            using (IntPtrEx pBuffer = new IntPtrEx(ZlibStream.UncompressBuffer(zbuf)))
            {
                string name = null;
                GrfItem item;

                try
                {
                    for (int i = 0, offset = 0; i < m_Items.Capacity; i++, offset += 0x11)
                    {
                        name = pBuffer.Read<string>(offset);
                        len = name.Length + 1;

                        if (len >= GRF_NAMELEN)
                            throw new GrfException();

                        offset += len;

                        item = GrfItem.CreateV2
                        (
                            this,
                            name,
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset)),
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 4)),
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 8)),
                            (GrfFileFlags)pBuffer[offset + 0xC],
                            EndianConverter.LittleEndian(pBuffer.Read<int>(offset + 0xD)) + GRF_HEADER_FULL_LEN
                        );

                        m_Items.GrfAdd(item);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }
Ejemplo n.º 28
0
        private void ReadHeader()
        {
            if (FileStream.CanWrite && FileStream.Length < 1)
            {
                byte[] zbuf        = ZlibStream.CompressBuffer(new byte[0]);
                byte[] zero        = new byte[4];
                int    zlen_le     = EndianConverter.LittleEndian(zbuf.Length),
                       zero_fcount = EndianConverter.LittleEndian(7),
                       create_ver  = EndianConverter.LittleEndian(m_IntVersion);

                FileStream.Write(Encoding.ASCII.GetBytes(GRF_HEADER), 0, GRF_HEADER_LEN);
                FileStream.Write(CryptWatermark, 0, CryptWatermark.Length);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(BitConverter.GetBytes(zero_fcount), 0, 4);
                FileStream.Write(BitConverter.GetBytes(create_ver), 0, 4);
                FileStream.Write(BitConverter.GetBytes(zlen_le), 0, 4);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(zbuf, 0, zbuf.Length);

                FileStream.Seek(0, SeekOrigin.Begin);
            }

            byte[] buf = new byte[GRF_HEADER_FULL_LEN];
            FileStream.Read(buf, 0, buf.Length);

            if (buf[GRF_HEADER_LEN + 1] == 1)
            {
                m_AllowCrypt = true;
                // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E
                for (byte i = 0; i < 0xF; i++)
                {
                    if (buf[GRF_HEADER_LEN + i] != i)
                    {
                        throw new GrfException();
                    }
                }
            }
            else if (buf[GRF_HEADER_LEN] == 0)
            {
                m_AllowCrypt = false;
                // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                for (byte i = 0; i < 0xF; i++)
                {
                    if (buf[GRF_HEADER_LEN + i] != 0)
                    {
                        throw new GrfException();
                    }
                }
            }
            else
            {
                throw new GrfException();
            }

            using (IntPtrEx pBuffer = new IntPtrEx(buf))
            {
                m_Items = new GrfItemCollection(this);

                m_IntVersion     = EndianConverter.LittleEndian(pBuffer.Read <int>(GRF_HEADER_MID_LEN + 0xC));
                m_Items.Capacity = EndianConverter.LittleEndian(pBuffer.Read <int>(GRF_HEADER_MID_LEN + 8))
                                   - EndianConverter.LittleEndian(pBuffer.Read <int>(GRF_HEADER_MID_LEN + 4))
                                   - 7;

                FileStream.Seek(EndianConverter.LittleEndian(pBuffer.Read <int>(GRF_HEADER_MID_LEN) + GRF_HEADER_FULL_LEN), SeekOrigin.Begin);
            }

            switch (m_IntVersion & 0xFF00)
            {
            case 0x0200: ReadVer2Info(); break;

            case 0x0100: ReadVer1Info(); break;

            default: throw new GrfException();
            }
        }
Ejemplo n.º 29
0
        private void ReadVer1Info()
        {
            if (m_IntVersion > 0x103)
            {
                throw new GrfException();
            }

            int offset = (int)FileStream.Position;
            int len2, len = (int)FileStream.Length - offset;

            byte[] buffer = new byte[len], namebuf = new byte[GRF_NAMELEN];

            try
            {
                FileStream.Read(buffer, 0, len);

                string  name = null;
                GrfItem item;

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (int i = offset = 0; i < m_Items.Capacity; i++)
                    {
                        len     = EndianConverter.LittleEndian(pBuffer.Read <int>(offset));
                        offset += 4;

                        if (m_IntVersion < 0x101)
                        {
                            len2 = pBuffer.Read <string>(offset).Length;
                            if (len2 >= GRF_NAMELEN)
                            {
                                throw new GrfException();
                            }

                            name = SwapNibbles(pBuffer + offset, len2);
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            offset += 2;
                            len2    = len - 6;
                            if (len2 >= GRF_NAMELEN)
                            {
                                throw new GrfException();
                            }

                            SwapNibbles(namebuf, pBuffer + offset, len2);
                            name = GrfCrypt.DecryptNameVer1(namebuf, len2);

                            len -= 2;
                        }

                        offset += len;

                        item = GrfItem.CreateV1
                               (
                            this,
                            name,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset)) - EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 8)) - 0x02CB,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 4)) - 0x92CB,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 8)),
                            (GrfFileFlags)pBuffer[offset + 0xC],
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 0xD)) + GRF_HEADER_FULL_LEN
                               );

                        m_Items.GrfAdd(item);

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Encrypts the contents of a file inside the <see cref="GrfArchive"/>.
 /// </summary>
 /// <param name="buffer">The unencrypted contents.</param>
 /// <param name="len">The length of the contents.
 /// (Note: this is the AlignedCompressedLength, not the CompressedLength)</param>
 /// <param name="flags">The <see cref="GrfFileFlags"/> of the file.</param>
 /// <returns>A <see cref="Byte"/> array containing the encrypted contents of the file.</returns>
 public static byte[] EncryptFileBuffer(byte[] buffer, int len, GrfFileFlags flags)
 {
     byte[] dst = new byte[buffer.Length];
     using (IntPtrEx pDst = new IntPtrEx(dst),
                     pBuffer = new IntPtrEx(buffer))
     {
         GRFProcess(pDst, pBuffer, buffer.Length, (byte)flags, len, m_KeySchedule, CryptoType.Encrypt);
         return dst;
     }
 }
Ejemplo n.º 31
0
        private void ReadHeader()
        {
            if (FileStream.CanWrite && FileStream.Length < 1)
            {
                byte[] zbuf = ZlibStream.CompressBuffer(new byte[0]);
                byte[] zero = new byte[4];
                int zlen_le = EndianConverter.LittleEndian(zbuf.Length),
                    zero_fcount = EndianConverter.LittleEndian(7),
                    create_ver = EndianConverter.LittleEndian(m_IntVersion);

                FileStream.Write(Encoding.ASCII.GetBytes(GRF_HEADER), 0, GRF_HEADER_LEN);
                FileStream.Write(CryptWatermark, 0, CryptWatermark.Length);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(BitConverter.GetBytes(zero_fcount), 0, 4);
                FileStream.Write(BitConverter.GetBytes(create_ver), 0, 4);
                FileStream.Write(BitConverter.GetBytes(zlen_le), 0, 4);
                FileStream.Write(zero, 0, 4);
                FileStream.Write(zbuf, 0, zbuf.Length);

                FileStream.Seek(0, SeekOrigin.Begin);
            }

            byte[] buf = new byte[GRF_HEADER_FULL_LEN];
            FileStream.Read(buf, 0, buf.Length);

            if (buf[GRF_HEADER_LEN + 1] == 1)
            {
                m_AllowCrypt = true;
                // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E
                for (byte i = 0; i < 0xF; i++)
                    if (buf[GRF_HEADER_LEN + i] != i)
                        throw new GrfException();
            }
            else if (buf[GRF_HEADER_LEN] == 0)
            {
                m_AllowCrypt = false;
                // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                for (byte i = 0; i < 0xF; i++)
                    if (buf[GRF_HEADER_LEN + i] != 0)
                        throw new GrfException();
            }
            else
            {
                throw new GrfException();
            }

            using (IntPtrEx pBuffer = new IntPtrEx(buf))
            {
                m_Items = new GrfItemCollection(this);

                m_IntVersion = EndianConverter.LittleEndian(pBuffer.Read<int>(GRF_HEADER_MID_LEN + 0xC));
                m_Items.Capacity = EndianConverter.LittleEndian(pBuffer.Read<int>(GRF_HEADER_MID_LEN + 8))
                    - EndianConverter.LittleEndian(pBuffer.Read<int>(GRF_HEADER_MID_LEN + 4))
                    - 7;

                FileStream.Seek(EndianConverter.LittleEndian(pBuffer.Read<int>(GRF_HEADER_MID_LEN) + GRF_HEADER_FULL_LEN), SeekOrigin.Begin);
            }

            switch (m_IntVersion & 0xFF00)
            {
                case 0x0200: ReadVer2Info(); break;
                case 0x0100: ReadVer1Info(); break;
                default: throw new GrfException();
            }
        }
Ejemplo n.º 32
0
 /// <summary>
 /// Encrypts a filename in a <see cref="GrfArchive"/> that has a version major of 1.
 /// </summary>
 /// <param name="name">The name to encrypt.</param>
 /// <param name="len">The length of the name.</param>
 /// <returns>A <see cref="Byte"/> array containing the encrypted filename.</returns>
 public static byte[] EncryptNameVer1(string name, int len)
 {
     byte[] namebuf = new byte[len];
     using (IntPtrEx pName = new IntPtrEx(name),
                     pNamebuf = new IntPtrEx(namebuf))
     {
         GRFMixedProcess(pNamebuf, pName, len, 1, KeySchedule, CryptoType.Encrypt);
         return namebuf;
     }
 }
Ejemplo n.º 33
0
        private void FlushVer2()
        {
            byte[] buffer = new byte[m_Items.Count * GRF_ITEM_SIZE];
            IntPtrEx pName;
            int i, offset, len;
            GrfFileInfo gfile = null;

            try
            {
                m_Items.SortToPosition();

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (i = offset = 0; i < Items.Count; i++)
                    {
                        len = m_Items[i].FullName.Length + 1;
                        using (pName = new IntPtrEx(m_Items[i].FullName))
                        {
                            Marshal.Copy(pName, buffer, offset, len);
                        }

                        offset += len;

                        if (m_Items[i] is GrfFileInfo)
                        {
                            gfile = (GrfFileInfo)m_Items[i];

                            if (m_ForceRepack)
                            {
                                gfile.CompressedLength = 0;
                                gfile.AlignedCompressedLength = 0;
                                gfile.Position = 0;
                            }

                            if (gfile.CompressedLength == 0 &&
                                gfile.AlignedCompressedLength == 0 &&
                                gfile.Position == 0 &&
                                gfile.Length != 0)
                            {
                                if (!m_AllowCrypt)
                                    gfile.Flags &= ~(GrfFileFlags.MixCrypt | GrfFileFlags.Des_0x14);

                                FlushFile(i);
                            }

                            pBuffer.Write<int>(offset, EndianConverter.LittleEndian(gfile.CompressedLength));
                            pBuffer.Write<int>(offset + 4, EndianConverter.LittleEndian(gfile.AlignedCompressedLength));
                            pBuffer.Write<int>(offset + 8, EndianConverter.LittleEndian(gfile.Length));
                            pBuffer.Write<int>(offset + 0xD, EndianConverter.LittleEndian(gfile.Position - GRF_HEADER_FULL_LEN));
                        }
                        else
                        {
                            pBuffer.Write<int>(offset, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZSMALL));
                            pBuffer.Write<int>(offset + 4, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZFILE));
                            pBuffer.Write<int>(offset + 8, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZORIG));
                            pBuffer.Write<int>(offset + 0xD, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_OFFSET - GRF_HEADER_FULL_LEN));
                        }

                        pBuffer.Write<byte>(offset + 0xC, (byte)m_Items[i].Flags);

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            Array.Resize<byte>(ref buffer, offset);
            buffer = ZlibStream.CompressBuffer(buffer);

            m_Items.SortToPosition();

            int writeOffset = m_Items.FindUnused(8 + buffer.Length);
            if (writeOffset == 0)
            {
                FileStream.Seek(0, SeekOrigin.End);
                writeOffset = (int)FileStream.Position;
            }
            else
            {
                FileStream.Seek(writeOffset, SeekOrigin.Begin);
            }

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(buffer.Length)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(offset)), 0, 4);
            FileStream.Write(buffer, 0, buffer.Length);

            FileStream.Seek(GRF_HEADER_MID_LEN, SeekOrigin.Begin);

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(writeOffset - GRF_HEADER_FULL_LEN)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(0), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(i + 7)), 0, 4);
        }
Ejemplo n.º 34
0
        private static IntPtr DESProcess(IntPtrEx dst, IntPtrEx src, int len, byte[] ks, CryptoType dir)
        {
            IntPtr orig = dst;
            for (int i = 0; i < len / 8; i++, dst += 8, src += 8)
                DESProcessBlock(1, dst, src, ks, dir);

            return orig;
        }
Ejemplo n.º 35
0
        private void FlushVer1()
        {
            byte[] buffer = new byte[m_Items.Count * GRF_ITEM_SIZE];
            int i, offset, len, writeOffset;
            GrfFileInfo gfile = null;

            try
            {
                m_Items.SortToPosition();

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (i = offset = 0; i < Items.Count; i++)
                    {
                        if (m_Items[i] is GrfFileInfo)
                        {
                            gfile = (GrfFileInfo)m_Items[i];

                            if (m_ForceRepack)
                            {
                                gfile.CompressedLength = 0;
                                gfile.AlignedCompressedLength = 0;
                                gfile.Position = 0;
                            }

                            if (gfile.CompressedLength == 0 &&
                                gfile.AlignedCompressedLength == 0 &&
                                gfile.Position == 0 &&
                                gfile.Length != 0)
                            {
                                if (gfile.CheckExtension())
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.MixCrypt) | GrfFileFlags.Des_0x14;
                                else
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.Des_0x14) | GrfFileFlags.MixCrypt;

                                FlushFile(i);
                            }
                        }

                        len = m_Items[i].FullName.Length + 1;
                        if (m_IntVersion < 0x101)
                        {
                            pBuffer.Write<int>(offset, len);
                            SwapNibbles(pBuffer + offset + 4, m_Items[i].FullName, len);
                            offset += 4 + len;
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            pBuffer.Write<int>(offset, len + 6);
                            offset += 4;
                            SwapNibbles(pBuffer + offset + 6, GrfCrypt.EncryptNameVer1(m_Items[i].Name, len), len);
                            offset += len + 6;
                        }

                        if (m_Items[i] is GrfDirectoryInfo)
                        {
                            pBuffer.Write<int>(offset, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZSMALL + GrfItem.GRFFILE_DIR_SZORIG + 0x02CB));
                            pBuffer.Write<int>(offset + 4, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZFILE + 0x92CB));
                            pBuffer.Write<int>(offset + 8, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZORIG));
                            pBuffer.Write<int>(offset + 0xD, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_OFFSET - GRF_HEADER_FULL_LEN));
                        }
                        else
                        {
                            pBuffer.Write<int>(offset, EndianConverter.LittleEndian(gfile.CompressedLength + gfile.Length + 0x02CB));
                            pBuffer.Write<int>(offset + 4, EndianConverter.LittleEndian(gfile.AlignedCompressedLength + 0x92CB));
                            pBuffer.Write<int>(offset + 8, EndianConverter.LittleEndian(gfile.Length));
                            pBuffer.Write<int>(offset + 0xD, EndianConverter.LittleEndian(gfile.Position - GRF_HEADER_FULL_LEN));
                        }

                        pBuffer.Write<byte>(offset + 0xC, (byte)(m_Items[i].Flags & GrfFileFlags.File));

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            FileStream.Seek(0, SeekOrigin.End);
            writeOffset = (int)FileStream.Position;
            FileStream.Write(buffer, 0, offset);
            FileStream.Seek(GRF_HEADER_MID_LEN, SeekOrigin.End);

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(writeOffset - GRF_HEADER_FULL_LEN)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(0), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(i + 0 + 7)), 0, 4);
        }
Ejemplo n.º 36
0
        private static IntPtr DESRawProcessBlock(IntPtrEx block, byte[] ks)
        {
            int tmp;
            byte[][] tmpblock = new byte[2][];
            tmpblock[0] = new byte[8];
            tmpblock[1] = new byte[8];

            for (int i = 0; i < 0x30; i++)
            {
                tmp = DES_E[i] + 0x1F;
                if ((block[tmp >> 3] & BitMap[tmp & 7]) > 0)
                    tmpblock[0][i / 6] |= BitMap[i % 6];
            }

            for (int i = 0; i < 8; i++)
                tmpblock[0][i] ^= ks[i];

            for (int i = 0; i < 8; i++)
            {
                if (i % 2 > 0)
                    tmpblock[1][i >> 1] += DES_S(i)[tmpblock[0][i] >> 2];
                else
                    tmpblock[1][i >> 1] = (byte)(DES_S(i)[tmpblock[0][i] >> 2] << 4);
            }

            tmpblock[0] = new byte[8];

            for (int i = 0; i < 0x20; i++)
            {
                tmp = DES_P[i] - 1;
                if ((tmpblock[1][tmp >> 3] & BitMap[tmp & 7]) > 0)
                    tmpblock[0][i >> 3] |= BitMap[i & 7];
            }

            block[0] ^= tmpblock[0][0];
            block[1] ^= tmpblock[0][1];
            block[2] ^= tmpblock[0][2];
            block[3] ^= tmpblock[0][3];

            return block;
        }
Ejemplo n.º 37
0
        private static IntPtrEx SwapNibbles(IntPtrEx dst, IntPtrEx src, int len)
        {
            for (int i = 0; i < len; i++)
                dst[i] = (byte)((src[i] << 4) | (src[i] >> 4));

            return dst;
        }
Ejemplo n.º 38
0
        private static IntPtr GRFProcess(IntPtrEx dst, IntPtrEx src, int len, byte flags, int digitsGen, byte[] ks, CryptoType dir)
        {
            int digits, i;
            if ((flags & GRFFILE_FLAG_MIXCRYPT) == GRFFILE_FLAG_MIXCRYPT)
            {
                for (i = digitsGen, digits = 0; i > 0; i /= 0xA, digits++) ;
                if (digits < 1) digits = 1;

                GRFMixedProcess(dst, src, len, (byte)digits, ks, dir);
            }
            else if ((flags & GRFFILE_FLAG_0x14_DES) == GRFFILE_FLAG_0x14_DES)
            {
                i = len / 8;
                if (i > 0x14)
                {
                    i = 0x14;
                    MemCpy(src + 0x14 * 8, dst + 0x14 * 8, len - 0x14 * 8);
                }

                DESProcess(dst, src, i * 8, ks, dir);
            }
            else
            {
                MemCpy(src, dst, len);
            }

            return dst;
        }
Ejemplo n.º 39
0
        private static IntPtr GRFMixedProcess(IntPtrEx dst, IntPtrEx src, int len, byte cycle, byte[] ks, CryptoType dir)
        {
            IntPtr orig = dst;
            byte   j = 0, tmp;

            if (cycle < 3)
            {
                cycle = 1;
            }
            else if (cycle < 5)
            {
                cycle++;
            }
            else if (cycle < 7)
            {
                cycle += 9;
            }
            else
            {
                cycle += 0xF;
            }

            for (int i = 0; i < len / 8; i++, dst += 8, src += 8)
            {
                if (i < 0x14 || i % cycle == 0)
                {
                    DESProcessBlock(1, dst, src, ks, dir);
                }
                else
                {
                    if (j == 7)
                    {
                        if (dir == CryptoType.Decrypt)
                        {
                            // 3450162
                            MemCpy(src + 3, dst, 2);
                            // 01_____
                            dst[2] = src[6];
                            // 012____
                            MemCpy(src, dst + 3, 3);
                            // 012345_
                            dst[6] = src[5];
                        }
                        else
                        {
                            // 0123456
                            MemCpy(src, dst + 3, 2);
                            // ___01__
                            dst[6] = src[2];
                            // ___01_2
                            MemCpy(src + 3, dst, 3);
                            // 34501_2
                            dst[5] = src[6];
                            // 3450162
                        }

                        // Modify byte 7
                        if ((tmp = src[7]) <= 0x77)
                        {
                            if (tmp == 0x77)                // 0x77
                            {
                                dst[7] = 0x48;
                            }
                            else if (tmp == 0)              // 0x00
                            {
                                dst[7] = 0x2B;
                            }
                            else if ((--tmp) == 0)          // 0x01
                            {
                                dst[7] = 0x68;
                            }
                            else if ((tmp -= 0x2A) == 0)    // 0x2B
                            {
                                dst[7] = 0x00;
                            }
                            else if ((tmp -= 0x1D) == 0)    // 0x48
                            {
                                dst[7] = 0x77;
                            }
                            else if ((tmp -= 0x18) == 0)    // 0x60
                            {
                                dst[7] = 0xFF;
                            }
                            else if ((tmp -= 0x08) == 0)    // 0x68
                            {
                                dst[7] = 0x01;
                            }
                            else if ((tmp -= 0x04) == 0)    // 0x6C
                            {
                                dst[7] = 0x80;
                            }
                            else
                            {
                                dst[7] = src[7];
                            }
                        }
                        else
                        {
                            if ((tmp -= 0x80) == 0)         // 0x80
                            {
                                dst[7] = 0x6C;
                            }
                            else if ((tmp -= 0x39) == 0)      // 0xB9
                            {
                                dst[7] = 0xC0;
                            }
                            else if ((tmp -= 0x07) == 0)      // 0xC0
                            {
                                dst[7] = 0xB9;
                            }
                            else if ((tmp -= 0x2B) == 0)      // 0xEB
                            {
                                dst[7] = 0xFE;
                            }
                            else if ((tmp -= 0x13) == 0)      // 0xFE
                            {
                                dst[7] = 0xEB;
                            }
                            else if ((--tmp) == 0)          // 0xFF
                            {
                                dst[7] = 0x60;
                            }
                            else
                            {
                                dst[7] = src[7];
                            }
                        }
                        j = 0;
                    }
                    else
                    {
                        MemCpy(src, dst, 8);
                    }
                    j++;
                }
            }

            return(orig);
        }
Ejemplo n.º 40
0
 private static void MemCpy(byte[] src, IntPtrEx dst, int len)
 {
     Marshal.Copy(src, 0, dst, len);
 }
Ejemplo n.º 41
0
 private static IntPtrEx SwapNibbles(IntPtrEx dst, string src, int len)
 {
     using (IntPtrEx pSrc = new IntPtrEx(src))
     {
         return SwapNibbles(dst, pSrc, len);
     }
 }
Ejemplo n.º 42
0
 private static void MemCpy(byte[] src, IntPtrEx dst, int len)
 {
     Marshal.Copy(src, 0, dst, len);
 }
Ejemplo n.º 43
0
        private void FlushVer1()
        {
            byte[]      buffer = new byte[m_Items.Count * GRF_ITEM_SIZE];
            int         i, offset, len, writeOffset;
            GrfFileInfo gfile = null;

            try
            {
                m_Items.SortToPosition();

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (i = offset = 0; i < Items.Count; i++)
                    {
                        if (m_Items[i] is GrfFileInfo)
                        {
                            gfile = (GrfFileInfo)m_Items[i];

                            if (m_ForceRepack)
                            {
                                gfile.CompressedLength        = 0;
                                gfile.AlignedCompressedLength = 0;
                                gfile.Position = 0;
                            }

                            if (gfile.CompressedLength == 0 &&
                                gfile.AlignedCompressedLength == 0 &&
                                gfile.Position == 0 &&
                                gfile.Length != 0)
                            {
                                if (gfile.CheckExtension())
                                {
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.MixCrypt) | GrfFileFlags.Des_0x14;
                                }
                                else
                                {
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.Des_0x14) | GrfFileFlags.MixCrypt;
                                }

                                FlushFile(i);
                            }
                        }

                        len = m_Items[i].FullName.Length + 1;
                        if (m_IntVersion < 0x101)
                        {
                            pBuffer.Write <int>(offset, len);
                            SwapNibbles(pBuffer + offset + 4, m_Items[i].FullName, len);
                            offset += 4 + len;
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            pBuffer.Write <int>(offset, len + 6);
                            offset += 4;
                            SwapNibbles(pBuffer + offset + 6, GrfCrypt.EncryptNameVer1(m_Items[i].Name, len), len);
                            offset += len + 6;
                        }

                        if (m_Items[i] is GrfDirectoryInfo)
                        {
                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZSMALL + GrfItem.GRFFILE_DIR_SZORIG + 0x02CB));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZFILE + 0x92CB));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZORIG));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_OFFSET - GRF_HEADER_FULL_LEN));
                        }
                        else
                        {
                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(gfile.CompressedLength + gfile.Length + 0x02CB));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(gfile.AlignedCompressedLength + 0x92CB));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(gfile.Length));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(gfile.Position - GRF_HEADER_FULL_LEN));
                        }

                        pBuffer.Write <byte>(offset + 0xC, (byte)(m_Items[i].Flags & GrfFileFlags.File));

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            FileStream.Seek(0, SeekOrigin.End);
            writeOffset = (int)FileStream.Position;
            FileStream.Write(buffer, 0, offset);
            FileStream.Seek(GRF_HEADER_MID_LEN, SeekOrigin.End);

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(writeOffset - GRF_HEADER_FULL_LEN)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(0), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(i + 0 + 7)), 0, 4);
        }