mirror of
https://github.com/SabreTools/NDecrypt.git
synced 2026-07-08 18:06:38 +00:00
Migrate NDS to using standard models
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NDecrypt.Core;
|
||||
using NDecrypt.Nitro.Headers;
|
||||
using SabreTools.Models.Nitro;
|
||||
|
||||
namespace NDecrypt.Nitro
|
||||
{
|
||||
@@ -42,15 +44,15 @@ namespace NDecrypt.Nitro
|
||||
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)))
|
||||
{
|
||||
NDSHeader? header = NDSHeader.Read(reader);
|
||||
if (header == null)
|
||||
Cart? cart = NDSHeader.Read(reader);
|
||||
if (cart == null)
|
||||
{
|
||||
Console.WriteLine("Error: Not a DS or DSi Rom!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Process the secure area
|
||||
ProcessSecureArea(header, reader, writer);
|
||||
ProcessSecureArea(cart, reader, writer);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -66,10 +68,10 @@ namespace NDecrypt.Nitro
|
||||
/// <summary>
|
||||
/// Process secure area in the DS/DSi file
|
||||
/// </summary>
|
||||
/// <param name="ndsHeader">NDS header representing the DS file</param>
|
||||
/// <param name="cart">Cart representing the DS file</param>
|
||||
/// <param name="reader">BinaryReader representing the input stream</param>
|
||||
/// <param name="writer">BinaryWriter representing the output stream</param>
|
||||
private void ProcessSecureArea(NDSHeader ndsHeader, BinaryReader reader, BinaryWriter writer)
|
||||
private void ProcessSecureArea(Cart cart, BinaryReader reader, BinaryWriter writer)
|
||||
{
|
||||
// If we're forcing the operation, tell the user
|
||||
if (decryptArgs.Force)
|
||||
@@ -79,7 +81,7 @@ namespace NDecrypt.Nitro
|
||||
// If we're not forcing the operation, check to see if we should be proceeding
|
||||
else
|
||||
{
|
||||
bool? isDecrypted = DSTool.CheckIfDecrypted(reader);
|
||||
bool? isDecrypted = CheckIfDecrypted(reader);
|
||||
if (isDecrypted == null)
|
||||
{
|
||||
Console.WriteLine("File has an empty secure area, cannot proceed");
|
||||
@@ -92,7 +94,7 @@ namespace NDecrypt.Nitro
|
||||
}
|
||||
}
|
||||
|
||||
ProcessARM9(ndsHeader, reader, writer);
|
||||
ProcessARM9(cart.CommonHeader!, reader, writer);
|
||||
|
||||
Console.WriteLine("File has been " + (decryptArgs.Encrypt ? "encrypted" : "decrypted"));
|
||||
}
|
||||
@@ -159,10 +161,10 @@ namespace NDecrypt.Nitro
|
||||
/// <summary>
|
||||
/// Process the secure ARM9 region of the file, if possible
|
||||
/// </summary>
|
||||
/// <param name="ndsHeader">NDS header representing the DS file</param>
|
||||
/// <param name="commonHeader">CommonHeader representing the DS header</param>
|
||||
/// <param name="reader">BinaryReader representing the input stream</param>
|
||||
/// <param name="writer">BinaryWriter representing the output stream</param>
|
||||
private void ProcessARM9(NDSHeader ndsHeader, BinaryReader reader, BinaryWriter writer)
|
||||
private void ProcessARM9(CommonHeader commonHeader, BinaryReader reader, BinaryWriter writer)
|
||||
{
|
||||
// Seek to the beginning of the secure area
|
||||
reader.BaseStream.Seek(0x4000, SeekOrigin.Begin);
|
||||
@@ -173,7 +175,7 @@ namespace NDecrypt.Nitro
|
||||
uint p1 = reader.ReadUInt32();
|
||||
|
||||
// Perform the initialization steps
|
||||
Init1(ndsHeader);
|
||||
Init1(commonHeader);
|
||||
if (!decryptArgs.Encrypt) Decrypt(ref p1, ref p0);
|
||||
_arg2[1] <<= 1;
|
||||
_arg2[2] >>= 1;
|
||||
@@ -231,7 +233,7 @@ namespace NDecrypt.Nitro
|
||||
}
|
||||
|
||||
Encrypt(ref p1, ref p0);
|
||||
Init1(ndsHeader);
|
||||
Init1(commonHeader);
|
||||
Encrypt(ref p1, ref p0);
|
||||
|
||||
writer.Write(p0);
|
||||
@@ -242,11 +244,11 @@ namespace NDecrypt.Nitro
|
||||
/// <summary>
|
||||
/// First common initialization step
|
||||
/// </summary>
|
||||
/// <param name="ndsHeader">NDS header representing the DS file</param>
|
||||
private void Init1(NDSHeader ndsHeader)
|
||||
/// <param name="commonHeader">CommonHeader representing the DS file</param>
|
||||
private void Init1(CommonHeader commonHeader)
|
||||
{
|
||||
Buffer.BlockCopy(Constants.NDSEncryptionData, 0, _cardHash, 0, 4 * (1024 + 18));
|
||||
_arg2 = [ndsHeader.Gamecode, ndsHeader.Gamecode >> 1, ndsHeader.Gamecode << 1];
|
||||
_arg2 = [commonHeader.GameCode, commonHeader.GameCode >> 1, commonHeader.GameCode << 1];
|
||||
Init2();
|
||||
Init2();
|
||||
}
|
||||
|
||||
@@ -1,578 +1,145 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.Models.Nitro;
|
||||
|
||||
namespace NDecrypt.Nitro.Headers
|
||||
{
|
||||
internal class NDSHeader
|
||||
internal static class NDSHeader
|
||||
{
|
||||
#region Common
|
||||
|
||||
/// <summary>
|
||||
/// Game Title
|
||||
/// </summary>
|
||||
public char[]? GameTitle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gamecode
|
||||
/// </summary>
|
||||
public uint Gamecode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Makercode
|
||||
/// </summary>
|
||||
public char[]? Makercode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unitcode
|
||||
/// </summary>
|
||||
public NDSUnitcode Unitcode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Encryption seed select (device code. 0 = normal)
|
||||
/// </summary>
|
||||
public byte EncryptionSeedSelect { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Devicecapacity
|
||||
/// </summary>
|
||||
public byte Devicecapacity { get; private set; }
|
||||
public int DeviceCapacityInBytes { get { return (1 << Devicecapacity) * (1024 * 1024); } }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved1 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Game Revision (used by DSi titles)
|
||||
/// </summary>
|
||||
public ushort GameRevision { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ROM Version
|
||||
/// </summary>
|
||||
public byte RomVersion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal flags, (Bit2: Autostart)
|
||||
/// </summary>
|
||||
public byte InternalFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 rom offset
|
||||
/// </summary>
|
||||
public uint ARM9RomOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 entry address
|
||||
/// </summary>
|
||||
public uint ARM9EntryAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 load address
|
||||
/// </summary>
|
||||
public uint ARM9LoadAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 size
|
||||
/// </summary>
|
||||
public uint ARM9Size { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 rom offset
|
||||
/// </summary>
|
||||
public uint ARM7RomOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 entry address
|
||||
/// </summary>
|
||||
public uint ARM7EntryAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 load address
|
||||
/// </summary>
|
||||
public uint ARM7LoadAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 size
|
||||
/// </summary>
|
||||
public uint ARM7Size { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) offset
|
||||
/// </summary>
|
||||
public uint FileNameTableOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) length
|
||||
/// </summary>
|
||||
public uint FileNameTableLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Allocation Table (FNT) offset
|
||||
/// </summary>
|
||||
public uint FileAllocationTableOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Allocation Table (FNT) length
|
||||
/// </summary>
|
||||
public uint FileAllocationTableLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) offset
|
||||
/// </summary>
|
||||
public uint ARM9OverlayOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) length
|
||||
/// </summary>
|
||||
public uint ARM9OverlayLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) offset
|
||||
/// </summary>
|
||||
public uint ARM7OverlayOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File Name Table (FNT) length
|
||||
/// </summary>
|
||||
public uint ARM7OverlayLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normal card control register settings (0x00416657 for OneTimePROM)
|
||||
/// </summary>
|
||||
public byte[]? NormalCardControlRegisterSettings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Secure card control register settings (0x081808F8 for OneTimePROM)
|
||||
/// </summary>
|
||||
public byte[]? SecureCardControlRegisterSettings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Icon Banner offset (NDSi same as NDS, but with new extra entries)
|
||||
/// </summary>
|
||||
public uint IconBannerOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Secure area (2K) CRC
|
||||
/// </summary>
|
||||
public ushort SecureAreaCRC { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Secure transfer timeout (0x0D7E for OneTimePROM)
|
||||
/// </summary>
|
||||
public ushort SecureTransferTimeout { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 autoload
|
||||
/// </summary>
|
||||
public byte[]? ARM9Autoload { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 autoload
|
||||
/// </summary>
|
||||
public byte[]? ARM7Autoload { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Secure disable
|
||||
/// </summary>
|
||||
public byte[]? SecureDisable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// NTR region ROM size (excluding DSi area)
|
||||
/// </summary>
|
||||
public uint NTRRegionRomSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header size
|
||||
/// </summary>
|
||||
public uint HeaderSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///Reserved (0x88, 0x8C, 0x90 = Unknown, used by DSi)
|
||||
/// </summary>
|
||||
public byte[]? Reserved2 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nintendo Logo
|
||||
/// </summary>
|
||||
public byte[]? NintendoLogo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nintendo Logo CRC
|
||||
/// </summary>
|
||||
public ushort NintendoLogoCRC { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header CRC
|
||||
/// </summary>
|
||||
public ushort HeaderCRC { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Debugger reserved
|
||||
/// </summary>
|
||||
public byte[]? DebuggerReserved { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extended DSi
|
||||
|
||||
/// <summary>
|
||||
/// Global MBK1..MBK5 Settings
|
||||
/// </summary>
|
||||
public byte[]? GlobalMBK15Settings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Local MBK6..MBK8 Settings for ARM9
|
||||
/// </summary>
|
||||
public byte[]? LocalMBK68SettingsARM9 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Local MBK6..MBK8 Settings for ARM7
|
||||
/// </summary>
|
||||
public byte[]? LocalMBK68SettingsARM7 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Global MBK9 Setting
|
||||
/// </summary>
|
||||
public byte[]? GlobalMBK9Setting { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public byte[]? RegionFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Access control
|
||||
/// </summary>
|
||||
public byte[]? AccessControl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 SCFG EXT mask (controls which devices to enable)
|
||||
/// </summary>
|
||||
public byte[]? ARM7SCFGEXTMask { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/flags? When bit2 of byte 0x1bf is set, usage of banner.sav from the title data dir is enabled.(additional banner data)
|
||||
/// </summary>
|
||||
public byte[]? ReservedFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9i rom offset
|
||||
/// </summary>
|
||||
public uint ARM9iRomOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved3 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9i load address
|
||||
/// </summary>
|
||||
public uint ARM9iLoadAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9i size;
|
||||
/// </summary>
|
||||
public uint ARM9iSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7i rom offset
|
||||
/// </summary>
|
||||
public uint ARM7iRomOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pointer to base address where various structures and parameters are passed to the title - what is that???
|
||||
/// </summary>
|
||||
public byte[]? Reserved4 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7i load address
|
||||
/// </summary>
|
||||
public uint ARM7iLoadAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7i size;
|
||||
/// </summary>
|
||||
public uint ARM7iSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest NTR region offset
|
||||
/// </summary>
|
||||
public uint DigestNTRRegionOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest NTR region length
|
||||
/// </summary>
|
||||
public uint DigestNTRRegionLength { get; private set; }
|
||||
|
||||
// <summary>
|
||||
/// Digest TWL region offset
|
||||
/// </summary>
|
||||
public uint DigestTWLRegionOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest TWL region length
|
||||
/// </summary>
|
||||
public uint DigestTWLRegionLength { get; private set; }
|
||||
|
||||
// <summary>
|
||||
/// Digest Sector Hashtable region offset
|
||||
/// </summary>
|
||||
public uint DigestSectorHashtableRegionOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest Sector Hashtable region length
|
||||
/// </summary>
|
||||
public uint DigestSectorHashtableRegionLength { get; private set; }
|
||||
|
||||
// <summary>
|
||||
/// Digest Block Hashtable region offset
|
||||
/// </summary>
|
||||
public uint DigestBlockHashtableRegionOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest Block Hashtable region length
|
||||
/// </summary>
|
||||
public uint DigestBlockHashtableRegionLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest Sector size
|
||||
/// </summary>
|
||||
public uint DigestSectorSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digeset Block Sectorount
|
||||
/// </summary>
|
||||
public uint DigestBlockSectorCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Icon Banner Size (usually 0x23C0)
|
||||
/// </summary>
|
||||
public uint IconBannerSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown (used by DSi)
|
||||
/// </summary>
|
||||
public byte[]? Unknown1 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// NTR+TWL region ROM size (total size including DSi area)
|
||||
/// </summary>
|
||||
public uint NTRTWLRegionRomSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown (used by DSi)
|
||||
/// </summary>
|
||||
public byte[]? Unknown2 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Modcrypt area 1 offset
|
||||
/// </summary>
|
||||
public uint ModcryptArea1Offset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Modcrypt area 1 size
|
||||
/// </summary>
|
||||
public uint ModcryptArea1Size { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Modcrypt area 2 offset
|
||||
/// </summary>
|
||||
public uint ModcryptArea2Offset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Modcrypt area 2 size
|
||||
/// </summary>
|
||||
public uint ModcryptArea2Size { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Title ID
|
||||
/// </summary>
|
||||
public byte[]? TitleID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// DSiWare: "public.sav" size
|
||||
/// </summary>
|
||||
public uint DSiWarePublicSavSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// DSiWare: "private.sav" size
|
||||
/// </summary>
|
||||
public uint DSiWarePrivateSavSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved (zero)
|
||||
/// </summary>
|
||||
public byte[]? ReservedZero { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown (used by DSi)
|
||||
/// </summary>
|
||||
public byte[]? Unknown3 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 (with encrypted secure area) SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? ARM9WithSecureAreaSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7 SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? ARM7SHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Digest master SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? DigestMasterSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Banner SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? BannerSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9i (decrypted) SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? ARM9iDecryptedSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM7i (decrypted) SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? ARM7iDecryptedSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved5 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// ARM9 (without secure area) SHA1 HMAC hash
|
||||
/// </summary>
|
||||
public byte[]? ARM9NoSecureAreaSHA1HMACHash { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
public byte[]? Reserved6 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reserved and unchecked region, always zero. Used for passing arguments in debug environment.
|
||||
/// </summary>
|
||||
public byte[]? ReservedAndUnchecked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// RSA signature (the first 0xE00 bytes of the header are signed with an 1024-bit RSA signature).
|
||||
/// </summary>
|
||||
public byte[]? RSASignature { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Read from a stream and get an NDS/NDSi header, if possible
|
||||
/// Read from a stream and get an NDS/NDSi Cart, if possible
|
||||
/// </summary>
|
||||
/// <param name="reader">BinaryReader representing the input stream</param>
|
||||
/// <returns>NDS/NDSi header object, null on error</returns>
|
||||
public static NDSHeader? Read(BinaryReader reader)
|
||||
/// <returns>NDS/NDSi Cart object, null on error</returns>
|
||||
public static Cart? Read(BinaryReader reader)
|
||||
{
|
||||
var header = new NDSHeader();
|
||||
var cart = new Cart();
|
||||
|
||||
try
|
||||
{
|
||||
header.GameTitle = reader.ReadChars(0xC);
|
||||
header.Gamecode = reader.ReadUInt32();
|
||||
header.Makercode = reader.ReadChars(2);
|
||||
header.Unitcode = (NDSUnitcode)reader.ReadByte();
|
||||
header.EncryptionSeedSelect = reader.ReadByte();
|
||||
header.Devicecapacity = reader.ReadByte();
|
||||
header.Reserved1 = reader.ReadBytes(7);
|
||||
header.GameRevision = reader.ReadUInt16();
|
||||
header.RomVersion = reader.ReadByte();
|
||||
header.InternalFlags = reader.ReadByte();
|
||||
header.ARM9RomOffset = reader.ReadUInt32();
|
||||
header.ARM9EntryAddress = reader.ReadUInt32();
|
||||
header.ARM9LoadAddress = reader.ReadUInt32();
|
||||
header.ARM9Size = reader.ReadUInt32();
|
||||
header.ARM7RomOffset = reader.ReadUInt32();
|
||||
header.ARM7EntryAddress = reader.ReadUInt32();
|
||||
header.ARM7LoadAddress = reader.ReadUInt32();
|
||||
header.ARM7Size = reader.ReadUInt32();
|
||||
header.FileNameTableOffset = reader.ReadUInt32();
|
||||
header.FileNameTableLength = reader.ReadUInt32();
|
||||
header.FileAllocationTableOffset = reader.ReadUInt32();
|
||||
header.FileAllocationTableLength = reader.ReadUInt32();
|
||||
header.ARM9OverlayOffset = reader.ReadUInt32();
|
||||
header.ARM9OverlayLength = reader.ReadUInt32();
|
||||
header.ARM7OverlayOffset = reader.ReadUInt32();
|
||||
header.ARM7OverlayLength = reader.ReadUInt32();
|
||||
header.SecureDisable = reader.ReadBytes(8);
|
||||
header.NTRRegionRomSize = reader.ReadUInt32();
|
||||
header.HeaderSize = reader.ReadUInt32();
|
||||
header.Reserved2 = reader.ReadBytes(56);
|
||||
header.NintendoLogo = reader.ReadBytes(156);
|
||||
header.NintendoLogoCRC = reader.ReadUInt16();
|
||||
header.DebuggerReserved = reader.ReadBytes(0x20);
|
||||
var commonHeader = new CommonHeader();
|
||||
|
||||
// If we have a DSi compatible title
|
||||
if (header.Unitcode == NDSUnitcode.NDSPlusDSi
|
||||
|| header.Unitcode == NDSUnitcode.DSi)
|
||||
{
|
||||
header.GlobalMBK15Settings = reader.ReadBytes(20);
|
||||
header.LocalMBK68SettingsARM9 = reader.ReadBytes(12);
|
||||
header.LocalMBK68SettingsARM7 = reader.ReadBytes(12);
|
||||
header.GlobalMBK9Setting = reader.ReadBytes(4);
|
||||
header.RegionFlags = reader.ReadBytes(4);
|
||||
header.AccessControl = reader.ReadBytes(4);
|
||||
header.ARM7SCFGEXTMask = reader.ReadBytes(4);
|
||||
header.ReservedFlags = reader.ReadBytes(4);
|
||||
header.ARM9iRomOffset = reader.ReadUInt32();
|
||||
header.Reserved3 = reader.ReadBytes(4);
|
||||
header.ARM9iLoadAddress = reader.ReadUInt32();
|
||||
header.ARM9iSize = reader.ReadUInt32();
|
||||
header.ARM7iRomOffset = reader.ReadUInt32();
|
||||
header.Reserved4 = reader.ReadBytes(4);
|
||||
header.ARM7iLoadAddress = reader.ReadUInt32();
|
||||
header.ARM7iSize = reader.ReadUInt32();
|
||||
header.DigestNTRRegionOffset = reader.ReadUInt32();
|
||||
header.DigestNTRRegionLength = reader.ReadUInt32();
|
||||
header.DigestTWLRegionOffset = reader.ReadUInt32();
|
||||
header.DigestTWLRegionLength = reader.ReadUInt32();
|
||||
header.DigestSectorHashtableRegionOffset = reader.ReadUInt32();
|
||||
header.DigestSectorHashtableRegionLength = reader.ReadUInt32();
|
||||
header.DigestBlockHashtableRegionOffset = reader.ReadUInt32();
|
||||
header.DigestBlockHashtableRegionLength = reader.ReadUInt32();
|
||||
header.DigestSectorSize = reader.ReadUInt32();
|
||||
header.DigestBlockSectorCount = reader.ReadUInt32();
|
||||
header.IconBannerSize = reader.ReadUInt32();
|
||||
header.Unknown1 = reader.ReadBytes(4);
|
||||
header.ModcryptArea1Offset = reader.ReadUInt32();
|
||||
header.ModcryptArea1Size = reader.ReadUInt32();
|
||||
header.ModcryptArea2Offset = reader.ReadUInt32();
|
||||
header.ModcryptArea2Size = reader.ReadUInt32();
|
||||
header.TitleID = reader.ReadBytes(8);
|
||||
header.DSiWarePublicSavSize = reader.ReadUInt32();
|
||||
header.DSiWarePrivateSavSize = reader.ReadUInt32();
|
||||
header.ReservedZero = reader.ReadBytes(176);
|
||||
header.Unknown2 = reader.ReadBytes(0x10);
|
||||
header.ARM9WithSecureAreaSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.ARM7SHA1HMACHash = reader.ReadBytes(20);
|
||||
header.DigestMasterSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.BannerSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.ARM9iDecryptedSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.ARM7iDecryptedSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.Reserved5 = reader.ReadBytes(40);
|
||||
header.ARM9NoSecureAreaSHA1HMACHash = reader.ReadBytes(20);
|
||||
header.Reserved6 = reader.ReadBytes(2636);
|
||||
header.ReservedAndUnchecked = reader.ReadBytes(0x180);
|
||||
header.RSASignature = reader.ReadBytes(0x80);
|
||||
}
|
||||
byte[] gameTitleBytes = reader.ReadBytes(0x0C);
|
||||
commonHeader.GameTitle = Encoding.ASCII.GetString(gameTitleBytes);
|
||||
commonHeader.GameCode = reader.ReadUInt32();
|
||||
byte[] makerCodeBytes = reader.ReadBytes(2);
|
||||
commonHeader.MakerCode = Encoding.ASCII.GetString(makerCodeBytes);
|
||||
commonHeader.UnitCode = (Unitcode)reader.ReadByte();
|
||||
commonHeader.EncryptionSeedSelect = reader.ReadByte();
|
||||
commonHeader.DeviceCapacity = reader.ReadByte();
|
||||
commonHeader.Reserved1 = reader.ReadBytes(7);
|
||||
commonHeader.GameRevision = reader.ReadUInt16();
|
||||
commonHeader.RomVersion = reader.ReadByte();
|
||||
commonHeader.InternalFlags = reader.ReadByte();
|
||||
commonHeader.ARM9RomOffset = reader.ReadUInt32();
|
||||
commonHeader.ARM9EntryAddress = reader.ReadUInt32();
|
||||
commonHeader.ARM9LoadAddress = reader.ReadUInt32();
|
||||
commonHeader.ARM9Size = reader.ReadUInt32();
|
||||
commonHeader.ARM7RomOffset = reader.ReadUInt32();
|
||||
commonHeader.ARM7EntryAddress = reader.ReadUInt32();
|
||||
commonHeader.ARM7LoadAddress = reader.ReadUInt32();
|
||||
commonHeader.ARM7Size = reader.ReadUInt32();
|
||||
commonHeader.FileNameTableOffset = reader.ReadUInt32();
|
||||
commonHeader.FileNameTableLength = reader.ReadUInt32();
|
||||
commonHeader.FileAllocationTableOffset = reader.ReadUInt32();
|
||||
commonHeader.FileAllocationTableLength = reader.ReadUInt32();
|
||||
commonHeader.ARM9OverlayOffset = reader.ReadUInt32();
|
||||
commonHeader.ARM9OverlayLength = reader.ReadUInt32();
|
||||
commonHeader.ARM7OverlayOffset = reader.ReadUInt32();
|
||||
commonHeader.ARM7OverlayLength = reader.ReadUInt32();
|
||||
commonHeader.SecureDisable = reader.ReadBytes(8);
|
||||
commonHeader.NTRRegionRomSize = reader.ReadUInt32();
|
||||
commonHeader.HeaderSize = reader.ReadUInt32();
|
||||
commonHeader.Reserved2 = reader.ReadBytes(56);
|
||||
commonHeader.NintendoLogo = reader.ReadBytes(156);
|
||||
commonHeader.NintendoLogoCRC = reader.ReadUInt16();
|
||||
commonHeader.DebuggerReserved = reader.ReadBytes(0x20);
|
||||
|
||||
return header;
|
||||
cart.CommonHeader = commonHeader;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// If we have a DSi compatible title
|
||||
if (cart.CommonHeader.UnitCode == Unitcode.NDSPlusDSi
|
||||
|| cart.CommonHeader.UnitCode == Unitcode.DSi)
|
||||
{
|
||||
var extendedDsiHeader = new ExtendedDSiHeader();
|
||||
|
||||
extendedDsiHeader.GlobalMBK15Settings = new uint[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
extendedDsiHeader.GlobalMBK15Settings[i] = reader.ReadUInt32();
|
||||
}
|
||||
extendedDsiHeader.LocalMBK68SettingsARM9 = new uint[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
extendedDsiHeader.LocalMBK68SettingsARM9[i] = reader.ReadUInt32();
|
||||
}
|
||||
extendedDsiHeader.LocalMBK68SettingsARM7 = new uint[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
extendedDsiHeader.LocalMBK68SettingsARM7[i] = reader.ReadUInt32();
|
||||
}
|
||||
extendedDsiHeader.GlobalMBK9Setting = reader.ReadUInt32();
|
||||
extendedDsiHeader.RegionFlags = reader.ReadUInt32();
|
||||
extendedDsiHeader.AccessControl = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM7SCFGEXTMask = reader.ReadUInt32();
|
||||
extendedDsiHeader.ReservedFlags = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM9iRomOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.Reserved3 = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM9iLoadAddress = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM9iSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM7iRomOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.Reserved4 = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM7iLoadAddress = reader.ReadUInt32();
|
||||
extendedDsiHeader.ARM7iSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestNTRRegionOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestNTRRegionLength = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestTWLRegionOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestTWLRegionLength = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestSectorHashtableRegionOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestSectorHashtableRegionLength = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestBlockHashtableRegionOffset = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestBlockHashtableRegionLength = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestSectorSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.DigestBlockSectorCount = reader.ReadUInt32();
|
||||
extendedDsiHeader.IconBannerSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.Unknown1 = reader.ReadUInt32();
|
||||
extendedDsiHeader.ModcryptArea1Offset = reader.ReadUInt32();
|
||||
extendedDsiHeader.ModcryptArea1Size = reader.ReadUInt32();
|
||||
extendedDsiHeader.ModcryptArea2Offset = reader.ReadUInt32();
|
||||
extendedDsiHeader.ModcryptArea2Size = reader.ReadUInt32();
|
||||
extendedDsiHeader.TitleID = reader.ReadBytes(8);
|
||||
extendedDsiHeader.DSiWarePublicSavSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.DSiWarePrivateSavSize = reader.ReadUInt32();
|
||||
extendedDsiHeader.ReservedZero = reader.ReadBytes(176);
|
||||
extendedDsiHeader.Unknown2 = reader.ReadBytes(0x10);
|
||||
extendedDsiHeader.ARM9WithSecureAreaSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.ARM7SHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.DigestMasterSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.BannerSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.ARM9iDecryptedSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.ARM7iDecryptedSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.Reserved5 = reader.ReadBytes(40);
|
||||
extendedDsiHeader.ARM9NoSecureAreaSHA1HMACHash = reader.ReadBytes(20);
|
||||
extendedDsiHeader.Reserved6 = reader.ReadBytes(2636);
|
||||
extendedDsiHeader.ReservedAndUnchecked = reader.ReadBytes(0x180);
|
||||
extendedDsiHeader.RSASignature = reader.ReadBytes(0x80);
|
||||
|
||||
cart.ExtendedDSiHeader = extendedDsiHeader;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return cart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<VersionPrefix>0.2.5</VersionPrefix>
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<VersionPrefix>0.2.5</VersionPrefix>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>NDS encryption and decryption code</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2019-2024</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/SabreTools/NDecrypt</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>NDS encryption and decryption code</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2019-2024</Copyright>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/SabreTools/NDecrypt</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NDecrypt.Core\NDecrypt.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NDecrypt.Core\NDecrypt.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user