Beispiel #1
0
        private byte[] decryptContent(byte[] content, int contentIndex, Ticket tik, TMD tmd)
        {
            Array.Resize(ref content, Shared.AddPadding(content.Length, 16));
            byte[] titleKey = tik.TitleKey;
            byte[] iv       = new byte[16];

            byte[] tmp = BitConverter.GetBytes(tmd.Contents[contentIndex].Index);
            iv[0] = tmp[1];
            iv[1] = tmp[0];

            RijndaelManaged rm = new RijndaelManaged();

            rm.Mode      = CipherMode.CBC;
            rm.Padding   = PaddingMode.None;
            rm.KeySize   = 128;
            rm.BlockSize = 128;
            rm.Key       = titleKey;
            rm.IV        = iv;

            ICryptoTransform decryptor = rm.CreateDecryptor();

            MemoryStream ms = new MemoryStream(content);
            CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);

            byte[] decCont = new byte[content.Length];
            cs.Read(decCont, 0, decCont.Length);

            cs.Dispose();
            ms.Dispose();

            return(decCont);
        }
Beispiel #2
0
        private byte[] DecryptContent(byte[] content, int contentIndex, Ticket tik, TMD tmd)
        {
            Array.Resize(ref content, Shared.AddPadding(content.Length, 16));
            var titleKey = tik.TitleKey;
            var iv       = new byte[16];

            var tmp = BitConverter.GetBytes(tmd.Contents[contentIndex].Index);

            iv[0] = tmp[1];
            iv[1] = tmp[0];

            var rm = new RijndaelManaged()
            {
                Mode      = CipherMode.CBC,
                Padding   = PaddingMode.None,
                KeySize   = 128,
                BlockSize = 128,
                Key       = titleKey,
                IV        = iv
            };
            var decryptor = rm.CreateDecryptor();

            var ms = new MemoryStream(content);
            var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);

            var decCont = new byte[content.Length];

            cs.Read(decCont, 0, decCont.Length);

            cs.Dispose();
            ms.Dispose();

            return(decCont);
        }
Beispiel #3
0
        private void createFromDir(string path)
        {
            fireDebug("Creating U8 File from: {0}", path);

            if (path[path.Length - 1] != Path.DirectorySeparatorChar)
            {
                path += Path.DirectorySeparatorChar;
            }

            fireDebug("   Collecting Content...");
            string[] dirEntries   = getDirContent(path, true);
            int      offsetToName = 1;
            int      offsetToData = 0;

            fireDebug("   Creating U8 Header...");
            u8Header    = new U8_Header();
            rootNode    = new U8_Node();
            u8Nodes     = new List <U8_Node>();
            stringTable = new List <string>();
            data        = new List <byte[]>();

            //Create Rootnode
            fireDebug("   Creating Rootnode...");
            rootNode.Type         = U8_NodeType.Directory;
            rootNode.OffsetToName = 0;
            rootNode.OffsetToData = 0;
            rootNode.SizeOfData   = (uint)dirEntries.Length + 1;

            //Create Nodes
            for (int i = 0; i < dirEntries.Length; i++)
            {
                fireDebug("   Creating Node #{0} of {1}", i + 1, dirEntries.Length);
                fireProgress((i + 1) * 100 / dirEntries.Length);

                U8_Node tempNode = new U8_Node();
                byte[]  tempData = new byte[0];

                string tempDirEntry = dirEntries[i].Remove(0, path.Length - 1);

                if (Directory.Exists(dirEntries[i])) //It's a dir
                {
                    fireDebug("    -> Directory");

                    tempNode.Type         = U8_NodeType.Directory;
                    tempNode.OffsetToData = (uint)Shared.CountCharsInString(tempDirEntry, Path.DirectorySeparatorChar); //Recursion

                    int size = u8Nodes.Count + 2;
                    for (int j = 0; j < dirEntries.Length; j++)
                    {
                        if (dirEntries[j].Contains(dirEntries[i] + System.IO.Path.DirectorySeparatorChar.ToString()))
                        {
                            size++;
                        }
                    }

                    tempNode.SizeOfData = (uint)size;
                }
                else //It's a file
                {
                    fireDebug("    -> File");
                    fireDebug("    -> Reading File Data...");

                    tempData              = File.ReadAllBytes(dirEntries[i]);
                    tempNode.Type         = U8_NodeType.File;
                    tempNode.OffsetToData = (uint)offsetToData;
                    tempNode.SizeOfData   = (uint)tempData.Length;

                    offsetToData += Shared.AddPadding(offsetToData + tempData.Length, dataPadding);
                }

                tempNode.OffsetToName = (ushort)offsetToName;
                offsetToName         += (Path.GetFileName(dirEntries[i])).Length + 1;

                fireDebug("    -> Reading Name...");
                string tempName = Path.GetFileName(dirEntries[i]);

                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);
            }

            //Update U8 Header
            fireDebug("   Updating U8 Header...");
            u8Header.HeaderSize   = (uint)(((u8Nodes.Count + 1) * 12) + offsetToName);
            u8Header.OffsetToData = (uint)Shared.AddPadding((int)u8Header.OffsetToRootNode + (int)u8Header.HeaderSize, dataPadding);

            //Update dataOffsets
            fireDebug("   Calculating Data Offsets...");

            for (int i = 0; i < u8Nodes.Count; i++)
            {
                fireDebug("    -> Node #{0} of {1}...", i + 1, u8Nodes.Count);

                int tempOffset = (int)u8Nodes[i].OffsetToData;
                u8Nodes[i].OffsetToData = (uint)(u8Header.OffsetToData + tempOffset);
            }

            fireDebug("Creating U8 File Finished...");
        }
Beispiel #4
0
        private void writeToStream(Stream writeStream)
        {
            fireDebug("Writing U8 File...");

            //Update Rootnode
            fireDebug("   Updating Rootnode...");
            rootNode.SizeOfData = (uint)u8Nodes.Count + 1;

            MemoryStream u8Stream = new MemoryStream();

            //Write Stringtable
            u8Stream.Seek(u8Header.OffsetToRootNode + ((u8Nodes.Count + 1) * 12), SeekOrigin.Begin);

            fireDebug("   Writing String Table... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper());
            u8Stream.WriteByte(0x00);

            int stringTablePosition = (int)u8Stream.Position - 1;

            for (int i = 0; i < u8Nodes.Count; i++)
            {
                fireDebug("    -> Entry #{1} of {2}: \"{3}\"... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper(), i + 1, u8Nodes.Count, stringTable[i]);

                u8Nodes[i].OffsetToName = (ushort)(u8Stream.Position - stringTablePosition);
                byte[] stringBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(stringTable[i]);

                u8Stream.Write(stringBytes, 0, stringBytes.Length);
                u8Stream.WriteByte(0x00);
            }

            u8Header.HeaderSize   = (uint)(u8Stream.Position - u8Header.OffsetToRootNode);
            u8Header.OffsetToData = 0;

            //Write Data
            for (int i = 0; i < u8Nodes.Count; i++)
            {
                fireProgress((i + 1) * 100 / u8Nodes.Count);

                if (u8Nodes[i].Type == U8_NodeType.File)
                {
                    u8Stream.Seek(Shared.AddPadding((int)u8Stream.Position, dataPadding), SeekOrigin.Begin);

                    fireDebug("   Writing Data #{1} of {2}... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper(), i + 1, u8Nodes.Count);

                    if (u8Header.OffsetToData == 0)
                    {
                        u8Header.OffsetToData = (uint)u8Stream.Position;
                    }
                    u8Nodes[i].OffsetToData = (uint)u8Stream.Position;
                    u8Nodes[i].SizeOfData   = (uint)data[i].Length;

                    u8Stream.Write(data[i], 0, data[i].Length);
                }
                else
                {
                    fireDebug("   Node #{0} of {1} is a Directory...", i + 1, u8Nodes.Count);
                }
            }

            //Pad End to 16 bytes
            while (u8Stream.Position % 16 != 0)
            {
                u8Stream.WriteByte(0x00);
            }

            //Write Header + Nodes
            u8Stream.Seek(0, SeekOrigin.Begin);

            fireDebug("   Writing Header... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper());
            u8Header.Write(u8Stream);

            fireDebug("   Writing Rootnode... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper());
            rootNode.Write(u8Stream);

            for (int i = 0; i < u8Nodes.Count; i++)
            {
                fireDebug("   Writing Node Entry #{1} of {2}... (Offset: 0x{0})", u8Stream.Position.ToString("x8").ToUpper(), i + 1, u8Nodes.Count);
                u8Nodes[i].Write(u8Stream);
            }

            byte[] u8Array = u8Stream.ToArray();
            u8Stream.Dispose();

            if (lz77)
            {
                fireDebug("   Lz77 Compressing U8 File...");

                Lz77 l = new Lz77();
                u8Array = l.Compress(u8Array);
            }

            //Write File Header
            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Adding IMD5 Header...");

                writeStream.Seek(0, SeekOrigin.Begin);
                Headers.IMD5 h = Headers.IMD5.Create(u8Array);
                h.Write(writeStream);
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Adding IMET Header...");

                ((Headers.IMET)header).IconSize   = (uint)iconSize;
                ((Headers.IMET)header).BannerSize = (uint)bannerSize;
                ((Headers.IMET)header).SoundSize  = (uint)soundSize;

                writeStream.Seek(0, SeekOrigin.Begin);
                ((Headers.IMET)header).Write(writeStream);
            }

            writeStream.Write(u8Array, 0, u8Array.Length);

            fireDebug("Writing U8 File Finished...");
        }