private void jSONToolStripMenuItem_Click(object sender, EventArgs e) { if (Control != null) { using (var Rom = Control.OpenSection(0, false, IntegrityCheckLevel.None)) { var Romfs = new Romfs(Rom); var Dialog = folderBrowserDialog1.ShowDialog(); if (Dialog != DialogResult.Cancel) { using (var InFile = Romfs.OpenFile(Romfs.Files.FirstOrDefault(f => f.Name == "control.nacp"))) using (var Read = new BinaryReader(InFile)) { var Nacp = new Nacp(Read); var Settings = new JsonSerializerSettings { Formatting = Formatting.Indented }; File.WriteAllText($"{folderBrowserDialog1.SelectedPath}/{Nca.Header.TitleId:x16}_control.json", JsonConvert.SerializeObject(Nacp, Settings)); } } } } else { MessageBox.Show("Error: No control is present!"); } }
public static byte[] GetFirmwareData(Switch device) { long titleId = 0x0100000000000809; string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, ContentType.Data); if (string.IsNullOrWhiteSpace(contentPath)) { return(null); } string firmwareTitlePath = device.FileSystem.SwitchPathToSystemPath(contentPath); using (FileStream firmwareStream = File.Open(firmwareTitlePath, FileMode.Open, FileAccess.Read)) { Nca firmwareContent = new Nca(device.System.KeySet, firmwareStream.AsStorage(), false); IStorage romFsStorage = firmwareContent.OpenSection(0, false, device.System.FsIntegrityCheckLevel, false); if (romFsStorage == null) { return(null); } Romfs firmwareRomFs = new Romfs(romFsStorage); IStorage firmwareFile = firmwareRomFs.OpenFile("/file"); byte[] data = new byte[firmwareFile.Length]; firmwareFile.Read(data, 0); return(data); } }
public void Load(System.IO.Stream stream) { string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string KeyFile = Path.Combine(homeFolder, ".switch", "prod.keys"); string TitleKeyFile = Path.Combine(homeFolder, ".switch", "title.keys"); var Keys = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile); Stream Input; var Pfs = new Pfs(stream.AsStorage()); var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream()); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream(); var Nca = new Nca(Keys, Input.AsStorage(), true); Romfs romfs = new Romfs( Nca.OpenSection(Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None, true)); for (int i = 0; i < romfs.Files.Count; i++) { files.Add(new FileEntry(romfs, romfs.Files[i])); } }
public void Load(System.IO.Stream stream) { var Keys = Forms.SwitchKeySelectionForm.ShowKeySelector(); if (Keys == null) { throw new Exception("Failed to get keys. Please select valid paths!"); } var Nca = new Nca(Keys, stream.AsStorage(), true); Romfs romfs = new Romfs( Nca.OpenSection(Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None, true)); if (Nca.CanOpenSection((int)ProgramPartitionType.Code)) { var exefs = new Pfs(Nca.OpenSection((int)ProgramPartitionType.Code, false, IntegrityCheckLevel.None, true)); foreach (var file in exefs.Files) { files.Add(new NSP.ExefsEntry(exefs, file)); } } for (int i = 0; i < romfs.Files.Count; i++) { files.Add(new NSP.FileEntry(romfs, romfs.Files[i])); } }
public static void ExtractSection(this Nca nca, int index, string outputDir, bool verify = false, IProgressReport logger = null) { if (index < 0 || index > 3) { throw new IndexOutOfRangeException(); } if (nca.Sections[index] == null) { return; } NcaSection section = nca.Sections[index]; Stream stream = nca.OpenSection(index, false, verify); switch (section.Type) { case SectionType.Invalid: break; case SectionType.Pfs0: var pfs0 = new Pfs(stream); pfs0.Extract(outputDir, logger); break; case SectionType.Romfs: var romfs = new Romfs(stream); romfs.Extract(outputDir, logger); break; case SectionType.Bktr: break; } }
private void iconToolStripMenuItem_Click(object sender, EventArgs e) { if (Control != null) { using (var Rom = Control.OpenSection(0, false, IntegrityCheckLevel.None)) { var Romfs = new Romfs(Rom); var Dialog = folderBrowserDialog1.ShowDialog(); if (Dialog != DialogResult.Cancel) { using (var Icon = Romfs.OpenFile(Romfs.Files.FirstOrDefault(f => f.Name.Contains("icon")))) Icon.WriteAllBytes($"{folderBrowserDialog1.SelectedPath}/{Control.Header.TitleId:x16}_icon.jpg"); } } } else if (pictureBox1.Image != null) { var Dialog = folderBrowserDialog1.ShowDialog(); if (Dialog != DialogResult.Cancel) { pictureBox1.Image.Save($"{folderBrowserDialog1.SelectedPath}/{Nca.Header.TitleId:x16}_icon.jpg"); } } else { MessageBox.Show("Error: No control is present and icon is not in the database!"); } }
public static void Process(Context ctx) { using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) { var romfs = new Romfs(file.AsStorage()); Process(ctx, romfs); } }
public void ReadControlData(Nca controlNca) { Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel, true)); IStorage controlFile = controlRomfs.OpenFile("/control.nacp"); ControlData = new Nacp(controlFile.AsStream()); }
public void Load(System.IO.Stream stream) { Romfs romfs = new Romfs(stream.AsStorage()); for (int i = 0; i < romfs.Files.Count; i++) { files.Add(new NSP.FileEntry(romfs, romfs.Files[i])); } }
public void ReadControlData(Nca ControlNca) { Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, EnableFsIntegrityChecks)); byte[] ControlFile = ControlRomfs.GetFile("/control.nacp"); BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile)); ControlData = new Nacp(Reader); }
public void ReadControlData(Nca controlNca) { Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); byte[] controlFile = controlRomfs.GetFile("/control.nacp"); BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); ControlData = new Nacp(reader); }
public void Load(System.IO.Stream stream) { var Keys = Forms.SwitchKeySelectionForm.ShowKeySelector(); if (Keys == null) { throw new Exception("Failed to get keys. Please select valid paths!"); } var Pfs = new Pfs(stream.AsStorage()); var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream()); foreach (var entry in Cnmt.ContentEntries) { if (entry.Type == CnmtContentType.Program) { var Program = entry; string ncaFileName = $"{Program.NcaId.ToHexString().ToLower()}.nca"; Stream Input = Pfs.OpenFile(ncaFileName).AsStream(); var Nca = new Nca(Keys, Input.AsStorage(), true); string root = Nca.Header.TitleId.ToString("X"); Romfs romfs = new Romfs( Nca.OpenSection(Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None, true)); if (Nca.CanOpenSection((int)ProgramPartitionType.Code)) { var exefs = new Pfs(Nca.OpenSection((int)ProgramPartitionType.Code, false, IntegrityCheckLevel.None, true)); foreach (var file in exefs.Files) { files.Add(new ExefsEntry(exefs, file, root)); } } for (int i = 0; i < romfs.Files.Count; i++) { files.Add(new FileEntry(romfs, romfs.Files[i], root)); } } } var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } }
public FileEntry(Romfs romfs, RomfsFile romfsFile, string root = "") { ParentROMFS = romfs; File = romfsFile; if (root != string.Empty) { FileName = $"{root}/Romfs/{File.FullPath}"; } else { FileName = $"Romfs/{File.FullPath}"; } }
private string[] GetTitleMeta(string TitleID = null) { var Info = new string[] { "No title info loaded.", "" }; if (Control != null) { var Rom = new Romfs(Control.OpenSection(0, false, IntegrityCheckLevel.None, true)); var OpenControl = Rom.OpenFile(Rom.Files.FirstOrDefault(f => f.Name == "control.nacp")); var OpenIcon = Rom.OpenFile(Rom.Files.FirstOrDefault(f => f.Name.Contains("icon"))); var ControlNacp = new Nacp(OpenControl.AsStream()); var Lang = ControlNacp.Descriptions.FirstOrDefault(l => l.Title.Length > 1); Info[0] = Lang.Title; Info[1] = Lang.Developer; pictureBox1.Image = Image.FromStream(OpenIcon.AsStream()); } return(Info); }
private string[] GetTitleMeta(string TitleID = null) { var Info = new string[] { "Title missing from database", "" }; if (Control != null) { var Rom = new Romfs(Control.OpenSection(0, false, IntegrityCheckLevel.None)); var OpenControl = Rom.OpenFile(Rom.Files.FirstOrDefault(f => f.Name == "control.nacp")); var OpenIcon = Rom.OpenFile(Rom.Files.FirstOrDefault(f => f.Name.Contains("icon"))); var ControlNacp = new Nacp(new BinaryReader(OpenControl)); var Lang = ControlNacp.Languages.FirstOrDefault(l => l.Title.Length > 1); Info[0] = Lang.Title; Info[1] = Lang.Developer; pictureBox1.Image = Image.FromStream(OpenIcon); } else { try { using (var WC = new WebClient()) { var Cli = WC.DownloadData($"https://gamechat.network/nucleus?title_id={TitleID}"); pictureBox1.Image = Image.FromStream(new MemoryStream(Cli)); Info[0] = Encoding.UTF8.GetString ( WC.ResponseHeaders.Get("X-GCN-Game-Name") .Select(b => (byte)b).ToArray() ); Info[1] = Encoding.UTF8.GetString ( WC.ResponseHeaders.Get("X-GCN-Game-Dev") .Select(b => (byte)b).ToArray() ); } } catch { } } return(Info); }
public void Load(System.IO.Stream stream) { string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string KeyFile = Path.Combine(homeFolder, ".switch", "prod.keys"); string TitleKeyFile = Path.Combine(homeFolder, ".switch", "title.keys"); var Keys = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile); var Nca = new Nca(Keys, stream.AsStorage(), true); Romfs romfs = new Romfs( Nca.OpenSection(Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None, true)); for (int i = 0; i < romfs.Files.Count; i++) { files.Add(new NSP.FileEntry(romfs, romfs.Files[i])); } }
private void rawToolStripMenuItem_Click(object sender, EventArgs e) { if (Control != null) { using (var Rom = Control.OpenSection(0, false, IntegrityCheckLevel.None)) { var Romfs = new Romfs(Rom); var Dialog = folderBrowserDialog1.ShowDialog(); if (Dialog != DialogResult.Cancel) { using (var Nacp = Romfs.OpenFile(Romfs.Files.FirstOrDefault(f => f.Name == "control.nacp"))) Nacp.WriteAllBytes($"{folderBrowserDialog1.SelectedPath}/{Nca.Header.TitleId:x16}_control.nacp"); } } } else { MessageBox.Show("Error: No control is present!"); } }
public static byte[] GetFirmwareData(Switch device) { byte[] data = null; long titleId = 0x0100000000000809; string contentPath = device.System.ContentManager.GetInstalledContentPath(titleId, StorageId.NandSystem, ContentType.Data); if (string.IsNullOrWhiteSpace(contentPath)) { return(null); } string firmwareTitlePath = device.FileSystem.SwitchPathToSystemPath(contentPath); FileStream firmwareStream = File.Open(firmwareTitlePath, FileMode.Open, FileAccess.Read); Nca firmwareContent = new Nca(device.System.KeySet, firmwareStream, false); Stream romFsStream = firmwareContent.OpenSection(0, false, device.System.FsIntegrityCheckLevel); if (romFsStream == null) { return(null); } Romfs firmwareRomFs = new Romfs(romFsStream); using (MemoryStream memoryStream = new MemoryStream()) { using (Stream firmwareFile = firmwareRomFs.OpenFile("/file")) { firmwareFile.CopyTo(memoryStream); } data = memoryStream.ToArray(); } firmwareContent.Dispose(); firmwareStream.Dispose(); return(data); }
public static byte[] GetFirmwareData(Switch Device) { byte[] Data = null; long TitleId = 0x0100000000000809; string ContentPath = Device.System.ContentManager.GetInstalledContentPath(TitleId, StorageId.NandSystem, ContentType.Data); if (string.IsNullOrWhiteSpace(ContentPath)) { return(null); } string FirmwareTitlePath = Device.FileSystem.SwitchPathToSystemPath(ContentPath); FileStream FirmwareStream = File.Open(FirmwareTitlePath, FileMode.Open, FileAccess.Read); Nca FirmwareContent = new Nca(Device.System.KeySet, FirmwareStream, false); Stream RomFsStream = FirmwareContent.OpenSection(0, false, Device.System.FsIntegrityCheckLevel); if (RomFsStream == null) { return(null); } Romfs FirmwareRomFs = new Romfs(RomFsStream); using (MemoryStream MemoryStream = new MemoryStream()) { using (Stream FirmwareFile = FirmwareRomFs.OpenFile("/file")) { FirmwareFile.CopyTo(MemoryStream); } Data = MemoryStream.ToArray(); } FirmwareContent.Dispose(); FirmwareStream.Dispose(); return(Data); }
private static void processControlNca(Nca nca, ref Title title) { log?.WriteLine("Processing Control NCA"); if (nca.Header.ContentType == ContentType.Control) { title.titleID = String.Format("{0:X16}", nca.Header.TitleId); if (title.type == TitleType.Patch) { title.titleID = title.titleID.Substring(0, Math.Min(title.titleID.Length, 13)) + "800"; } try { Romfs romfs = new Romfs(nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true)); RomfsFile[] romfsFiles = romfs.Files.ToArray(); foreach (RomfsFile romfsFile in romfsFiles) { if (romfsFile.Name.Equals("control.nacp")) { using (var control = romfs.OpenFile(romfsFile).AsStream()) { processControlNacp(control, ref title); } } } } catch (MissingKeyException ex) { title.error = String.Format("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key")); log?.WriteLine(title.error); } catch (FileNotFoundException) { } } }
public static void Process(Context ctx, Romfs romfs) { if (ctx.Options.ListRomFs) { foreach (RomfsFile romfsFile in romfs.Files) { ctx.Logger.LogMessage(romfsFile.FullPath); } } if (ctx.Options.RomfsOut != null) { using (var outFile = new FileStream(ctx.Options.RomfsOut, FileMode.Create, FileAccess.ReadWrite)) { IStorage romfsStorage = romfs.OpenRawStream(); romfsStorage.CopyToStream(outFile, romfsStorage.Length, ctx.Logger); } } if (ctx.Options.RomfsOutDir != null) { romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger); } }
public FileEntry(Romfs romfs, RomfsFile romfsFile) { ParentROMFS = romfs; File = romfsFile; FileName = $"Romfs/{File.FullPath}"; }
public ControlNACP(Romfs romfs, string baseTitleID) { TitleNames = new string[15]; DeveloperNames = new string[15]; Icons = new Bitmap[15]; Languages = new List <Languages>(); BaseTitleID = baseTitleID; using (var control = new BinaryReader(romfs.OpenFile("/control.nacp"))) { var versionBytes = new byte[16]; control.BaseStream.Seek(0x3060, SeekOrigin.Begin); control.Read(versionBytes, 0, 0x10); var version = Encoding.UTF8.GetString(versionBytes); var index = version.IndexOf("\0", StringComparison.Ordinal); if (index == 0) { version = string.Empty; } if (index > 0) { version = version.Substring(0, index); } Version = version; for (var i = 0; i < 15; i++) { var offset = i * 0x300; control.BaseStream.Seek(offset, SeekOrigin.Begin); var titlenameBytes = new byte[0x200]; var developernameBytes = new byte[0x100]; control.Read(titlenameBytes, 0, 0x200); control.Read(developernameBytes, 0, 0x100); var lname = ((Languages)i).ToString(); lname = $"/icon_{lname}.dat"; if (!romfs.FileExists(lname)) { continue; } Bitmap icon; using (var bm = new Bitmap(romfs.OpenFile(lname))) { icon = new Bitmap(bm); } Languages.Add((Languages)i); var titlename = Encoding.UTF8.GetString(titlenameBytes); index = titlename.IndexOf("\0", StringComparison.Ordinal); if (index == 0) { titlename = string.Empty; } if (index > 0) { titlename = titlename.Substring(0, index); } var developername = Encoding.UTF8.GetString(developernameBytes); index = developername.IndexOf("\0", StringComparison.Ordinal); if (index == 0) { developername = string.Empty; } if (index > 0) { developername = developername.Substring(0, index); } TitleNames[i] = titlename; DeveloperNames[i] = developername; Icons[i] = icon; } } }
private void Open() { treeView1.Nodes.Clear(); string FileToOpen = null; if (Program.FileArg != null) { FileToOpen = Program.FileArg; } else { FileToOpen = openFileDialog1.FileName; } Program.FileArg = null; Stream Input = null; try { string ExpEnv(string In) => Environment.ExpandEnvironmentVariables(In); var ProdKeys = ExpEnv(@"%USERPROFILE%\.switch\prod.keys"); var TitleKeys = ExpEnv(@"%USERPROFILE%\.switch\title.keys"); var Keys = ExternalKeys.ReadKeyFile(ProdKeys, TitleKeys); var Ext = (new FileInfo(FileToOpen).Extension); if (Ext == ".nsp") { var InputPFS = File.OpenRead(FileToOpen); var Pfs = new Pfs(InputPFS); var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0])); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca"); } else if (Ext == ".xci") { var InputPFS = File.OpenRead(FileToOpen); var Xci = new Xci(Keys, InputPFS); var CnmtNca = new Nca(Keys, Xci.SecurePartition.OpenFile(Xci.SecurePartition.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0])); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Xci.SecurePartition.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = Xci.SecurePartition.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca"); } else if (FileToOpen.Split('.')[1] == "cnmt" && Ext == ".nca") { var TargetFile = File.OpenRead(FileToOpen); var CnmtNca = new Nca(Keys, TargetFile, false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0])); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, File.OpenRead($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = File.OpenRead($"{Program.NcaId.ToHexString().ToLower()}.nca"); } else { Input = File.OpenRead(FileToOpen); } try { Nca = new Nca(Keys, Input, true); if (Nca.HasRightsId && !Keys.TitleKeys.Keys.Any(k => k.SequenceEqual(Nca.Header.RightsId))) { MessageBox.Show($"Error: the titlekey for {Nca.Header.RightsId.ToHexString().ToLower()} is not present in your key file."); } else { bool isUpdateNca = false; if (Nca.Sections.Any(s => s?.Type == SectionType.Bktr)) { isUpdateNca = true; } if (isUpdateNca) { openFileDialog1.Title = "Select base Nca"; openFileDialog1.ShowDialog(); var Input2 = File.OpenRead(openFileDialog1.FileName); Patch = new Nca(Keys, Input2, true); Nca.SetBaseNca(Patch); } new Thread ( () => { Thread.CurrentThread.IsBackground = true; var Info = GetTitleMeta($"{Nca.Header.TitleId:x16}"); label2.Invoke(new Action(() => { label2.Text = Info[0]; label3.Text = Info[1]; })); } ) .Start(); Rom = new Romfs ( Nca.OpenSection ( Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None ) ); IO.PopulateTreeView(treeView1.Nodes, Rom.RootDir); } } catch { MessageBox.Show("There was an error reading the NCA. Are you sure the correct keys are present in your keyfiles?"); } } catch (ArgumentNullException) { MessageBox.Show("Error: key files are missing!"); } }
public void EnsureInitialized(ContentManager ContentManager) { if (FontData == null) { Device.Memory.FillWithZeros(PhysicalAddress, Horizon.FontSize); uint FontOffset = 0; FontInfo CreateFont(string Name) { if (ContentManager.TryGetFontTitle(Name, out long FontTitle)) { string ContentPath = ContentManager.GetInstalledContentPath(FontTitle, StorageId.NandSystem, ContentType.Data); string FontPath = Device.FileSystem.SwitchPathToSystemPath(ContentPath); if (!string.IsNullOrWhiteSpace(FontPath)) { int FileIndex = 0; //Use second file in Chinese Font title for standard if (Name == "FontChineseSimplified") { FileIndex = 1; } FileStream NcaFileStream = new FileStream(FontPath, FileMode.Open, FileAccess.Read); Nca Nca = new Nca(Device.System.KeySet, NcaFileStream, false); NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); Romfs Romfs = new Romfs(Nca.OpenSection(RomfsSection.SectionNum, false, Device.System.FsIntegrityCheckLevel)); Stream FontFile = Romfs.OpenFile(Romfs.Files[FileIndex]); byte[] Data = DecryptFont(FontFile); FontInfo Info = new FontInfo((int)FontOffset, Data.Length); WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length); FontOffset += 8; uint Start = FontOffset; for (; FontOffset - Start < Data.Length; FontOffset++) { Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]); } NcaFileStream.Dispose(); Nca.Dispose(); return(Info); } } string FontFilePath = Path.Combine(FontsPath, Name + ".ttf"); if (File.Exists(FontFilePath)) { byte[] Data = File.ReadAllBytes(FontFilePath); FontInfo Info = new FontInfo((int)FontOffset, Data.Length); WriteMagicAndSize(PhysicalAddress + FontOffset, Data.Length); FontOffset += 8; uint Start = FontOffset; for (; FontOffset - Start < Data.Length; FontOffset++) { Device.Memory.WriteByte(PhysicalAddress + FontOffset, Data[FontOffset - Start]); } return(Info); } else { throw new InvalidSystemResourceException($"Font \"{Name}.ttf\" not found. Please provide it in \"{FontsPath}\"."); } } FontData = new Dictionary <SharedFontType, FontInfo>() { { SharedFontType.JapanUsEurope, CreateFont("FontStandard") }, { SharedFontType.SimplifiedChinese, CreateFont("FontChineseSimplified") }, { SharedFontType.SimplifiedChineseEx, CreateFont("FontExtendedChineseSimplified") }, { SharedFontType.TraditionalChinese, CreateFont("FontChineseTraditional") }, { SharedFontType.Korean, CreateFont("FontKorean") }, { SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") } }; if (FontOffset > Horizon.FontSize) { throw new InvalidSystemResourceException( $"The sum of all fonts size exceed the shared memory size. " + $"Please make sure that the fonts don't exceed {Horizon.FontSize} bytes in total. " + $"(actual size: {FontOffset} bytes)."); } } }
public void LoadNca(Nca MainNca, Nca ControlNca) { NcaSection RomfsSection = MainNca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs || x?.Type == SectionType.Bktr); NcaSection ExefsSection = MainNca.Sections.FirstOrDefault(x => x?.IsExefs == true); if (ExefsSection == null) { Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA"); return; } if (RomfsSection == null) { Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA"); } else { Stream RomfsStream = MainNca.OpenSection(RomfsSection.SectionNum, false, EnableFsIntegrityChecks); Device.FileSystem.SetRomFs(RomfsStream); } Stream ExefsStream = MainNca.OpenSection(ExefsSection.SectionNum, false, EnableFsIntegrityChecks); Pfs Exefs = new Pfs(ExefsStream); Npdm MetaData = null; if (Exefs.FileExists("main.npdm")) { Logger.PrintInfo(LogClass.Loader, "Loading main.npdm..."); MetaData = new Npdm(Exefs.OpenFile("main.npdm")); } else { Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!"); } Process MainProcess = MakeProcess(MetaData); void LoadNso(string Filename) { foreach (PfsFileEntry File in Exefs.Files.Where(x => x.Name.StartsWith(Filename))) { if (Path.GetExtension(File.Name) != string.Empty) { continue; } Logger.PrintInfo(LogClass.Loader, $"Loading {Filename}..."); string Name = Path.GetFileNameWithoutExtension(File.Name); Nso Program = new Nso(Exefs.OpenFile(File), Name); MainProcess.LoadProgram(Program); } } Nacp ReadControlData() { Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, EnableFsIntegrityChecks)); byte[] ControlFile = ControlRomfs.GetFile("/control.nacp"); BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile)); Nacp ControlData = new Nacp(Reader); CurrentTitle = ControlData.Languages[(int)State.DesiredTitleLanguage].Title; if (string.IsNullOrWhiteSpace(CurrentTitle)) { CurrentTitle = ControlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; } return(ControlData); } if (ControlNca != null) { MainProcess.ControlData = ReadControlData(); } else { CurrentTitle = MainProcess.MetaData.ACI0.TitleId.ToString("x16"); } if (!MainProcess.MetaData.Is64Bits) { throw new NotImplementedException("32-bit titles are unsupported!"); } LoadNso("rtld"); MainProcess.SetEmptyArgs(); LoadNso("main"); LoadNso("subsdk"); LoadNso("sdk"); MainProcess.Run(); }
public static void Process(Context ctx) { using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) { var xci = new Xci(ctx.Keyset, file.AsStorage()); ctx.Logger.LogMessage(xci.Print()); if (ctx.Options.RootDir != null) { xci.RootPartition?.Extract(ctx.Options.RootDir, ctx.Logger); } if (ctx.Options.UpdateDir != null) { xci.UpdatePartition?.Extract(ctx.Options.UpdateDir, ctx.Logger); } if (ctx.Options.NormalDir != null) { xci.NormalPartition?.Extract(ctx.Options.NormalDir, ctx.Logger); } if (ctx.Options.SecureDir != null) { xci.SecurePartition?.Extract(ctx.Options.SecureDir, ctx.Logger); } if (ctx.Options.LogoDir != null) { xci.LogoPartition?.Extract(ctx.Options.LogoDir, ctx.Logger); } if (ctx.Options.OutDir != null && xci.RootPartition != null) { XciPartition root = xci.RootPartition; if (root == null) { ctx.Logger.LogMessage("Could not find root partition"); return; } foreach (PfsFileEntry sub in root.Files) { var subPfs = new Pfs(root.OpenFile(sub)); string subDir = Path.Combine(ctx.Options.OutDir, sub.Name); subPfs.Extract(subDir, ctx.Logger); } } if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null) { Nca mainNca = GetXciMainNca(xci, ctx); if (mainNca == null) { ctx.Logger.LogMessage("Could not find Program NCA"); return; } NcaSection exefsSection = mainNca.Sections[(int)ProgramPartitionType.Code]; if (exefsSection == null) { ctx.Logger.LogMessage("NCA has no ExeFS section"); return; } if (ctx.Options.ExefsOutDir != null) { mainNca.ExtractSection(exefsSection.SectionNum, ctx.Options.ExefsOutDir, ctx.Options.IntegrityLevel, ctx.Logger); } if (ctx.Options.ExefsOut != null) { mainNca.ExportSection(exefsSection.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger); } } if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null) { Nca mainNca = GetXciMainNca(xci, ctx); if (mainNca == null) { ctx.Logger.LogMessage("Could not find Program NCA"); return; } NcaSection romfsSection = mainNca.Sections.FirstOrDefault(x => x.Type == SectionType.Romfs); if (romfsSection == null) { ctx.Logger.LogMessage("NCA has no RomFS section"); return; } if (ctx.Options.RomfsOutDir != null) { var romfs = new Romfs(mainNca.OpenSection(romfsSection.SectionNum, false, ctx.Options.IntegrityLevel, true)); romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger); } if (ctx.Options.RomfsOut != null) { mainNca.ExportSection(romfsSection.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Options.IntegrityLevel, ctx.Logger); } } } }
public RomFsProvider(Stream storageStream) { _romFs = new Romfs(storageStream); }
//Open update only private void Open_NSP_Update(object sender, EventArgs e) { var Dialog = openFileDialog1.ShowDialog(); if (Dialog != DialogResult.Cancel) { Console.WriteLine("LOADING."); label8.Visible = true; this.Update(); treeView1.Nodes.Clear(); string FileToOpen = null; if (Program.FileArg != null) { FileToOpen = Program.FileArg; } else { FileToOpen = openFileDialog1.FileName; } Program.FileArg = null; Stream Input = null; try { string ExpEnv(string In) => Environment.ExpandEnvironmentVariables(In); var ProdKeys = ExpEnv(@"%USERPROFILE%\.switch\prod.keys"); var TitleKeys = ExpEnv(@"%USERPROFILE%\.switch\title.keys"); Console.WriteLine(FileToOpen); var Keys = ExternalKeys.ReadKeyFile(ProdKeys, TitleKeys); var Ext = (new FileInfo(FileToOpen).Extension); if (Ext == ".nsp") { var InputPFS = File.OpenRead(FileToOpen); var Pfs = new Pfs(InputPFS.AsStorage()); var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream()); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream(); } else { Input = File.OpenRead(FileToOpen); } try { Nca = new Nca(Keys, Input.AsStorage(), true); if (Nca.HasRightsId && !Keys.TitleKeys.Keys.Any(k => k.SequenceEqual(Nca.Header.RightsId))) { MessageBox.Show($"Error: the titlekey for {Nca.Header.RightsId.ToHexString().ToLower()} is not present in your key file."); } else { var isUpdateNca = false; if (Nca.Sections.Any(s => s?.Type == SectionType.Bktr)) { isUpdateNca = true; } if (isUpdateNca) { var InputPFS = File.OpenRead(FileToOpen); var Pfs = new Pfs(InputPFS.AsStorage()); var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false); var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true)); var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream()); var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program); var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control); if (CtrlEntry != null) { Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false); } Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream(); var Input2 = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream(); Patch = new Nca(Keys, Input2.AsStorage(), true); Nca.SetBaseNca(Patch); } new Thread (() => { Thread.CurrentThread.IsBackground = true; var Info = GetTitleMeta($"{Nca.Header.TitleId:x16}"); label2.Invoke(new Action(() => { label2.Text = Info[0]; label3.Text = Info[1]; })); }).Start(); Rom = new Romfs( Nca.OpenSection(Nca.Sections.FirstOrDefault (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr) .SectionNum, false, IntegrityCheckLevel.None, true) ); IO.PopulateTreeView(treeView1.Nodes, Rom.RootDir); Console.WriteLine("DONE."); fileToolStripMenuItem.Text = "File / Explore"; label8.Visible = false; this.Update(); } } catch { MessageBox.Show("There was an error reading the NCA. Are you sure the correct keys are present in your keyfiles?"); } } catch (ArgumentNullException) { MessageBox.Show("Error: key files are missing!"); } } }
public void LoadNca(Nca mainNca, Nca controlNca) { if (mainNca.Header.ContentType != ContentType.Program) { Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA"); return; } Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel); Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel); if (exefsStream == null) { Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA"); return; } if (romfsStream == null) { Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA"); } else { Device.FileSystem.SetRomFs(romfsStream); } Pfs exefs = new Pfs(exefsStream); Npdm metaData = null; if (exefs.FileExists("main.npdm")) { Logger.PrintInfo(LogClass.Loader, "Loading main.npdm..."); metaData = new Npdm(exefs.OpenFile("main.npdm")); } else { Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!"); metaData = GetDefaultNpdm(); } List <IExecutable> staticObjects = new List <IExecutable>(); void LoadNso(string filename) { foreach (PfsFileEntry file in exefs.Files.Where(x => x.Name.StartsWith(filename))) { if (Path.GetExtension(file.Name) != string.Empty) { continue; } Logger.PrintInfo(LogClass.Loader, $"Loading {filename}..."); NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file)); staticObjects.Add(staticObject); } } Nacp ReadControlData() { Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel)); byte[] controlFile = controlRomfs.GetFile("/control.nacp"); BinaryReader reader = new BinaryReader(new MemoryStream(controlFile)); Nacp controlData = new Nacp(reader); CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title; if (string.IsNullOrWhiteSpace(CurrentTitle)) { CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; } return(controlData); } if (controlNca != null) { ReadControlData(); } else { CurrentTitle = metaData.Aci0.TitleId.ToString("x16"); } if (!metaData.Is64Bits) { throw new NotImplementedException("32-bit titles are not supported!"); } LoadNso("rtld"); LoadNso("main"); LoadNso("subsdk"); LoadNso("sdk"); ContentManager.LoadEntries(); ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray()); }