Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            //Check that at least one argument has been passed to the application
            if (args.Length == 0)
            {
                //If not, show usage and quit
                PrintUsage();
                Environment.Exit(1);
            }

            Console.WriteLine();

            //Find all targetted files
            List <string> targetfiles = new List <string>();

            foreach (string filepattern in args)
            {
                targetfiles.AddRange(FilePatternResolver.resolve(filepattern));
            }

            //Process the files one by one
            List <NCCHInfoEntry> entries = new List <NCCHInfoEntry>();

            foreach (string file in targetfiles)
            {
                Parser parser = new Parser();
                List <NCCHInfoEntry> newentries = parser.parse(file);
                entries.AddRange(newentries);

                Console.WriteLine();
            }

            //Generate the output file
            FileStream     outputfile = File.Open("ncchinfo.bin", FileMode.Create);
            BinaryWriter   writer     = new BinaryWriter(outputfile, Encoding.ASCII);
            NCCHInfoHeader header     = new NCCHInfoHeader((UInt32)entries.Count);

            writer.Write(StructMarshaling.StructToBytes <NCCHInfoHeader>(header));
            foreach (NCCHInfoEntry entry in entries)
            {
                writer.Write(StructMarshaling.StructToBytes <NCCHInfoEntry>(entry));
            }
            writer.Close();

            //Signal completion
            Console.WriteLine("Done!");
        }
Ejemplo n.º 2
0
        private List <NCCHInfoEntry> parseNCSD(BinaryReader reader)
        {
            Console.WriteLine("Parsing NCSD in file \"{0}\"", (reader.BaseStream as FileStream).Name);
            reader.BaseStream.Position = 0;

            byte[]     headerbytes = reader.ReadBytes(Marshal.SizeOf(typeof(NCSDHeader)));
            NCSDHeader header      = StructMarshaling.BytesToStruct <NCSDHeader>(headerbytes);

            string titleID = ByteArrayTo3DSIdentifier(header.titleId);

            List <NCCHInfoEntry> entries = new List <NCCHInfoEntry>();

            for (uint i = 0; i <= header.partitionTable.GetUpperBound(0); ++i)
            {
                PartitionEntry currententry = header.partitionTable[i];
                if (currententry.offset != 0)
                {
                    List <NCCHInfoEntry> newentries = parseNCCH(reader, currententry.offset * MEDIAUNITSIZE, i, titleID, false);
                    entries.AddRange(newentries);
                }
            }

            return(entries);
        }
Ejemplo n.º 3
0
        private List <NCCHInfoEntry> parseNCCH(BinaryReader reader, uint offset = 0, uint idx = 0, string titleID = "", bool standalone = true)
        {
            string indent = standalone ? "  " : "    ";

            if (standalone)
            {
                Console.WriteLine("Parsing NCCH in file " + (reader.BaseStream as FileStream).Name);
            }
            else
            {
                Console.WriteLine("  Parsing {0} NCCH", GetPartitionName(idx));
            }

            //Read the NCCH header
            reader.BaseStream.Position = offset;
            byte[]     headerbytes = reader.ReadBytes(Marshal.SizeOf(typeof(NCCHHeader)));
            NCCHHeader header      = StructMarshaling.BytesToStruct <NCCHHeader>(headerbytes);

            if (titleID.Equals(""))
            {
                titleID = ByteArrayTo3DSIdentifier(header.titleId);
            }

            //Find keyY
            byte[] keyY = new byte[16];
            Array.Copy(header.signature, 0, keyY, 0, keyY.Length);

            //Print info
            if (!standalone)
            {
                Console.WriteLine(indent + "NCCH offset: {0:X8}", offset);
            }
            Console.WriteLine(indent + "Product code: " + Encoding.ASCII.GetString(header.productCode).TrimEnd((char)0x00));
            if (!standalone)
            {
                Console.WriteLine(indent + "Partition number: {0}", idx);
            }
            Console.WriteLine(indent + "KeyY: {0}", ToHexString(keyY));
            Console.WriteLine(indent + "Title ID: {0}", ByteArrayTo3DSIdentifier(header.titleId));
            Console.WriteLine(indent + "Format version: {0}", header.formatVersion);

            bool uses7xCrypto   = (header.flags[3] != 0x00);
            bool usesSeedCrypto = (header.flags[3] == 0x20);

            if (uses7xCrypto)
            {
                Console.WriteLine(indent + "Uses 7.x NCCH crypto");
            }
            if (usesSeedCrypto)
            {
                Console.WriteLine(indent + "Uses 9.x SEED crypto");
            }

            Console.WriteLine();

            List <NCCHInfoEntry> entries = new List <NCCHInfoEntry>();
            NCCHInfoEntry        entry;

            if (header.exhdrSize != 0)
            {
                entry = parseNCCHSection(header, NCCHSection.ExHeader, keyY, false, false, true, indent);
                byte[] namebytes = Encoding.UTF8.GetBytes(genOutName(titleID, GetPartitionName(idx), "exheader"));
                Array.Copy(namebytes, 0, entry.outputname, 0, namebytes.Length);
                entries.Add(entry);
                Console.WriteLine();
            }

            if (header.exefsSize != 0)
            {
                //We need generate two xorpads for exefs if it uses 7.x crypto, since only a part of it uses the new crypto.
                entry = parseNCCHSection(header, NCCHSection.ExeFS, keyY, false, false, true, indent);
                byte[] namebytes = Encoding.UTF8.GetBytes(genOutName(titleID, GetPartitionName(idx), "exefs_norm"));
                Array.Copy(namebytes, 0, entry.outputname, 0, namebytes.Length);
                entries.Add(entry);
                if (uses7xCrypto)
                {
                    entry     = parseNCCHSection(header, NCCHSection.ExeFS, keyY, uses7xCrypto, usesSeedCrypto, false, indent);
                    namebytes = Encoding.UTF8.GetBytes(genOutName(titleID, GetPartitionName(idx), "exefs_7x"));
                    Array.Copy(namebytes, 0, entry.outputname, 0, namebytes.Length);
                    entries.Add(entry);
                }
                Console.WriteLine();
            }

            if (header.romfsSize != 0)
            {
                entry = parseNCCHSection(header, NCCHSection.RomFS, keyY, uses7xCrypto, usesSeedCrypto, true, indent);
                byte[] namebytes = Encoding.UTF8.GetBytes(genOutName(titleID, GetPartitionName(idx), "romfs"));
                Array.Copy(namebytes, 0, entry.outputname, 0, namebytes.Length);
                entries.Add(entry);
                Console.WriteLine();
            }

            Console.WriteLine();

            return(entries);
        }