mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
hactoolnet: add nax0 support
This commit is contained in:
parent
d68062c8b4
commit
496250f094
4 changed files with 87 additions and 1 deletions
|
@ -12,7 +12,7 @@ namespace LibHac.FsSystem
|
|||
private int BlockSize { get; }
|
||||
private OpenMode Mode { get; }
|
||||
|
||||
private AesXtsFileHeader Header { get; }
|
||||
public AesXtsFileHeader Header { get; }
|
||||
private IStorage BaseStorage { get; }
|
||||
|
||||
internal const int HeaderLength = 0x4000;
|
||||
|
|
|
@ -272,6 +272,10 @@ namespace hactoolnet
|
|||
sb.AppendLine(" --listfiles List files in save file.");
|
||||
sb.AppendLine(" --repack <dir> Replaces the contents of the save data with the specified directory.");
|
||||
sb.AppendLine(" --replacefile <filename in save> <file> Replaces a file in the save data");
|
||||
sb.AppendLine("NAX0 options:");
|
||||
sb.AppendLine(" --sdseed <seed> Set console unique seed for SD card NAX0 encryption.");
|
||||
sb.AppendLine(" --sdpath <path> Set relative path for NAX0 key derivation (ex: /registered/000000FF/cafebabecafebabecafebabecafebabe.nca).");
|
||||
sb.AppendLine(" --plaintext Specify file path to save decrypted contents.");
|
||||
sb.AppendLine("NDV0 (Delta) options:");
|
||||
sb.AppendLine(" Input delta patch can be a delta NCA file or a delta fragment file.");
|
||||
sb.AppendLine(" --basefile <file> Specify base file path.");
|
||||
|
|
81
src/hactoolnet/ProcessNax0.cs
Normal file
81
src/hactoolnet/ProcessNax0.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibHac;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem;
|
||||
using static hactoolnet.Print;
|
||||
|
||||
namespace hactoolnet
|
||||
{
|
||||
internal static class ProcessNax0
|
||||
{
|
||||
public static void Process(Context ctx)
|
||||
{
|
||||
byte[][] keys = ctx.Keyset.SdCardKeys;
|
||||
|
||||
using var baseFile = new LocalFile(ctx.Options.InFile, OpenMode.Read);
|
||||
|
||||
AesXtsFile xtsFile = null;
|
||||
int contentType = 0;
|
||||
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
byte[] kekSource = keys[i].AsSpan(0, 0x10).ToArray();
|
||||
byte[] validationKey = keys[i].AsSpan(0x10, 0x10).ToArray();
|
||||
|
||||
try
|
||||
{
|
||||
xtsFile = new AesXtsFile(OpenMode.Read, baseFile, ctx.Options.SdPath, kekSource, validationKey, 0x4000);
|
||||
contentType = i;
|
||||
|
||||
break;
|
||||
}
|
||||
catch (HorizonResultException) { }
|
||||
}
|
||||
|
||||
if (xtsFile == null)
|
||||
{
|
||||
ctx.Logger.LogMessage($"Error: NAX0 key derivation failed. Check SD card seed and relative path.");
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.Logger.LogMessage(xtsFile.Print(contentType));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ctx.Options.PlaintextOut)) return;
|
||||
|
||||
xtsFile.AsStorage().WriteAllBytes(ctx.Options.PlaintextOut, ctx.Logger);
|
||||
ctx.Logger.LogMessage($"Saved Decrypted NAX0 Content to {ctx.Options.PlaintextOut}...");
|
||||
}
|
||||
|
||||
private static string Print(this AesXtsFile xtsFile, int contentType)
|
||||
{
|
||||
int colLen = 36;
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine("NAX0:");
|
||||
|
||||
AesXtsFileHeader header = xtsFile.Header;
|
||||
uint magic = header.Magic;
|
||||
|
||||
PrintItem(sb, colLen, " Magic:", Util.GetUtf8String(SpanHelpers.AsReadOnlyByteSpan(ref magic)));
|
||||
PrintItem(sb, colLen, " Content Type:", GetContentType(contentType));
|
||||
PrintItem(sb, colLen, " Content Size:", $"{header.Size:x12}");
|
||||
PrintItem(sb, colLen, " Header HMAC:", header.Signature);
|
||||
PrintItem(sb, colLen, " Encrypted Keys:", header.EncryptedKey1.Concat(header.EncryptedKey2).ToArray());
|
||||
PrintItem(sb, colLen, " Decrypted Keys:", header.DecryptedKey1.Concat(header.DecryptedKey2).ToArray());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string GetContentType(int type) => type switch
|
||||
{
|
||||
0 => "Save",
|
||||
1 => "NCA",
|
||||
2 => "Custom storage",
|
||||
_ => "Unknown"
|
||||
};
|
||||
}
|
||||
}
|
|
@ -126,6 +126,7 @@ namespace hactoolnet
|
|||
ProcessFsBuild.ProcessRomFs(ctx);
|
||||
break;
|
||||
case FileType.Nax0:
|
||||
ProcessNax0.Process(ctx);
|
||||
break;
|
||||
case FileType.SwitchFs:
|
||||
ProcessSwitchFs.Process(ctx);
|
||||
|
|
Loading…
Reference in a new issue