mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Extract ExeFS and RomFS for more input types
This commit is contained in:
parent
dce63507d1
commit
8433b2c91a
2 changed files with 132 additions and 33 deletions
|
@ -156,7 +156,10 @@ namespace hactoolnet
|
||||||
sb.AppendLine(" --section1dir <dir> Specify Section 1 directory path.");
|
sb.AppendLine(" --section1dir <dir> Specify Section 1 directory path.");
|
||||||
sb.AppendLine(" --section2dir <dir> Specify Section 2 directory path.");
|
sb.AppendLine(" --section2dir <dir> Specify Section 2 directory path.");
|
||||||
sb.AppendLine(" --section3dir <dir> Specify Section 3 directory path.");
|
sb.AppendLine(" --section3dir <dir> Specify Section 3 directory path.");
|
||||||
sb.AppendLine(" --romfsdir <dir> Specify main RomFS directory path.");
|
sb.AppendLine(" --exefs <file> Specify ExeFS directory path.");
|
||||||
|
sb.AppendLine(" --exefsdir <dir> Specify ExeFS directory path.");
|
||||||
|
sb.AppendLine(" --romfs <file> Specify RomFS directory path.");
|
||||||
|
sb.AppendLine(" --romfsdir <dir> Specify RomFS directory path.");
|
||||||
sb.AppendLine(" --listromfs List files in RomFS.");
|
sb.AppendLine(" --listromfs List files in RomFS.");
|
||||||
sb.AppendLine(" --basenca Set Base NCA to use with update partitions.");
|
sb.AppendLine(" --basenca Set Base NCA to use with update partitions.");
|
||||||
sb.AppendLine("XCI options:");
|
sb.AppendLine("XCI options:");
|
||||||
|
@ -166,13 +169,19 @@ namespace hactoolnet
|
||||||
sb.AppendLine(" --securedir <dir> Specify secure XCI directory path.");
|
sb.AppendLine(" --securedir <dir> Specify secure XCI directory path.");
|
||||||
sb.AppendLine(" --logodir <dir> Specify logo XCI directory path.");
|
sb.AppendLine(" --logodir <dir> Specify logo XCI directory path.");
|
||||||
sb.AppendLine(" --outdir <dir> Specify XCI directory path.");
|
sb.AppendLine(" --outdir <dir> Specify XCI directory path.");
|
||||||
|
sb.AppendLine(" --exefs <file> Specify main ExeFS file path.");
|
||||||
|
sb.AppendLine(" --exefsdir <dir> Specify main ExeFS directory path.");
|
||||||
|
sb.AppendLine(" --romfs <file> Specify main RomFS file path.");
|
||||||
sb.AppendLine(" --romfsdir <dir> Specify main RomFS directory path.");
|
sb.AppendLine(" --romfsdir <dir> Specify main RomFS directory path.");
|
||||||
sb.AppendLine("Switch FS options:");
|
sb.AppendLine("Switch FS options:");
|
||||||
sb.AppendLine(" --sdseed <seed> Set console unique seed for SD card NAX0 encryption.");
|
sb.AppendLine(" --sdseed <seed> Set console unique seed for SD card NAX0 encryption.");
|
||||||
sb.AppendLine(" --listapps List application info.");
|
sb.AppendLine(" --listapps List application info.");
|
||||||
sb.AppendLine(" --listtitles List title info for all titles.");
|
sb.AppendLine(" --listtitles List title info for all titles.");
|
||||||
sb.AppendLine(" --title <title id> Specify title ID to use.");
|
sb.AppendLine(" --title <title id> Specify title ID to use.");
|
||||||
sb.AppendLine(" --outdir <dir> Specify directory path to save title to. (--title must be specified)");
|
sb.AppendLine(" --outdir <dir> Specify directory path to save title NCAs to. (--title must be specified)");
|
||||||
|
sb.AppendLine(" --exefs <file> Specify ExeFS directory path. (--title must be specified)");
|
||||||
|
sb.AppendLine(" --exefsdir <dir> Specify ExeFS directory path. (--title must be specified)");
|
||||||
|
sb.AppendLine(" --romfs <file> Specify RomFS directory path. (--title must be specified)");
|
||||||
sb.AppendLine(" --romfsdir <dir> Specify RomFS directory path. (--title must be specified)");
|
sb.AppendLine(" --romfsdir <dir> Specify RomFS directory path. (--title must be specified)");
|
||||||
sb.AppendLine("Savefile options:");
|
sb.AppendLine("Savefile options:");
|
||||||
sb.AppendLine(" --outdir <dir> Specify directory path to save contents to.");
|
sb.AppendLine(" --outdir <dir> Specify directory path to save contents to.");
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null)
|
||||||
{
|
{
|
||||||
NcaSection section = nca.Sections.FirstOrDefault(x => x.Type == SectionType.Romfs || x.Type == SectionType.Bktr);
|
NcaSection section = nca.Sections.FirstOrDefault(x => x.Type == SectionType.Romfs || x.Type == SectionType.Bktr);
|
||||||
|
|
||||||
|
@ -105,27 +105,25 @@ namespace hactoolnet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section.Type == SectionType.Bktr)
|
if (section.Type == SectionType.Bktr && ctx.Options.BaseNca == null)
|
||||||
{
|
{
|
||||||
if (ctx.Options.BaseNca == null)
|
ctx.Logger.LogMessage("Cannot save BKTR section without base RomFS");
|
||||||
{
|
return;
|
||||||
ctx.Logger.LogMessage("Cannot save BKTR section without base RomFS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bktr = nca.OpenSection(1, false);
|
|
||||||
var romfs = new Romfs(bktr);
|
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (ctx.Options.RomfsOut != null)
|
||||||
|
{
|
||||||
|
nca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
{
|
{
|
||||||
var romfs = new Romfs(nca.OpenSection(section.SectionNum, false));
|
var romfs = new Romfs(nca.OpenSection(section.SectionNum, false));
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.ExefsOutDir != null)
|
if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null)
|
||||||
{
|
{
|
||||||
NcaSection section = nca.Sections.FirstOrDefault(x => x.IsExefs);
|
NcaSection section = nca.Sections.FirstOrDefault(x => x.IsExefs);
|
||||||
|
|
||||||
|
@ -135,7 +133,15 @@ namespace hactoolnet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Logger);
|
if (ctx.Options.ExefsOut != null)
|
||||||
|
{
|
||||||
|
nca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
|
{
|
||||||
|
nca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Logger.LogMessage(nca.Dump());
|
ctx.Logger.LogMessage(nca.Dump());
|
||||||
|
@ -156,7 +162,47 @@ namespace hactoolnet
|
||||||
ctx.Logger.LogMessage(ListApplications(switchFs));
|
ctx.Logger.LogMessage(ListApplications(switchFs));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null)
|
||||||
|
{
|
||||||
|
var id = ctx.Options.TitleId;
|
||||||
|
if (id == 0)
|
||||||
|
{
|
||||||
|
ctx.Logger.LogMessage("Title ID must be specified to dump ExeFS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!switchFs.Titles.TryGetValue(id, out var title))
|
||||||
|
{
|
||||||
|
ctx.Logger.LogMessage($"Could not find title {id:X16}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title.MainNca == null)
|
||||||
|
{
|
||||||
|
ctx.Logger.LogMessage($"Could not find main data for title {id:X16}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var section = title.MainNca.Sections.FirstOrDefault(x => x.IsExefs == true);
|
||||||
|
|
||||||
|
if (section == null)
|
||||||
|
{
|
||||||
|
ctx.Logger.LogMessage($"Main NCA for title {id:X16} has no ExeFS section");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
|
{
|
||||||
|
title.MainNca.ExtractSection(section.SectionNum, ctx.Options.ExefsOutDir, ctx.Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.ExefsOut != null)
|
||||||
|
{
|
||||||
|
title.MainNca.ExportSection(section.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null)
|
||||||
{
|
{
|
||||||
var id = ctx.Options.TitleId;
|
var id = ctx.Options.TitleId;
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
|
@ -181,12 +227,20 @@ namespace hactoolnet
|
||||||
|
|
||||||
if (section == null)
|
if (section == null)
|
||||||
{
|
{
|
||||||
ctx.Logger.LogMessage($"Main NCA for title {id:X16} has no Rom FS section");
|
ctx.Logger.LogMessage($"Main NCA for title {id:X16} has no RomFS section");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var romfs = new Romfs(title.MainNca.OpenSection(section.SectionNum, false));
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
{
|
||||||
|
var romfs = new Romfs(title.MainNca.OpenSection(section.SectionNum, false));
|
||||||
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.RomfsOut != null)
|
||||||
|
{
|
||||||
|
title.MainNca.ExportSection(section.SectionNum, ctx.Options.RomfsOut, ctx.Options.Raw, ctx.Logger);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.OutDir != null)
|
if (ctx.Options.OutDir != null)
|
||||||
|
@ -249,27 +303,39 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null)
|
if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null)
|
||||||
{
|
{
|
||||||
if (xci.SecurePartition == null)
|
var mainNca = GetXciMainNca(xci, ctx);
|
||||||
|
|
||||||
|
if (mainNca == null)
|
||||||
{
|
{
|
||||||
ctx.Logger.LogMessage("Could not find secure partition");
|
ctx.Logger.LogMessage("Could not find Program NCA");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nca mainNca = null;
|
var exefsSection = mainNca.Sections.FirstOrDefault(x => x.IsExefs == true);
|
||||||
|
|
||||||
foreach (var fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
|
if (exefsSection == null)
|
||||||
{
|
{
|
||||||
var ncaStream = xci.SecurePartition.OpenFile(fileEntry);
|
ctx.Logger.LogMessage("NCA has no ExeFS section");
|
||||||
var nca = new Nca(ctx.Keyset, ncaStream, true);
|
return;
|
||||||
|
|
||||||
if (nca.Header.ContentType == ContentType.Program)
|
|
||||||
{
|
|
||||||
mainNca = nca;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.ExefsOutDir != null)
|
||||||
|
{
|
||||||
|
mainNca.ExtractSection(exefsSection.SectionNum, ctx.Options.ExefsOutDir, ctx.Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.ExefsOut != null)
|
||||||
|
{
|
||||||
|
mainNca.ExportSection(exefsSection.SectionNum, ctx.Options.ExefsOut, ctx.Options.Raw, ctx.Logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.Options.RomfsOutDir != null || ctx.Options.RomfsOut != null)
|
||||||
|
{
|
||||||
|
var mainNca = GetXciMainNca(xci, ctx);
|
||||||
|
|
||||||
if (mainNca == null)
|
if (mainNca == null)
|
||||||
{
|
{
|
||||||
ctx.Logger.LogMessage("Could not find Program NCA");
|
ctx.Logger.LogMessage("Could not find Program NCA");
|
||||||
|
@ -298,6 +364,30 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Nca GetXciMainNca(Xci xci, Context ctx)
|
||||||
|
{
|
||||||
|
if (xci.SecurePartition == null)
|
||||||
|
{
|
||||||
|
ctx.Logger.LogMessage("Could not find secure partition");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nca mainNca = null;
|
||||||
|
|
||||||
|
foreach (var fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
|
||||||
|
{
|
||||||
|
var ncaStream = xci.SecurePartition.OpenFile(fileEntry);
|
||||||
|
var nca = new Nca(ctx.Keyset, ncaStream, true);
|
||||||
|
|
||||||
|
if (nca.Header.ContentType == ContentType.Program)
|
||||||
|
{
|
||||||
|
mainNca = nca;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mainNca;
|
||||||
|
}
|
||||||
|
|
||||||
private static void OpenKeyset(Context ctx)
|
private static void OpenKeyset(Context ctx)
|
||||||
{
|
{
|
||||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||||
|
|
Loading…
Reference in a new issue