コード例 #1
0
        public bool Read()
        {
            var numBlocks = (int)(io.Stream.Length / BLOCK_SZ);

            if (numBlocks != NUM_BLOCKS_IN_FAT)
            {
                return(false); // invalid image
            }
            var ret = ReadFilesystem();

            if (!ret)
            {
                return(false); // failed to find valid FAT
            }
            SKSA = new iQueKernel(GetSKSAData());
            SKSA.Read();

            int idx = GetInodeIdx("cert.sys");

            if (idx >= 0)
            {
                var data = GetInodeData(MainFsInodes[idx]);
                Certs = new iQueCertCollection(data);
                if (iQueCertCollection.MainCollection == null)
                {
                    iQueCertCollection.MainCollection = new iQueCertCollection(data); // MainCollection wasn't loaded already, so lets try loading it from this nand (yolo)
                }
            }

            idx            = GetInodeIdx("depot.sys");
            HasPrivateData = idx >= 0;
            if (HasPrivateData)
            {
                var data = GetInodeData(MainFsInodes[idx]);
                PrivateData = Shared.BytesToStruct <iQuePrivateData>(data);
                //PrivateData.EndianSwap();
            }

            idx = GetInodeIdx("ticket.sys");
            if (idx >= 0)
            {
                var data = GetInodeData(MainFsInodes[idx]);
                Tickets = new iQueArrayFile <iQueTitleData>(data);
                for (int i = 0; i < Tickets.Count; i++)
                {
                    Tickets[i] = Tickets[i].EndianSwap();
                }
            }

            idx = GetInodeIdx("crl.sys");
            if (idx >= 0)
            {
                var data = GetInodeData(MainFsInodes[idx]);
                CRL = new iQueArrayFile <iQueCertificateRevocation>(data);
                foreach (var crl in CRL)
                {
                    crl.EndianSwap();
                }
            }

            // todo:
            // recrypt.sys
            // timer.sys
            // sig.db

            return(true);
        }
コード例 #2
0
        public bool SetSKSAData(byte[] sksaData)
        {
            var sksa = new iQueKernel(sksaData);

            sksa.Read();

            // write SK data
            io.Stream.Position = 0;
            io.Writer.Write(sksa.SKData);

            int lastDataBlock = -1;
            int curDataBlock  = NUM_SK_BLOCKS;

            // write SA1 ticket area
            int sa1TicketBlock = curDataBlock;

            io.Stream.Position = curDataBlock * BLOCK_SZ;
            io.Writer.Write(new byte[BLOCK_SZ]);
            io.Stream.Position = curDataBlock * BLOCK_SZ;
            io.Writer.Write(sksa.SA1SigArea.GetBytes());

            // get next good block after SA1 ticket (which will be SA1 final block)
            curDataBlock = GetNextGoodBlock(curDataBlock);
            int sa1FinalDataBlock = curDataBlock;

            int numDataBlocks = (int)(sksa.SA1SigArea.Ticket.ContentSize / BLOCK_SZ);

            for (int i = numDataBlocks - 1; i >= 0; i--)
            {
                byte[] data = new byte[BLOCK_SZ];
                Array.Copy(sksa.SA1Data, i * BLOCK_SZ, data, 0, BLOCK_SZ);

                io.Stream.Position = curDataBlock * BLOCK_SZ;
                io.Writer.Write(data);

                lastDataBlock = curDataBlock;
                curDataBlock  = GetNextGoodBlock(curDataBlock);
            }

            if (sksa.SA2IsValid)
            {
                // write SA2 ticket area
                int sa2TicketBlock = curDataBlock;
                io.Stream.Position = curDataBlock * BLOCK_SZ;
                io.Writer.Write(new byte[BLOCK_SZ]);
                io.Stream.Position = curDataBlock * BLOCK_SZ;
                io.Writer.Write(sksa.SA2SigArea.GetBytes());

                // get next good block after SA2 ticket (which will be SA2 final block)
                curDataBlock = GetNextGoodBlock(curDataBlock);
                int sa2FinalDataBlock = curDataBlock;

                numDataBlocks = (int)(sksa.SA2SigArea.Ticket.ContentSize / BLOCK_SZ);
                for (int i = numDataBlocks - 1; i >= 0; i--)
                {
                    byte[] data = new byte[BLOCK_SZ];
                    Array.Copy(sksa.SA2Data, i * BLOCK_SZ, data, 0, BLOCK_SZ);

                    io.Stream.Position = curDataBlock * BLOCK_SZ;
                    io.Writer.Write(data);

                    lastDataBlock = curDataBlock;
                    curDataBlock  = GetNextGoodBlock(curDataBlock);
                }
            }

            io.Stream.Flush();

            Console.WriteLine("Updated SKSA!");
            Console.WriteLine("Wrote updated nand to " + FilePath);

            // reload this.SKSA
            SKSA = new iQueKernel(GetSKSAData());
            SKSA.Read();

            return(true);
        }