Beispiel #1
0
        /// <summary>
        /// Creates a WAD file from contents.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="tik"></param>
        /// <param name="tmd"></param>
        /// <param name="contents"></param>
        public void CreateNew(CertificateChain cert, Ticket tik, TMD tmd, byte[][] contents)
        {
            this.cert = cert;
            this.tik = tik;
            this.tmd = tmd;
            this.contents = new List<byte[]>(contents);

            this.wadHeader = new WAD_Header();
            this.wadHeader.TmdSize = (uint)(484 + (tmd.Contents.Length * 36));

            int contentSize = 0;
            for (int i = 0; i < contents.Length - 1; i++)
                contentSize += Shared.AddPadding(contents[i].Length);

            contentSize += contents[contents.Length - 1].Length;

            this.wadHeader.ContentSize = (uint)contentSize;

            for (int i = 0; i < this.tmd.Contents.Length; i++)
                if (this.tmd.Contents[i].Index == 0x0000)
                {
                    try { this.bannerApp.LoadFile(contents[i]); hasBanner = true; }
                    catch { hasBanner = false; } //Probably System Wad => No Banner App...
                    break;
                }
        }
Beispiel #2
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing && !isDisposed)
            {
                sha.Clear();
                sha = null;

                wadHeader = null;

                cert.Dispose();
                tik.Dispose();
                tmd.Dispose();

                contents.Clear();
                contents = null;

                bannerApp.Dispose();

                footer = null;
            }

            isDisposed = true;
        }
Beispiel #3
0
        private void parseWad(Stream wadFile)
        {
            fireDebug("Parsing Wad...");

            wadFile.Seek(0, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            wadHeader = new WAD_Header();
            contents = new List<byte[]>();

            //Read Header
            fireDebug("   Parsing Header... (Offset: 0x{0})", wadFile.Position.ToString("x8").ToUpper());
            wadFile.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != wadHeader.HeaderSize)
                throw new Exception("Invalid Headersize!");

            wadFile.Read(temp, 0, 4);
            wadHeader.WadType = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            wadFile.Seek(12, SeekOrigin.Current);

            wadFile.Read(temp, 0, 4);
            wadHeader.TmdSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            wadFile.Read(temp, 0, 4);
            wadHeader.ContentSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            wadFile.Read(temp, 0, 4);
            wadHeader.FooterSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            //Read Cert
            fireDebug("   Parsing Certificate Chain... (Offset: 0x{0})", wadFile.Position.ToString("x8").ToUpper());
            wadFile.Seek(Shared.AddPadding((int)wadFile.Position), SeekOrigin.Begin);

            temp = new byte[wadHeader.CertSize];
            wadFile.Read(temp, 0, temp.Length);
            cert.LoadFile(temp);

            //Read Tik
            fireDebug("   Parsing Ticket... (Offset: 0x{0})", wadFile.Position.ToString("x8").ToUpper());
            wadFile.Seek(Shared.AddPadding((int)wadFile.Position), SeekOrigin.Begin);

            temp = new byte[wadHeader.TicketSize];
            wadFile.Read(temp, 0, temp.Length);
            tik.LoadFile(temp);

            //Read Tmd
            fireDebug("   Parsing TMD... (Offset: 0x{0})", wadFile.Position.ToString("x8").ToUpper());
            wadFile.Seek(Shared.AddPadding((int)wadFile.Position), SeekOrigin.Begin);

            temp = new byte[wadHeader.TmdSize];
            wadFile.Read(temp, 0, temp.Length);
            tmd.LoadFile(temp);

            if (tmd.TitleID != tik.TitleID)
                fireWarning("The Title ID in the Ticket doesn't match the one in the TMD!");

            //Read Content
            for (int i = 0; i < tmd.NumOfContents; i++)
            {
                fireProgress((i + 1) * 100 / tmd.NumOfContents);

                fireDebug("   Reading Content #{0} of {1}... (Offset: 0x{2})", i + 1, tmd.NumOfContents, wadFile.Position.ToString("x8").ToUpper());
                fireDebug("    -> Content ID: 0x{0}", tmd.Contents[i].ContentID.ToString("x8"));
                fireDebug("    -> Index: 0x{0}", tmd.Contents[i].Index.ToString("x4"));
                fireDebug("    -> Type: 0x{0} ({1})", ((ushort)tmd.Contents[i].Type).ToString("x4"), tmd.Contents[i].Type.ToString());
                fireDebug("    -> Size: {0} bytes", tmd.Contents[i].Size);
                fireDebug("    -> Hash: {0}", Shared.ByteArrayToString(tmd.Contents[i].Hash));

                wadFile.Seek(Shared.AddPadding((int)wadFile.Position), SeekOrigin.Begin);

                temp = new byte[Shared.AddPadding((int)tmd.Contents[i].Size, 16)];
                wadFile.Read(temp, 0, temp.Length);

                //Decrypt Content
                temp = decryptContent(temp, i);
                Array.Resize(ref temp, (int)tmd.Contents[i].Size);

                byte[] tmdHash = tmd.Contents[i].Hash;
                byte[] newHash = sha.ComputeHash(temp, 0, (int)tmd.Contents[i].Size);

                if (!Shared.CompareByteArrays(tmdHash, newHash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Content #{0} (Content ID: 0x{1}; Index: 0x{2}): Hashes do not match! The content might be corrupted!", i + 1, tmd.Contents[i].ContentID.ToString("x8"), tmd.Contents[i].Index.ToString("x4")));
                }

                contents.Add(temp);

                if (tmd.Contents[i].Index == 0x0000)
                {
                    try { bannerApp.LoadFile(temp); hasBanner = true; }
                    catch { hasBanner = false; } //Probably System Wad => No Banner App...
                }
            }

            //Read Footer
            if (wadHeader.FooterSize > 0)
            {
                fireDebug("   Reading Footer... (Offset: 0x{0})", wadFile.Position.ToString("x8").ToUpper());
                footer = new byte[wadHeader.FooterSize];

                wadFile.Seek(Shared.AddPadding((int)wadFile.Position), SeekOrigin.Begin);
                wadFile.Read(footer, 0, footer.Length);

                parseFooterTimestamp();
            }

            fireDebug("Parsing Wad Finished...");
        }