diff --git a/NDecrypt.N3DS/CIATool.cs b/NDecrypt.N3DS/CIATool.cs index 0350fa9..9de8d33 100644 --- a/NDecrypt.N3DS/CIATool.cs +++ b/NDecrypt.N3DS/CIATool.cs @@ -72,7 +72,7 @@ namespace NDecrypt.N3DS using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) { - var cia = Serializer.ReadCIAHeader(reader); + var cia = Serializer.ReadCIA(reader); if (cia == null) { Console.WriteLine("Error: Not a 3DS CIA!"); diff --git a/NDecrypt.N3DS/Serializer.cs b/NDecrypt.N3DS/Serializer.cs index 28319b2..b717e0e 100644 --- a/NDecrypt.N3DS/Serializer.cs +++ b/NDecrypt.N3DS/Serializer.cs @@ -13,135 +13,11 @@ namespace NDecrypt.N3DS private const string NCCHMagicNumber = "NCCH"; private const string NCSDMagicNumber = "NCSD"; - private const string RomFSMagicNumber = "IVFC"; - private const uint RomFSSecondMagicNumber = 0x10000; #endregion #region Reading - /// - /// Read from a stream and get access control info, if possible - /// - /// BinaryReader representing the input stream - /// Access control info object, null on error - public static AccessControlInfo? ReadAccessControlInfo(BinaryReader reader) - { - var aci = new AccessControlInfo(); - - try - { - aci.ARM11LocalSystemCapabilities = ReadARM11LocalSystemCapabilities(reader); - aci.ARM11KernelCapabilities = ReadARM11KernelCapabilities(reader); - aci.ARM9AccessControl = ReadARM9AccessControl(reader); - return aci; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get ARM9 access control, if possible - /// - /// BinaryReader representing the input stream - /// ARM9 access control object, null on error - public static ARM9AccessControl? ReadARM9AccessControl(BinaryReader reader) - { - var ac = new ARM9AccessControl(); - - try - { - ac.Descriptors = new byte[15]; // TODO: Implement ARM9AccessControlDescriptors in Models - for (int i = 0; i < 15; i++) - { - ac.Descriptors[i] = reader.ReadByte(); - } - - ac.DescriptorVersion = reader.ReadByte(); - return ac; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get ARM11 kernel capabilities, if possible - /// - /// BinaryReader representing the input stream - /// ARM11 kernel capabilities object, null on error - public static ARM11KernelCapabilities? ReadARM11KernelCapabilities(BinaryReader reader) - { - var kc = new ARM11KernelCapabilities(); - - try - { - kc.Descriptors = new uint[28]; - for (int i = 0; i < 28; i++) - { - kc.Descriptors[i] = reader.ReadUInt32(); - } - - kc.Reserved = reader.ReadBytes(0x10); - return kc; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get ARM11 local system capabilities, if possible - /// - /// BinaryReader representing the input stream - /// ARM11 local system capabilities object, null on error - public static ARM11LocalSystemCapabilities? ReadARM11LocalSystemCapabilities(BinaryReader reader) - { - var lsc = new ARM11LocalSystemCapabilities(); - - try - { - lsc.ProgramID = reader.ReadUInt64(); - lsc.CoreVersion = reader.ReadUInt32(); - lsc.Flag1 = (ARM11LSCFlag1)reader.ReadByte(); - lsc.Flag2 = (ARM11LSCFlag2)reader.ReadByte(); - lsc.Flag0 = (ARM11LSCFlag0)reader.ReadByte(); - lsc.Priority = reader.ReadByte(); - - lsc.ResourceLimitDescriptors = new ushort[16]; - for (int i = 0; i < 16; i++) - { - lsc.ResourceLimitDescriptors[i] = reader.ReadUInt16(); - } - - lsc.StorageInfo = ReadStorageInfo(reader); - - lsc.ServiceAccessControl = new ulong[32]; - for (int i = 0; i < 32; i++) - { - lsc.ServiceAccessControl[i] = reader.ReadUInt64(); - } - - lsc.ExtendedServiceAccessControl = new ulong[2]; - for (int i = 0; i < 2; i++) - { - lsc.ExtendedServiceAccessControl[i] = reader.ReadUInt64(); - } - - lsc.Reserved = reader.ReadBytes(0xF); - lsc.ResourceLimitCategory = (ResourceLimitCategory)reader.ReadByte(); - return lsc; - } - catch - { - return null; - } - } - /// /// Read from a stream and get N3DS cart image, if possible /// @@ -166,7 +42,7 @@ namespace NDecrypt.N3DS if (cart.CardInfoHeader == null) return (null, null); - // TODO: Undocumented in current model? + // TODO: Remove when InitialData is read correctly backupHeader = ReadNCCHHeader(reader, readSignature: false); if (development) @@ -185,115 +61,12 @@ namespace NDecrypt.N3DS } } - /// - /// Read from a stream and get an CardInfo header, if possible - /// - /// BinaryReader representing the input stream - /// CardInfo header object, null on error - public static CardInfoHeader? ReadCardInfoHeader(BinaryReader reader) - { - var header = new CardInfoHeader(); - - try - { - header.WritableAddressMediaUnits = reader.ReadUInt32(); - header.CardInfoBitmask = reader.ReadUInt32(); - header.Reserved3 = reader.ReadBytes(0x108); - header.TitleVersion = reader.ReadUInt16(); - header.CardRevision = reader.ReadUInt16(); - header.Reserved4 = reader.ReadBytes(0xCD6); - - // TODO: Undocumented in current model? - _ = reader.ReadBytes(0x10); // header.CardSeedKeyY - _ = reader.ReadBytes(0x10); // header.EncryptedCardSeed - _ = reader.ReadBytes(0x10); // header.CardSeedAESMAC - _ = reader.ReadBytes(0x0C); // header.CardSeedNonce - _ = reader.ReadBytes(0xC4); // header.Reserved5 - - return header; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get certificate, if possible - /// - /// BinaryReader representing the input stream - /// Certificate object, null on error - public static Certificate? ReadCertificate(BinaryReader reader) - { - var ct = new Certificate(); - - try - { - ct.SignatureType = (SignatureType)reader.ReadUInt32(); - switch (ct.SignatureType) - { - case SignatureType.RSA_4096_SHA1: - case SignatureType.RSA_4096_SHA256: - ct.SignatureSize = 0x200; - ct.PaddingSize = 0x3C; - break; - case SignatureType.RSA_2048_SHA1: - case SignatureType.RSA_2048_SHA256: - ct.SignatureSize = 0x100; - ct.PaddingSize = 0x3C; - break; - case SignatureType.ECDSA_SHA1: - case SignatureType.ECDSA_SHA256: - ct.SignatureSize = 0x03C; - ct.PaddingSize = 0x40; - break; - default: - return null; - } - - ct.Signature = reader.ReadBytes(ct.SignatureSize); - reader.ReadBytes(ct.PaddingSize); // Padding - byte[] issuerBytes = reader.ReadBytes(0x40); - ct.Issuer = Encoding.ASCII.GetString(issuerBytes); - ct.KeyType = (PublicKeyType)reader.ReadUInt32(); - byte[] nameBytes = reader.ReadBytes(0x40); - ct.Name = Encoding.ASCII.GetString(nameBytes); - ct.ExpirationTime = reader.ReadUInt32(); - - switch (ct.KeyType) - { - case PublicKeyType.RSA_4096: - ct.RSAModulus = reader.ReadBytes(0x200); - ct.RSAPublicExponent = reader.ReadUInt32(); - ct.RSAPadding = reader.ReadBytes(0x34); - break; - case PublicKeyType.RSA_2048: - ct.RSAModulus = reader.ReadBytes(0x100); - ct.RSAPublicExponent = reader.ReadUInt32(); - ct.RSAPadding = reader.ReadBytes(0x34); - break; - case PublicKeyType.EllipticCurve: - ct.ECCPublicKey = reader.ReadBytes(0x3C); - ct.ECCPadding = reader.ReadBytes(0x3C); - break; - default: - return null; - } - - return ct; - } - catch - { - return null; - } - } - /// /// Read from a stream and get a CIA header, if possible /// /// BinaryReader representing the input stream /// CIA header object, null on error - public static CIA? ReadCIAHeader(BinaryReader reader) + public static CIA? ReadCIA(BinaryReader reader) { var cia = new CIA(); @@ -358,120 +131,6 @@ namespace NDecrypt.N3DS } } - /// - /// Read from a stream and get code set info, if possible - /// - /// BinaryReader representing the input stream - /// Code set info object, null on error - public static CodeSetInfo? ReadCodeSetInfo(BinaryReader reader) - { - var csi = new CodeSetInfo(); - - try - { - csi.Address = reader.ReadUInt32(); - csi.PhysicalRegionSizeInPages = reader.ReadUInt32(); - csi.SizeInBytes = reader.ReadUInt32(); - return csi; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get content chunk record, if possible - /// - /// BinaryReader representing the input stream - /// Content chunk record object, null on error - public static ContentChunkRecord? ReadContentChunkRecord(BinaryReader reader) - { - var ccr = new ContentChunkRecord(); - - try - { - ccr.ContentId = reader.ReadUInt32(); - ccr.ContentIndex = (ContentIndex)reader.ReadUInt16(); - ccr.ContentType = (TMDContentType)reader.ReadUInt16(); - ccr.ContentSize = reader.ReadUInt64(); - ccr.SHA256Hash = reader.ReadBytes(0x20); - return ccr; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get content info record, if possible - /// - /// BinaryReader representing the input stream - /// Content info record object, null on error - public static ContentInfoRecord? ReadContentInfoRecord(BinaryReader reader) - { - var cir = new ContentInfoRecord(); - - try - { - cir.ContentIndexOffset = reader.ReadUInt16(); - cir.ContentCommandCount = reader.ReadUInt16(); - cir.UnhashedContentRecordsSHA256Hash = reader.ReadBytes(0x20); - return cir; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get an DevelopmentCardInfo header, if possible - /// - /// BinaryReader representing the input stream - /// DevelopmentCardInfo object, null on error - public static DevelopmentCardInfoHeader? ReadDevelopmentCardInfoHeader(BinaryReader reader) - { - var header = new DevelopmentCardInfoHeader(); - - try - { - header.CardDeviceReserved1 = reader.ReadBytes(0x200); - header.TitleKey = reader.ReadBytes(0x10); - header.CardDeviceReserved2 = reader.ReadBytes(0xF0); - - return header; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get an ExeFS file header, if possible - /// - /// BinaryReader representing the input stream - /// ExeFS file header object, null on error - public static ExeFSFileHeader? ReadExeFSFileHeader(BinaryReader reader) - { - var header = new ExeFSFileHeader(); - - try - { - byte[] fileNameBytes = reader.ReadBytes(8); - header.FileName = Encoding.ASCII.GetString(fileNameBytes); - header.FileOffset = reader.ReadUInt32(); - header.FileSize = reader.ReadUInt32(); - return header; - } - catch - { - return null; - } - } - /// /// Read from a stream and get an ExeFS header, if possible /// @@ -505,31 +164,6 @@ namespace NDecrypt.N3DS } } - /// - /// Read from a stream and get the Metafile data, if possible - /// - /// BinaryReader representing the input stream - /// Metafile data object, null on error - public static MetaData? ReadMetaData(BinaryReader reader) - { - var metaData = new MetaData(); - - try - { - metaData.TitleIDDependencyList = reader.ReadBytes(0x180); - metaData.Reserved1 = reader.ReadBytes(0x180); - metaData.CoreVersion = reader.ReadUInt32(); - metaData.Reserved2 = reader.ReadBytes(0xFC); - metaData.IconData = reader.ReadBytes(0x36C0); - - return metaData; - } - catch - { - return null; - } - } - /// /// Read from a stream and get an NCCH header, if possible /// @@ -585,12 +219,252 @@ namespace NDecrypt.N3DS } } + /// + /// Read from a stream and get an CardInfo header, if possible + /// + /// BinaryReader representing the input stream + /// CardInfo header object, null on error + private static CardInfoHeader? ReadCardInfoHeader(BinaryReader reader) + { + var header = new CardInfoHeader(); + + try + { + header.WritableAddressMediaUnits = reader.ReadUInt32(); + header.CardInfoBitmask = reader.ReadUInt32(); + header.Reserved3 = reader.ReadBytes(0x108); + header.TitleVersion = reader.ReadUInt16(); + header.CardRevision = reader.ReadUInt16(); + header.Reserved4 = reader.ReadBytes(0xCD6); + _ = ReadInitialData(reader); + + return header; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get certificate, if possible + /// + /// BinaryReader representing the input stream + /// Certificate object, null on error + private static Certificate? ReadCertificate(BinaryReader reader) + { + var ct = new Certificate(); + + try + { + ct.SignatureType = (SignatureType)reader.ReadUInt32(); + switch (ct.SignatureType) + { + case SignatureType.RSA_4096_SHA1: + case SignatureType.RSA_4096_SHA256: + ct.SignatureSize = 0x200; + ct.PaddingSize = 0x3C; + break; + case SignatureType.RSA_2048_SHA1: + case SignatureType.RSA_2048_SHA256: + ct.SignatureSize = 0x100; + ct.PaddingSize = 0x3C; + break; + case SignatureType.ECDSA_SHA1: + case SignatureType.ECDSA_SHA256: + ct.SignatureSize = 0x03C; + ct.PaddingSize = 0x40; + break; + default: + return null; + } + + ct.Signature = reader.ReadBytes(ct.SignatureSize); + reader.ReadBytes(ct.PaddingSize); // Padding + byte[] issuerBytes = reader.ReadBytes(0x40); + ct.Issuer = Encoding.ASCII.GetString(issuerBytes); + ct.KeyType = (PublicKeyType)reader.ReadUInt32(); + byte[] nameBytes = reader.ReadBytes(0x40); + ct.Name = Encoding.ASCII.GetString(nameBytes); + ct.ExpirationTime = reader.ReadUInt32(); + + switch (ct.KeyType) + { + case PublicKeyType.RSA_4096: + ct.RSAModulus = reader.ReadBytes(0x200); + ct.RSAPublicExponent = reader.ReadUInt32(); + ct.RSAPadding = reader.ReadBytes(0x34); + break; + case PublicKeyType.RSA_2048: + ct.RSAModulus = reader.ReadBytes(0x100); + ct.RSAPublicExponent = reader.ReadUInt32(); + ct.RSAPadding = reader.ReadBytes(0x34); + break; + case PublicKeyType.EllipticCurve: + ct.ECCPublicKey = reader.ReadBytes(0x3C); + ct.ECCPadding = reader.ReadBytes(0x3C); + break; + default: + return null; + } + + return ct; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get content chunk record, if possible + /// + /// BinaryReader representing the input stream + /// Content chunk record object, null on error + private static ContentChunkRecord? ReadContentChunkRecord(BinaryReader reader) + { + var ccr = new ContentChunkRecord(); + + try + { + ccr.ContentId = reader.ReadUInt32(); + ccr.ContentIndex = (ContentIndex)reader.ReadUInt16(); + ccr.ContentType = (TMDContentType)reader.ReadUInt16(); + ccr.ContentSize = reader.ReadUInt64(); + ccr.SHA256Hash = reader.ReadBytes(0x20); + return ccr; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get content info record, if possible + /// + /// BinaryReader representing the input stream + /// Content info record object, null on error + private static ContentInfoRecord? ReadContentInfoRecord(BinaryReader reader) + { + var cir = new ContentInfoRecord(); + + try + { + cir.ContentIndexOffset = reader.ReadUInt16(); + cir.ContentCommandCount = reader.ReadUInt16(); + cir.UnhashedContentRecordsSHA256Hash = reader.ReadBytes(0x20); + return cir; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get an DevelopmentCardInfo header, if possible + /// + /// BinaryReader representing the input stream + /// DevelopmentCardInfo object, null on error + private static DevelopmentCardInfoHeader? ReadDevelopmentCardInfoHeader(BinaryReader reader) + { + var header = new DevelopmentCardInfoHeader(); + + try + { + header.CardDeviceReserved1 = reader.ReadBytes(0x200); + header.TitleKey = reader.ReadBytes(0x10); + header.CardDeviceReserved2 = reader.ReadBytes(0xF0); + + return header; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get an ExeFS file header, if possible + /// + /// BinaryReader representing the input stream + /// ExeFS file header object, null on error + private static ExeFSFileHeader? ReadExeFSFileHeader(BinaryReader reader) + { + var header = new ExeFSFileHeader(); + + try + { + byte[] fileNameBytes = reader.ReadBytes(8); + header.FileName = Encoding.ASCII.GetString(fileNameBytes); + header.FileOffset = reader.ReadUInt32(); + header.FileSize = reader.ReadUInt32(); + return header; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get inital data, if possible + /// + /// BinaryReader representing the input stream + /// Initial data object, null on error + private static InitialData? ReadInitialData(BinaryReader reader) + { + var id = new InitialData(); + + try + { + id.CardSeedKeyY = reader.ReadBytes(0x10); + id.EncryptedCardSeed = reader.ReadBytes(0x10); + id.CardSeedAESMAC = reader.ReadBytes(0x10); + id.CardSeedNonce = reader.ReadBytes(0x0C); + id.Reserved = reader.ReadBytes(0xC4); + // TODO: Read backup header here instead of separately + + return id; + } + catch + { + return null; + } + } + + /// + /// Read from a stream and get the Metafile data, if possible + /// + /// BinaryReader representing the input stream + /// Metafile data object, null on error + private static MetaData? ReadMetaData(BinaryReader reader) + { + var metaData = new MetaData(); + + try + { + metaData.TitleIDDependencyList = reader.ReadBytes(0x180); + metaData.Reserved1 = reader.ReadBytes(0x180); + metaData.CoreVersion = reader.ReadUInt32(); + metaData.Reserved2 = reader.ReadBytes(0xFC); + metaData.IconData = reader.ReadBytes(0x36C0); + + return metaData; + } + catch + { + return null; + } + } + /// /// Read from a stream and get an NCCH header flags, if possible /// /// BinaryReader representing the input stream /// NCCH header flags object, null on error - public static NCCHHeaderFlags? ReadNCCHHeaderFlags(BinaryReader reader) + private static NCCHHeaderFlags? ReadNCCHHeaderFlags(BinaryReader reader) { var flags = new NCCHHeaderFlags(); @@ -612,36 +486,12 @@ namespace NDecrypt.N3DS } } - /// - /// Read from a stream and get a CXI extended header, if possible - /// - /// BinaryReader representing the input stream - /// CXI extended header object, null on error - public static NCCHExtendedHeader? ReadNCCHExtendedHeader(BinaryReader reader) - { - var header = new NCCHExtendedHeader(); - - try - { - header.SCI = ReadSystemControlInfo(reader); - header.ACI = ReadAccessControlInfo(reader); - header.AccessDescSignature = reader.ReadBytes(0x100); - header.NCCHHDRPublicKey = reader.ReadBytes(0x100); - header.ACIForLimitations = ReadAccessControlInfo(reader); - return header; - } - catch - { - return null; - } - } - /// /// Read from a stream and get an NCSD header, if possible /// /// BinaryReader representing the input stream /// NCSD header object, null on error - public static NCSDHeader? ReadNCSDHeader(BinaryReader reader) + private static NCSDHeader? ReadNCSDHeader(BinaryReader reader) { var header = new NCSDHeader(); @@ -701,7 +551,7 @@ namespace NDecrypt.N3DS /// /// BinaryReader representing the input stream /// Partition table entry object, null on error - public static PartitionTableEntry? ReadPartitionTableEntry(BinaryReader reader) + private static PartitionTableEntry? ReadPartitionTableEntry(BinaryReader reader) { var entry = new PartitionTableEntry(); @@ -717,138 +567,13 @@ namespace NDecrypt.N3DS } } - /// - /// Read from a stream and get a RomFS header, if possible - /// - /// BinaryReader representing the input stream - /// RomFS header object, null on error - public static RomFSHeader? ReadRomFSHeader(BinaryReader reader) - { - var header = new RomFSHeader(); - - try - { - if (new string(reader.ReadChars(4)) != RomFSMagicNumber) - return null; - - if (reader.ReadUInt32() != RomFSSecondMagicNumber) - return null; - - header.MasterHashSize = reader.ReadUInt32(); - header.Level1LogicalOffset = reader.ReadUInt64(); - header.Level1HashdataSize = reader.ReadUInt64(); - header.Level1BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved1 = reader.ReadUInt32(); - header.Level2LogicalOffset = reader.ReadUInt64(); - header.Level2HashdataSize = reader.ReadUInt64(); - header.Level2BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved2 = reader.ReadUInt32(); - header.Level3LogicalOffset = reader.ReadUInt64(); - header.Level3HashdataSize = reader.ReadUInt64(); - header.Level3BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved3 = reader.ReadUInt32(); - header.Reserved4 = reader.ReadUInt32(); - header.OptionalInfoSize = reader.ReadUInt32(); - - return header; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get storage info, if possible - /// - /// BinaryReader representing the input stream - /// Storage info object, null on error - public static StorageInfo? ReadStorageInfo(BinaryReader reader) - { - var si = new StorageInfo(); - - try - { - si.ExtdataID = reader.ReadUInt64(); - si.SystemSavedataIDs = reader.ReadBytes(8); - si.StorageAccessibleUniqueIDs = reader.ReadBytes(8); - si.FileSystemAccessInfo = reader.ReadBytes(7); - si.OtherAttributes = (StorageInfoOtherAttributes)reader.ReadByte(); - return si; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get system control info, if possible - /// - /// BinaryReader representing the input stream - /// System control info object, null on error - public static SystemControlInfo? ReadSystemControlInfo(BinaryReader reader) - { - var sci = new SystemControlInfo(); - - try - { - byte[] applicationTitleBytes = reader.ReadBytes(8); - sci.ApplicationTitle = Encoding.ASCII.GetString(applicationTitleBytes); - sci.Reserved1 = reader.ReadBytes(5); - sci.Flag = reader.ReadByte(); - sci.RemasterVersion = reader.ReadUInt16(); - sci.TextCodeSetInfo = ReadCodeSetInfo(reader); - sci.StackSize = reader.ReadUInt32(); - sci.ReadOnlyCodeSetInfo = ReadCodeSetInfo(reader); - sci.Reserved2 = reader.ReadUInt32(); - sci.DataCodeSetInfo = ReadCodeSetInfo(reader); - sci.BSSSize = reader.ReadUInt32(); - - sci.DependencyModuleList = new ulong[48]; - for (int i = 0; i < 48; i++) - { - sci.DependencyModuleList[i] = reader.ReadUInt64(); - } - - sci.SystemInfo = ReadSystemInfo(reader); - return sci; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get system info, if possible - /// - /// BinaryReader representing the input stream - /// System info object, null on error - public static SystemInfo? ReadSystemInfo(BinaryReader reader) - { - var si = new SystemInfo(); - - try - { - si.SaveDataSize = reader.ReadUInt64(); - si.JumpID = reader.ReadUInt64(); - si.Reserved = reader.ReadBytes(0x30); - return si; - } - catch - { - return null; - } - } - /// /// Read from a stream and get ticket, if possible /// /// BinaryReader representing the input stream /// Ticket size from the header /// Ticket object, null on error - public static Ticket? ReadTicket(BinaryReader reader, uint ticketSize) + private static Ticket? ReadTicket(BinaryReader reader, uint ticketSize) { var tk = new Ticket(); @@ -936,7 +661,7 @@ namespace NDecrypt.N3DS /// BinaryReader representing the input stream /// Metadata size from the header /// Title metadata object, null on error - public static TitleMetadata? ReadTitleMetadata(BinaryReader reader, uint metadataSize) + private static TitleMetadata? ReadTitleMetadata(BinaryReader reader, uint metadataSize) { var tm = new TitleMetadata();