mirror of
https://github.com/SabreTools/NDecrypt.git
synced 2026-09-23 07:14:53 +00:00
Add CIA header (nw)
This commit is contained in:
80
NDecrypt/N3DS/CIATool.cs
Normal file
80
NDecrypt/N3DS/CIATool.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using NDecrypt.N3DS.Headers;
|
||||
|
||||
namespace NDecrypt.N3DS
|
||||
{
|
||||
// https://www.3dbrew.org/wiki/CIA
|
||||
internal class CIATool : ITool
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the input CIA file
|
||||
/// </summary>
|
||||
private readonly string filename;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to detrmine if development keys should be used
|
||||
/// </summary>
|
||||
private readonly bool development;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to determine if encrypting or decrypting
|
||||
/// </summary>
|
||||
private readonly bool encrypt;
|
||||
|
||||
/// <summary>
|
||||
/// Flag to determine if forcing operations
|
||||
/// </summary>
|
||||
private readonly bool force;
|
||||
|
||||
public CIATool(string filename, bool development, bool encrypt, bool force)
|
||||
{
|
||||
this.filename = filename;
|
||||
this.development = development;
|
||||
this.encrypt = encrypt;
|
||||
this.force = force;
|
||||
}
|
||||
|
||||
#region Common Methods
|
||||
|
||||
/// <summary>
|
||||
/// Process an input file given the input values
|
||||
/// </summary>
|
||||
public bool ProcessFile()
|
||||
{
|
||||
// Ensure the constants are all set
|
||||
Constants.Init();
|
||||
if (Constants.IsReady != true)
|
||||
{
|
||||
Console.WriteLine("Could not read keys from keys.bin. Please make sure the file exists and try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Open the read and write on the same file for inplace processing
|
||||
using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
|
||||
using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)))
|
||||
{
|
||||
CIAHeader header = CIAHeader.Read(reader);
|
||||
if (header == null)
|
||||
{
|
||||
Console.WriteLine("Error: Not a 3DS Rom!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Implement CIA encrypt/decrypt
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine($"An error has occurred. {filename} may be corrupted if it was partially processed.");
|
||||
Console.WriteLine("Please check that the file was a valid 3DS or New 3DS file and try again.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
114
NDecrypt/N3DS/Headers/CIAHeader.cs
Normal file
114
NDecrypt/N3DS/Headers/CIAHeader.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System.IO;
|
||||
|
||||
namespace NDecrypt.N3DS.Headers
|
||||
{
|
||||
internal class CIAHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Archive header size, usually 0x2020 bytes
|
||||
/// </summary>
|
||||
public uint HeaderSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type
|
||||
/// </summary>
|
||||
public ushort Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version
|
||||
/// </summary>
|
||||
public ushort Version { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Certificate chain size
|
||||
/// </summary>
|
||||
public int CertificateChainSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ticket size
|
||||
/// </summary>
|
||||
public int TicketSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// TMD file size
|
||||
/// </summary>
|
||||
public int TMDFileSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Meta size (0 if no Meta data is present)
|
||||
/// </summary>
|
||||
public int MetaSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content size
|
||||
/// </summary>
|
||||
public long ContentSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content Index
|
||||
/// </summary>
|
||||
public byte[] ContentIndex { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Certificate chain
|
||||
/// </summary>
|
||||
public byte[] CertificateChain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ticket
|
||||
/// </summary>
|
||||
public byte[] Ticket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TMD file data
|
||||
/// </summary>
|
||||
public byte[] TMDFileData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Content file data
|
||||
/// </summary>
|
||||
public byte[] ContentFileData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Meta file data (Not a necessary component)
|
||||
/// </summary>
|
||||
public MetaFile MetaFileData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read from a stream and get a CIA header, if possible
|
||||
/// </summary>
|
||||
/// <param name="reader">BinaryReader representing the input stream</param>
|
||||
/// <returns>CIA header object, null on error</returns>
|
||||
public static CIAHeader Read(BinaryReader reader)
|
||||
{
|
||||
CIAHeader header = new CIAHeader();
|
||||
|
||||
try
|
||||
{
|
||||
header.HeaderSize = reader.ReadUInt32();
|
||||
header.Type = reader.ReadUInt16();
|
||||
header.Version = reader.ReadUInt16();
|
||||
header.CertificateChainSize = reader.ReadInt32();
|
||||
header.TicketSize = reader.ReadInt32();
|
||||
header.TMDFileSize = reader.ReadInt32();
|
||||
header.MetaSize = reader.ReadInt32();
|
||||
header.ContentSize = reader.ReadInt64();
|
||||
header.ContentIndex = reader.ReadBytes(0x2000);
|
||||
|
||||
header.CertificateChain = reader.ReadBytes(header.CertificateChainSize);
|
||||
header.Ticket = reader.ReadBytes(header.TicketSize);
|
||||
header.TMDFileData = reader.ReadBytes(header.TMDFileSize);
|
||||
header.ContentFileData = reader.ReadBytes((int)header.ContentSize);
|
||||
|
||||
if (header.MetaSize > 0)
|
||||
header.MetaFileData = MetaFile.Read(reader);
|
||||
|
||||
return header;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
NDecrypt/N3DS/Headers/MetaFile.cs
Normal file
57
NDecrypt/N3DS/Headers/MetaFile.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.IO;
|
||||
|
||||
namespace NDecrypt.N3DS.Headers
|
||||
{
|
||||
internal class MetaFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Title ID dependency list - Taken from the application's ExHeader
|
||||
/// </summary>
|
||||
public byte[] TitleIDDependencyList { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[] Reserved1 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Core Version
|
||||
/// </summary>
|
||||
public uint CoreVersion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[] Reserved2 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Icon Data(.ICN) - Taken from the application's ExeFS
|
||||
/// </summary>
|
||||
public byte[] IconData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read from a stream and get the Metafile data, if possible
|
||||
/// </summary>
|
||||
/// <param name="reader">BinaryReader representing the input stream</param>
|
||||
/// <returns>Metafile data object, null on error</returns>
|
||||
public static MetaFile Read(BinaryReader reader)
|
||||
{
|
||||
MetaFile metaFile = new MetaFile();
|
||||
|
||||
try
|
||||
{
|
||||
metaFile.TitleIDDependencyList = reader.ReadBytes(0x180);
|
||||
metaFile.Reserved1 = reader.ReadBytes(0x180);
|
||||
metaFile.CoreVersion = reader.ReadUInt32();
|
||||
metaFile.Reserved2 = reader.ReadBytes(0xFC);
|
||||
metaFile.IconData = reader.ReadBytes(0x36C0);
|
||||
|
||||
return metaFile;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ namespace NDecrypt
|
||||
iQueDS,
|
||||
N3DS,
|
||||
iQue3DS,
|
||||
N3DSCIA,
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
@@ -139,6 +140,9 @@ More than one path can be specified at a time.");
|
||||
case FileType.N3DS:
|
||||
Console.WriteLine("File recognized as Nintendo 3DS");
|
||||
return new ThreeDSTool(filename, development, encrypt, force);
|
||||
// case FileType.N3DSCIA:
|
||||
// Console.WriteLine("File recognized as Nintendo 3DS");
|
||||
// return new CIATool(filename, development, encrypt, force);
|
||||
case FileType.NULL:
|
||||
default:
|
||||
Console.WriteLine($"Unrecognized file format for {filename}. Expected *.nds, *.srl, *.dsi, *.3ds");
|
||||
@@ -165,6 +169,9 @@ More than one path can be specified at a time.");
|
||||
|
||||
else if (filename.EndsWith(".3ds", StringComparison.OrdinalIgnoreCase))
|
||||
return FileType.N3DS;
|
||||
|
||||
else if (filename.EndsWith(".cia", StringComparison.OrdinalIgnoreCase))
|
||||
return FileType.N3DSCIA;
|
||||
|
||||
return FileType.NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user