예제 #1
0
 /// <summary>
 /// Checks whether a file is Lz77 compressed or not.
 /// </summary>
 /// <param name="file"></param>
 /// <returns></returns>
 public static bool IsLz77Compressed(Stream file)
 {
     Headers.HeaderType headerType = Headers.DetectHeader(file);
     byte[]             buffer     = new byte[4];
     file.Seek((long)headerType, SeekOrigin.Begin);
     file.Read(buffer, 0, buffer.Length);
     return((int)Shared.Swap(BitConverter.ToUInt32(buffer, 0)) == (int)lz77Magic);
 }
예제 #2
0
 /// <summary>
 /// Checks whether a file is Lz77 compressed or not.
 /// </summary>
 /// <param name="file"></param>
 /// <returns></returns>
 public static bool IsLz77Compressed(Stream file)
 {
     Headers.HeaderType h    = Headers.DetectHeader(file);
     byte[]             temp = new byte[4];
     file.Seek((long)h, SeekOrigin.Begin);
     file.Read(temp, 0, temp.Length);
     return(Shared.Swap(BitConverter.ToUInt32(temp, 0)) == lz77Magic);
 }
예제 #3
0
        /// <summary>
        /// Adds an IMET Header to the U8 file.
        /// </summary>
        /// <param name="shortImet"></param>
        /// <param name="titles"></param>
        public void AddHeaderImet(bool shortImet, params string[] titles)
        {
            if (iconSize == -1)
            {
                throw new Exception("icon.bin wasn't found!");
            }
            else if (bannerSize == -1)
            {
                throw new Exception("banner.bin wasn't found!");
            }
            else if (soundSize == -1)
            {
                throw new Exception("sound.bin wasn't found!");
            }

            header     = Headers.IMET.Create(shortImet, iconSize, bannerSize, soundSize, titles);
            headerType = (shortImet) ? Headers.HeaderType.ShortIMET : Headers.HeaderType.IMET;
        }
예제 #4
0
        /// <summary>
        /// Checks whether a file is a U8 file or not.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static bool IsU8(byte[] file)
        {
            if (Lz77.IsLz77Compressed(file))
            {
                byte[] partOfFile = new byte[(file.Length > 2000) ? 2000 : file.Length];

                for (int i = 0; i < partOfFile.Length; i++)
                {
                    partOfFile[i] = file[i];
                }

                Lz77 l = new Lz77();
                partOfFile = l.Decompress(partOfFile);

                return(IsU8(partOfFile));
            }
            else
            {
                Headers.HeaderType h = Headers.DetectHeader(file);
                return(Shared.Swap(BitConverter.ToUInt32(file, (int)h)) == 0x55AA382D);
            }
        }
예제 #5
0
파일: U8.cs 프로젝트: bram777/nusdownloader
        private void parseU8(Stream u8File)
        {
            fireDebug("Pasing U8 File...");

            u8Header = new U8_Header();
            rootNode = new U8_Node();
            u8Nodes = new List<U8_Node>();
            stringTable = new List<string>();
            data = new List<byte[]>();

            fireDebug("   Detecting Header...");
            headerType = Headers.DetectHeader(u8File);
            Headers.HeaderType tempType = headerType;

            fireDebug("    -> {0}", headerType.ToString());

            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Reading IMD5 Header...");
                header = Headers.IMD5.Load(u8File);

                byte[] file = new byte[u8File.Length];
                u8File.Read(file, 0, file.Length);

                MD5 m = MD5.Create();
                byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType);
                m.Clear();

                if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!"));
                }
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Reading IMET Header...");
                header = Headers.IMET.Load(u8File);

                if (!((Headers.IMET)header).HashesMatch)
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!"));
                }
            }

            fireDebug("   Checking for Lz77 Compression...");
            if (Lz77.IsLz77Compressed(u8File))
            {
                fireDebug("    -> Lz77 Compression Found...");
                fireDebug("   Decompressing U8 Data...");

                Lz77 l = new Lz77();
                Stream decompressedFile = l.Decompress(u8File);

                tempType = Headers.DetectHeader(decompressedFile);
                u8File = decompressedFile;

                lz77 = true;
            }

            u8File.Seek((int)tempType, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            //Read U8 Header
            fireDebug("   Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic)
            { fireDebug("    -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!"); }

            fireDebug("   Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode)
            { fireDebug("    -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!"); }

            fireDebug("   Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            fireDebug("   Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Seek(16, SeekOrigin.Current);

            //Read Rootnode
            fireDebug("   Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            rootNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
            rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

            u8File.Read(temp, 0, 4);
            rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Read(temp, 0, 4);
            rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12);
            int nodePosition = (int)u8File.Position;

            //Read Nodes
            for (int i = 0; i < rootNode.SizeOfData - 1; i++)
            {
                fireDebug("   Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1);
                fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1)));

                U8_Node tempNode = new U8_Node();
                string tempName = string.Empty;
                byte[] tempData = new byte[0];

                //Read Node Entry
                u8File.Seek(nodePosition, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                u8File.Read(temp, 0, 4);
                tempNode.Type = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
                tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

                u8File.Read(temp, 0, 4);
                tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                u8File.Read(temp, 0, 4);
                tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                nodePosition = (int)u8File.Position;

                fireDebug("        -> {0}", tempNode.Type.ToString());

                //Read Node Name
                u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                for (;;)
                {
                    char tempChar = (char)u8File.ReadByte();
                    if (tempChar == 0x00) break;

                    tempName += tempChar;

                    if (tempName.Length > 255) break;
                }

                fireDebug("        -> {0}", tempName);

                //Read Node Data
                if (tempNode.Type == U8_NodeType.File)
                {
                    u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin);

                    fireDebug("    -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());

                    tempData = new byte[tempNode.SizeOfData];
                    u8File.Read(tempData, 0, tempData.Length);
                }

                if (tempName.ToLower() == "icon.bin") iconSize = getRealSize(tempData);
                else if (tempName.ToLower() == "banner.bin") bannerSize = getRealSize(tempData);
                else if (tempName.ToLower() == "sound.bin") soundSize = getRealSize(tempData);

                u8Nodes.Add(tempNode);
                stringTable.Add(tempName);
                data.Add(tempData);
            }

            fireDebug("Pasing U8 File Finished...");
        }
예제 #6
0
파일: U8.cs 프로젝트: bram777/nusdownloader
 /// <summary>
 /// Adds an IMD5 Header to the U8 file.
 /// </summary>
 public void AddHeaderImd5()
 {
     headerType = Headers.HeaderType.IMD5;
 }
예제 #7
0
파일: U8.cs 프로젝트: bram777/nusdownloader
        /// <summary>
        /// Adds an IMET Header to the U8 file.
        /// </summary>
        /// <param name="shortImet"></param>
        /// <param name="titles"></param>
        public void AddHeaderImet(bool shortImet, params string[] titles)
        {
            if (iconSize == -1)
                throw new Exception("icon.bin wasn't found!");
            else if (bannerSize == -1)
                throw new Exception("banner.bin wasn't found!");
            else if (soundSize == -1)
                throw new Exception("sound.bin wasn't found!");

            header = Headers.IMET.Create(shortImet, iconSize, bannerSize, soundSize, titles);
            headerType = (shortImet) ? Headers.HeaderType.ShortIMET : Headers.HeaderType.IMET;
        }
예제 #8
0
        private void parseU8(Stream u8File)
        {
            fireDebug("Pasing U8 File...");

            u8Header    = new U8_Header();
            rootNode    = new U8_Node();
            u8Nodes     = new List <U8_Node>();
            stringTable = new List <string>();
            data        = new List <byte[]>();

            fireDebug("   Detecting Header...");
            headerType = Headers.DetectHeader(u8File);
            Headers.HeaderType tempType = headerType;

            fireDebug("    -> {0}", headerType.ToString());

            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Reading IMD5 Header...");
                header = Headers.IMD5.Load(u8File);

                byte[] file = new byte[u8File.Length];
                u8File.Read(file, 0, file.Length);

                MD5    m       = MD5.Create();
                byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType);
                m.Clear();

                if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!"));
                }
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Reading IMET Header...");
                header = Headers.IMET.Load(u8File);

                if (!((Headers.IMET)header).HashesMatch)
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!"));
                }
            }

            fireDebug("   Checking for Lz77 Compression...");
            if (Lz77.IsLz77Compressed(u8File))
            {
                fireDebug("    -> Lz77 Compression Found...");
                fireDebug("   Decompressing U8 Data...");

                Lz77   l = new Lz77();
                Stream decompressedFile = l.Decompress(u8File);

                tempType = Headers.DetectHeader(decompressedFile);
                u8File   = decompressedFile;

                lz77 = true;
            }

            u8File.Seek((int)tempType, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            //Read U8 Header
            fireDebug("   Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic)
            {
                fireDebug("    -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!");
            }

            fireDebug("   Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode)
            {
                fireDebug("    -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!");
            }

            fireDebug("   Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            fireDebug("   Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Seek(16, SeekOrigin.Current);

            //Read Rootnode
            fireDebug("   Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            rootNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
            rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

            u8File.Read(temp, 0, 4);
            rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Read(temp, 0, 4);
            rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12);
            int nodePosition        = (int)u8File.Position;

            //Read Nodes
            for (int i = 0; i < rootNode.SizeOfData - 1; i++)
            {
                fireDebug("   Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1);
                fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1)));

                U8_Node tempNode = new U8_Node();
                string  tempName = string.Empty;
                byte[]  tempData = new byte[0];

                //Read Node Entry
                u8File.Seek(nodePosition, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                u8File.Read(temp, 0, 4);
                tempNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
                tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

                u8File.Read(temp, 0, 4);
                tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                u8File.Read(temp, 0, 4);
                tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                nodePosition = (int)u8File.Position;

                fireDebug("        -> {0}", tempNode.Type.ToString());

                //Read Node Name
                u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                for (;;)
                {
                    char tempChar = (char)u8File.ReadByte();
                    if (tempChar == 0x00)
                    {
                        break;
                    }

                    tempName += tempChar;

                    if (tempName.Length > 255)
                    {
                        break;
                    }
                }

                fireDebug("        -> {0}", tempName);

                //Read Node Data
                if (tempNode.Type == U8_NodeType.File)
                {
                    u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin);

                    fireDebug("    -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());

                    tempData = new byte[tempNode.SizeOfData];
                    u8File.Read(tempData, 0, tempData.Length);
                }

                if (tempName.ToLower() == "icon.bin")
                {
                    iconSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "banner.bin")
                {
                    bannerSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "sound.bin")
                {
                    soundSize = getRealSize(tempData);
                }

                u8Nodes.Add(tempNode);
                stringTable.Add(tempName);
                data.Add(tempData);
            }

            fireDebug("Pasing U8 File Finished...");
        }
예제 #9
0
 /// <summary>
 /// Adds an IMD5 Header to the U8 file.
 /// </summary>
 public void AddHeaderImd5()
 {
     headerType = Headers.HeaderType.IMD5;
 }
예제 #10
0
 /// <summary>
 /// Checks whether a file is Lz77 compressed or not.
 /// </summary>
 /// <param name="file"></param>
 /// <returns></returns>
 public static bool IsLz77Compressed(byte[] file)
 {
     Headers.HeaderType headerType = Headers.DetectHeader(file);
     return((int)Shared.Swap(BitConverter.ToUInt32(file, (int)headerType)) == (int)lz77Magic);
 }
예제 #11
0
        private Stream PrivDecompress(Stream inFile)
        {
            if (!IsLz77Compressed(inFile))
            {
                return(inFile);
            }

            inFile.Seek(0L, SeekOrigin.Begin);
            uint num1 = 0;

            Headers.HeaderType headerType = Headers.DetectHeader(inFile);
            byte[]             buffer     = new byte[8];
            inFile.Seek((long)headerType, SeekOrigin.Begin);
            inFile.Read(buffer, 0, 8);
            if ((int)Shared.Swap(BitConverter.ToUInt32(buffer, 0)) != (int)lz77Magic)
            {
                inFile.Dispose();
                throw new Exception("Invaild Magic!");
            }
            if (buffer[4] != 16)
            {
                inFile.Dispose();
                throw new Exception("Unsupported Compression Type!");
            }
            uint num2 = BitConverter.ToUInt32(buffer, 4) >> 8;

            for (int index = 0; index < 4078; ++index)
            {
                textBuffer[index] = 223;
            }

            int          num3         = 4078;
            uint         num4         = 7;
            int          num5         = 7;
            MemoryStream memoryStream = new MemoryStream();

label_10:
            while (true)
            {
                num4 <<= 1;
                ++num5;
                if (num5 == 8)
                {
                    int num6;
                    if ((num6 = inFile.ReadByte()) != -1)
                    {
                        num4 = (uint)num6;
                        num5 = 0;
                    }
                    else
                    {
                        goto label_24;
                    }
                }
                if (((int)num4 & 128) == 0)
                {
                    int num6;
                    if ((num6 = inFile.ReadByte()) != inFile.Length - 1L)
                    {
                        if (num1 < num2)
                        {
                            memoryStream.WriteByte((byte)num6);
                        }

                        ushort[] textBuffer = this.textBuffer;
                        int      index      = num3;
                        int      num7       = index + 1;
                        int      num8       = (byte)num6;
                        textBuffer[index] = (ushort)num8;
                        num3 = num7 & 4095;
                        ++num1;
                    }
                    else
                    {
                        goto label_24;
                    }
                }
                else
                {
                    break;
                }
            }
            int num9;
            int num10;

            if ((num9 = inFile.ReadByte()) != -1 && (num10 = inFile.ReadByte()) != -1)
            {
                int num6 = num10 | num9 << 8 & 3840;
                int num7 = (num9 >> 4 & 15) + 2;
                for (int index1 = 0; index1 <= num7; ++index1)
                {
                    int num8 = this.textBuffer[num3 - num6 - 1 & 4095];
                    if (num1 < num2)
                    {
                        memoryStream.WriteByte((byte)num8);
                    }

                    ushort[] textBuffer = this.textBuffer;
                    int      index2     = num3;
                    int      num11      = index2 + 1;
                    int      num12      = (byte)num8;
                    textBuffer[index2] = (ushort)num12;
                    num3 = num11 & 4095;
                    ++num1;
                }
                goto label_10;
            }
label_24:
            return(memoryStream);
        }
예제 #12
0
        private Stream decompress(Stream inFile)
        {
            if (!Lz77.IsLz77Compressed(inFile))
            {
                return(inFile);
            }
            inFile.Seek(0, SeekOrigin.Begin);

            int  i, j, k, r, c, z;
            uint flags, decompressedSize, currentSize = 0;

            Headers.HeaderType h = Headers.DetectHeader(inFile);

            byte[] temp = new byte[8];
            inFile.Seek((int)h, SeekOrigin.Begin);
            inFile.Read(temp, 0, 8);

            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != lz77Magic)
            {
                inFile.Dispose(); throw new Exception("Invaild Magic!");
            }
            if (temp[4] != 0x10)
            {
                inFile.Dispose(); throw new Exception("Unsupported Compression Type!");
            }

            decompressedSize = (BitConverter.ToUInt32(temp, 4)) >> 8;

            for (i = 0; i < N - F; i++)
            {
                textBuffer[i] = 0xdf;
            }
            r = N - F; flags = 7; z = 7;

            MemoryStream outFile = new MemoryStream();

            while (true)
            {
                flags <<= 1;
                z++;

                if (z == 8)
                {
                    if ((c = inFile.ReadByte()) == -1)
                    {
                        break;
                    }

                    flags = (uint)c;
                    z     = 0;
                }

                if ((flags & 0x80) == 0)
                {
                    if ((c = inFile.ReadByte()) == inFile.Length - 1)
                    {
                        break;
                    }
                    if (currentSize < decompressedSize)
                    {
                        outFile.WriteByte((byte)c);
                    }

                    textBuffer[r++] = (byte)c;
                    r &= (N - 1);
                    currentSize++;
                }
                else
                {
                    if ((i = inFile.ReadByte()) == -1)
                    {
                        break;
                    }
                    if ((j = inFile.ReadByte()) == -1)
                    {
                        break;
                    }

                    j = j | ((i << 8) & 0xf00);
                    i = ((i >> 4) & 0x0f) + threshold;
                    for (k = 0; k <= i; k++)
                    {
                        c = textBuffer[(r - j - 1) & (N - 1)];
                        if (currentSize < decompressedSize)
                        {
                            outFile.WriteByte((byte)c);
                        }
                        textBuffer[r++] = (byte)c; r &= (N - 1); currentSize++;
                    }
                }
            }

            return(outFile);
        }