public static void GetNcchAesCounter(ref byte[] counter, NCCH ncch, NcchSection type) { counter = new byte[16]; if (ncch.Header.Version == 2 || ncch.Header.Version == 0) { Array.Copy(ReverseByteArray(ncch.Header.TitleID), 0, counter, 0, 8); counter[8] = (byte)type; } else if (ncch.Header.Version == 1) { long num = 0; switch (type) { case NcchSection.exheader: num = 0x200; break; case NcchSection.exefs: num = ncch.Header.ExeFSOffset * 0x200; break; case NcchSection.romfs: num = ncch.Header.RomFSOffset * 0x200; break; } Array.Copy(ReverseByteArray(ncch.Header.TitleID), 0, counter, 0, 8); for (int i = 0; i < 4; i++) { counter[i + 12] = (byte)((num >> ((3 - i) * 8)) & 0xFF); } } }
public NCCHInfo(NCCH ncch, int PartitionIndex, Encoding encoding) { Entries = new List<NCCHInfoEntry>(); int Use7x = ncch.Header.Flags[3]; if ((ncch.Header.Flags[7] & 0x20) == 0x20) { if (!File.Exists("seedinfo.bin")) throw new Exception("Cannot find seedinfo.bin."); seedinfo = new SEEDinfo("seedinfo.bin"); for (int i = 0; i < seedinfo.Count; i++) { if (seedinfo.Entries[i].Checksum == ncch.Header.SEEDCheck) { byte[] KeyY = new byte[16]; Array.Copy(ncch.Header.NCCHHeaderSignature, 0, KeyY, 0, 16); seedinfo.Entries[i] = new SEEDEntry(seedinfo.Entries[i], KeyY); SEED = seedinfo.Entries[i]; break; } } } if (ncch.Header.ExtendedHeaderSize > 0) { Entries.Add(new NCCHInfoEntry(ncch, PartitionIndex, NcchSection.exheader, encoding, 0, "exheader")); } if (ncch.Header.ExeFSLength > 0) { Entries.Add(new NCCHInfoEntry(ncch, PartitionIndex, NcchSection.exefs, encoding, 0, "exefs_norm")); if (Use7x == 1) { Entries.Add(new NCCHInfoEntry(ncch, PartitionIndex, NcchSection.exefs, encoding, Use7x, "exefs_7x")); } } if (ncch.Header.RomFSLength > 0) { Entries.Add(new NCCHInfoEntry(ncch, PartitionIndex, NcchSection.romfs, encoding, Use7x, "romfs")); } }
public void LoadFile(string path,long ncchoffset) { FileStream fs = File.OpenRead(path); fs.Position = ncchoffset; if (fs.Position >= fs.Length - Marshal.SizeOf(typeof(NCCHHeader)) + 0x100) { PrintErrorMessage("Invalid file"); return; } CXI = new NCCH(fs); long ExefsSize = CaculateMediaUnite(CXI.Header.ExeFSLength); byte[] ExheaderRaw = new byte[0x800]; byte[] ExeFSRaw = new byte[ExefsSize]; fs.Read(ExheaderRaw, 0, ExheaderRaw.Length); fs.Position = NcchOffset + CaculateMediaUnite(CXI.Header.ExeFSOffset); fs.Read(ExeFSRaw, 0, ExeFSRaw.Length); using (MemoryStream exhstream = new MemoryStream(ExheaderRaw)) { switch (CXI.Header.Flags[7]) { case 0: case 0x20: { if (!CB_Advance.Checked) throw new Exception("Use Advance Options to decrypt this file."); if (string.IsNullOrEmpty(TB_Xor.Text)) return; string exhxor = GetXorFilePath("exheader"); using (FileStream xorfs = File.OpenRead(exhxor)) { using (MemoryStream decstream = new MemoryStream()) { Xorer.TramsfoemStream(decstream, exhstream, xorfs, 0, exhstream.Length); decstream.Position = 0; CXI.ExHeader = StructReader.ReadStruct<NCCHExtendedHeader>(decstream); CXI.AccessControlExtend = StructReader.ReadStruct<NCCHAccessControlExtend>(decstream); } } string exefsnorm = GetXorFilePath("exefs_norm"); using (FileStream xorfs = File.OpenRead(exefsnorm)) { using (MemoryStream decstream = new MemoryStream()) { Xorer.TramsfoemStream(decstream, new MemoryStream(ExeFSRaw), xorfs, 0, ExefsSize); decstream.Position = 0; ExeFs = new ExeFS(decstream); if (CXI.Header.Flags[3] == 1) { decstream.Position = 0; xorfs.Position = 0; Xorer.TramsfoemStream(decstream, new MemoryStream(ExeFSRaw), xorfs, 0, Marshal.SizeOf(typeof(ExeFSHeader))); using (FileStream xor7xfs = File.OpenRead(GetXorFilePath("exefs_7x"))) { Xorer.TramsfoemStream(decstream, new MemoryStream(ExeFSRaw), xor7xfs, Marshal.SizeOf(typeof(ExeFSHeader)), ExeFs.Header.HeaderEntries[0].size); } xorfs.Position = 0; long TopLength = Marshal.SizeOf(typeof(ExeFSHeader)) + ExeFs.Header.HeaderEntries[0].size; Xorer.TramsfoemStream(decstream, new MemoryStream(ExeFSRaw), xorfs, TopLength, ExeFSRaw.Length - TopLength); decstream.Position = 0; ExeFs = new ExeFS(decstream); } } } break; } case 1: case 0x21: { byte[] aesctr = new byte[16]; NCCHInfo.GetNcchAesCounter(ref aesctr, CXI, NcchSection.exheader); using (MemoryStream decstream = new MemoryStream()) { Aes128Ctr.TransformFile(new byte[16], aesctr, decstream, exhstream, 0, exhstream.Length); decstream.Position = 0; CXI.ExHeader = StructReader.ReadStruct<NCCHExtendedHeader>(decstream); CXI.AccessControlExtend = StructReader.ReadStruct<NCCHAccessControlExtend>(decstream); } NCCHInfo.GetNcchAesCounter(ref aesctr, CXI, NcchSection.exefs); using (MemoryStream decstream = new MemoryStream()) { Aes128Ctr.TransformFile(new byte[16], aesctr, decstream, new MemoryStream(ExeFSRaw), 0, ExeFSRaw.Length); decstream.Position = 0; ExeFs = new ExeFS(decstream); } break; } case 4: case 5: { CXI.ExHeader = StructReader.ReadStruct<NCCHExtendedHeader>(exhstream); CXI.AccessControlExtend = StructReader.ReadStruct<NCCHAccessControlExtend>(exhstream); ExeFs = new ExeFS(new MemoryStream(ExeFSRaw)); break; } } } fs.Close(); ExeFs.SavedCode += ExeFs_SavedCode; ExeFs.SavingCode += ExeFs_SavingCode; ExeFs.DecompressingCode += ExeFs_DecompressingCode; ExeFs.DecompressedCode += ExeFs_DecompressedCode; }
public NCCHInfoEntry(NCCH ncch, int PartitionIndex, NcchSection type, Encoding encoding, int use7x, string sectionname) { NCCHInfo.GetNcchAesCounter(ref Counter, ncch, type); Array.Copy(ncch.Header.NCCHHeaderSignature, 0, KeyY, 0, 16); if ((ncch.Header.Flags[7] & 0x20) == 0x20) { if ((type == NcchSection.romfs) || ((type == NcchSection.exefs) && (use7x == 1))) { Array.Copy(NCCHInfo.SEED.KeyY, 0, KeyY, 0, 16); } } switch (type) { case NcchSection.exefs: Size = NCCHInfo.roundUp((int)ncch.Header.ExeFSLength * 0x200, 1024 * 1024) / (1024 * 1024); break; case NcchSection.exheader: Size = NCCHInfo.roundUp((int)ncch.Header.ExtendedHeaderSize * 0x200, 1024 * 1024) / (1024 * 1024); break; case NcchSection.romfs: Size = NCCHInfo.roundUp((int)ncch.Header.RomFSLength * 0x200, 1024 * 1024) / (1024 * 1024); break; } using (MemoryStream ms = new MemoryStream()) { BinaryWriter writer = new BinaryWriter(ms, encoding); string path = ""; if (encoding == Encoding.Unicode) path = string.Format("sdmc:/{0:X16}.{1}.{2}.xorpad", BitConverter.ToUInt64(ncch.Header.TitleID, 0), PartitionName[PartitionIndex], sectionname); else if (encoding == Encoding.UTF8) path = string.Format("/{0:X16}.{1}.{2}.xorpad", BitConverter.ToUInt64(ncch.Header.TitleID, 0), PartitionName[PartitionIndex], sectionname); writer.Write(path.ToCharArray()); Array.Copy(ms.ToArray(), 0, FileName, 0, ms.Length); } Use7x = use7x; }
public void Initial() { CXI = null; ExeFs = null; NcchOffset = 0; ClearErrorMessage(); PB_1.Visible = false; PB_1.Maximum = 0; PB_1.Value = 0; }