LibHac/hactoolnet/Program.cs

148 lines
6 KiB
C#
Raw Normal View History

2018-06-21 18:16:51 +02:00
using System;
using System.IO;
2018-07-03 04:21:35 +02:00
using System.Text;
2018-08-31 17:47:11 +02:00
using LibHac;
using LibHac.Savefile;
2018-06-16 19:11:38 +02:00
2018-06-21 16:25:20 +02:00
namespace hactoolnet
2018-06-16 19:11:38 +02:00
{
2018-06-21 16:25:20 +02:00
public static class Program
2018-06-16 19:11:38 +02:00
{
2018-07-05 23:37:30 +02:00
public static void Main(string[] args)
2018-06-28 03:25:25 +02:00
{
2018-07-03 04:21:35 +02:00
Console.OutputEncoding = Encoding.UTF8;
2018-07-02 22:12:41 +02:00
var ctx = new Context();
ctx.Options = CliParser.Parse(args);
if (ctx.Options == null) return;
using (var logger = new ProgressBar())
{
ctx.Logger = logger;
OpenKeyset(ctx);
2018-07-06 04:37:46 +02:00
if (ctx.Options.RunCustom)
{
CustomTask(ctx);
return;
}
2018-07-02 22:12:41 +02:00
switch (ctx.Options.InFileType)
{
case FileType.Nca:
ProcessNca.Process(ctx);
2018-07-02 22:12:41 +02:00
break;
case FileType.Pfs0:
break;
case FileType.Romfs:
ProcessRomfs.Process(ctx);
2018-07-02 22:12:41 +02:00
break;
case FileType.Nax0:
break;
case FileType.SwitchFs:
ProcessSwitchFs.Process(ctx);
2018-07-02 22:12:41 +02:00
break;
case FileType.Save:
ProcessSave(ctx);
break;
2018-08-12 22:45:10 +02:00
case FileType.Xci:
ProcessXci.Process(ctx);
2018-08-12 22:45:10 +02:00
break;
2018-08-28 00:40:06 +02:00
case FileType.Keygen:
ProcessKeygen(ctx);
break;
2018-09-13 02:51:21 +02:00
case FileType.Pk11:
ProcessPackage.ProcessPk11(ctx);
2018-09-13 02:51:21 +02:00
break;
2018-07-02 22:12:41 +02:00
default:
throw new ArgumentOutOfRangeException();
}
}
2018-06-28 03:25:25 +02:00
}
2018-07-02 22:12:41 +02:00
private static void OpenKeyset(Context ctx)
{
2018-07-03 04:21:35 +02:00
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var homeKeyFile = Path.Combine(home, ".switch", "prod.keys");
2018-07-09 18:47:32 +02:00
var homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys");
var homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys");
2018-07-03 04:21:35 +02:00
var keyFile = ctx.Options.Keyfile;
var titleKeyFile = ctx.Options.TitleKeyFile;
2018-07-09 18:47:32 +02:00
var consoleKeyFile = ctx.Options.ConsoleKeyFile;
2018-07-03 04:21:35 +02:00
if (keyFile == null && File.Exists(homeKeyFile))
{
keyFile = homeKeyFile;
}
if (titleKeyFile == null && File.Exists(homeTitleKeyFile))
{
titleKeyFile = homeTitleKeyFile;
}
2018-07-09 18:47:32 +02:00
if (consoleKeyFile == null && File.Exists(homeConsoleKeyFile))
{
consoleKeyFile = homeConsoleKeyFile;
}
ctx.Keyset = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger);
2018-07-03 04:21:35 +02:00
if (ctx.Options.SdSeed != null)
{
ctx.Keyset.SetSdSeed(ctx.Options.SdSeed.ToBytes());
}
2018-07-02 22:12:41 +02:00
}
private static void ProcessSave(Context ctx)
{
using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read))
{
2018-09-16 05:10:42 +02:00
var save = new Savefile(ctx.Keyset, file, ctx.Logger);
2018-07-24 21:51:52 +02:00
if (ctx.Options.OutDir != null)
{
2018-07-24 21:51:52 +02:00
save.Extract(ctx.Options.OutDir, ctx.Logger);
}
2018-07-24 21:51:52 +02:00
if (ctx.Options.DebugOutDir != null)
{
2018-07-24 21:51:52 +02:00
var dir = ctx.Options.DebugOutDir;
Directory.CreateDirectory(dir);
2018-09-01 21:23:45 +02:00
File.WriteAllBytes(Path.Combine(dir, "L0_0_MasterHashA"), save.Header.MasterHashA);
File.WriteAllBytes(Path.Combine(dir, "L0_1_MasterHashB"), save.Header.MasterHashB);
File.WriteAllBytes(Path.Combine(dir, "L0_2_DuplexMasterA"), save.Header.DuplexMasterA);
File.WriteAllBytes(Path.Combine(dir, "L0_3_DuplexMasterB"), save.Header.DuplexMasterB);
save.DuplexL1A.WriteAllBytes(Path.Combine(dir, "L0_4_DuplexL1A"), ctx.Logger);
save.DuplexL1B.WriteAllBytes(Path.Combine(dir, "L0_5_DuplexL1B"), ctx.Logger);
save.DuplexDataA.WriteAllBytes(Path.Combine(dir, "L0_6_DuplexDataA"), ctx.Logger);
save.DuplexDataB.WriteAllBytes(Path.Combine(dir, "L0_7_DuplexDataB"), ctx.Logger);
save.JournalData.WriteAllBytes(Path.Combine(dir, "L0_9_JournalData"), ctx.Logger);
save.DuplexData.WriteAllBytes(Path.Combine(dir, "L1_0_DuplexData"), ctx.Logger);
save.JournalTable.WriteAllBytes(Path.Combine(dir, "L2_0_JournalTable"), ctx.Logger);
save.JournalBitmapUpdatedPhysical.WriteAllBytes(Path.Combine(dir, "L2_1_JournalBitmapUpdatedPhysical"), ctx.Logger);
save.JournalBitmapUpdatedVirtual.WriteAllBytes(Path.Combine(dir, "L2_2_JournalBitmapUpdatedVirtual"), ctx.Logger);
save.JournalBitmapUnassigned.WriteAllBytes(Path.Combine(dir, "L2_3_JournalBitmapUnassigned"), ctx.Logger);
save.JournalLayer1Hash.WriteAllBytes(Path.Combine(dir, "L2_4_Layer1Hash"), ctx.Logger);
save.JournalLayer2Hash.WriteAllBytes(Path.Combine(dir, "L2_5_Layer2Hash"), ctx.Logger);
save.JournalLayer3Hash.WriteAllBytes(Path.Combine(dir, "L2_6_Layer3Hash"), ctx.Logger);
save.JournalFat.WriteAllBytes(Path.Combine(dir, "L2_7_FAT"), ctx.Logger);
save.JournalStreamSource.CreateStream().WriteAllBytes(Path.Combine(dir, "L3_0_SaveData"), ctx.Logger);
}
}
}
2018-08-28 00:40:06 +02:00
private static void ProcessKeygen(Context ctx)
{
Console.WriteLine(ExternalKeys.PrintKeys(ctx.Keyset));
}
2018-07-05 23:37:30 +02:00
// For running random stuff
// ReSharper disable once UnusedParameter.Local
private static void CustomTask(Context ctx)
{
}
2018-06-16 19:11:38 +02:00
}
}