diff --git a/BurnOutSharp.Builders/N3DS.cs b/BurnOutSharp.Builders/N3DS.cs
index 32ac33e6..c134c1c2 100644
--- a/BurnOutSharp.Builders/N3DS.cs
+++ b/BurnOutSharp.Builders/N3DS.cs
@@ -82,17 +82,13 @@ namespace BurnOutSharp.Builders
#region Development Card Info Header
- // TODO: Hook up a builder flag to enable development parsing
- if (false)
- {
- // Try to parse the development card info header
- var developmentCardInfoHeader = ParseDevelopmentCardInfoHeader(data);
- if (developmentCardInfoHeader == null)
- return null;
+ // Try to parse the development card info header
+ var developmentCardInfoHeader = ParseDevelopmentCardInfoHeader(data);
+ if (developmentCardInfoHeader == null)
+ return null;
- // Set the development card info header
- cart.DevelopmentCardInfoHeader = developmentCardInfoHeader;
- }
+ // Set the development card info header
+ cart.DevelopmentCardInfoHeader = developmentCardInfoHeader;
#endregion
@@ -109,6 +105,10 @@ namespace BurnOutSharp.Builders
#endregion
+ // TODO: Parse partition extended headers (decrypted only)
+ // TODO: Parse ExeFS file entries (decrypted only)
+ // TODO: Parse ExeFS filename table (decrypted only)
+
return cart;
}
@@ -124,7 +124,7 @@ namespace BurnOutSharp.Builders
header.RSA2048Signature = data.ReadBytes(0x100);
byte[] magicNumber = data.ReadBytes(4);
- header.MagicNumber = Encoding.ASCII.GetString(magicNumber).TrimEnd('\0');;
+ header.MagicNumber = Encoding.ASCII.GetString(magicNumber).TrimEnd('\0'); ;
if (header.MagicNumber != NCSDMagicNumber)
return null;
@@ -269,10 +269,7 @@ namespace BurnOutSharp.Builders
header.RSA2048Signature = data.ReadBytes(0x100);
byte[] magicId = data.ReadBytes(4);
- header.MagicID = Encoding.ASCII.GetString(magicId).TrimEnd('\0');;
- if (header.MagicID != NCCHMagicNumber)
- return null;
-
+ header.MagicID = Encoding.ASCII.GetString(magicId).TrimEnd('\0');
header.ContentSizeInMediaUnits = data.ReadUInt32();
header.PartitionId = data.ReadUInt64();
header.MakerCode = data.ReadUInt16();
@@ -281,7 +278,8 @@ namespace BurnOutSharp.Builders
header.ProgramId = data.ReadBytes(8);
header.Reserved1 = data.ReadBytes(0x10);
header.LogoRegionHash = data.ReadBytes(0x20);
- header.ProductCode = data.ReadBytes(0x10);
+ byte[] productCode = data.ReadBytes(0x10);
+ header.ProductCode = Encoding.ASCII.GetString(productCode).TrimEnd('\0');
header.ExtendedHeaderHash = data.ReadBytes(0x20);
header.ExtendedHeaderSizeInBytes = data.ReadUInt32();
header.Reserved2 = data.ReadBytes(4);
diff --git a/BurnOutSharp.Models/N3DS/InitialData.cs b/BurnOutSharp.Models/N3DS/InitialData.cs
index 9415671c..1b57c223 100644
--- a/BurnOutSharp.Models/N3DS/InitialData.cs
+++ b/BurnOutSharp.Models/N3DS/InitialData.cs
@@ -9,7 +9,8 @@ namespace BurnOutSharp.Models.N3DS
public byte[] CardSeedKeyY;
///
- /// Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see CTRCARD_SECSEED) ///
+ /// Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see CTRCARD_SECSEED)
+ ///
public byte[] EncryptedCardSeed;
///
diff --git a/BurnOutSharp.Models/N3DS/NCCHHeader.cs b/BurnOutSharp.Models/N3DS/NCCHHeader.cs
index c363398b..1ea8c092 100644
--- a/BurnOutSharp.Models/N3DS/NCCHHeader.cs
+++ b/BurnOutSharp.Models/N3DS/NCCHHeader.cs
@@ -59,7 +59,7 @@
///
/// Product code
///
- public byte[] ProductCode;
+ public string ProductCode;
///
/// Extended header SHA-256 hash (SHA256 of 2x Alignment Size, beginning at 0x0 of ExHeader)
diff --git a/BurnOutSharp.Wrappers/N3DS.cs b/BurnOutSharp.Wrappers/N3DS.cs
index d8371b1a..64977ab9 100644
--- a/BurnOutSharp.Wrappers/N3DS.cs
+++ b/BurnOutSharp.Wrappers/N3DS.cs
@@ -371,6 +371,39 @@ namespace BurnOutSharp.Wrappers
Console.WriteLine($" Card seed AES-MAC: {BitConverter.ToString(DCIH_ID_CardSeedAESMAC).Replace('-', ' ')}");
Console.WriteLine($" Card seed nonce: {BitConverter.ToString(DCIH_ID_CardSeedNonce).Replace('-', ' ')}");
Console.WriteLine($" Reserved: {BitConverter.ToString(DCIH_ID_Reserved).Replace('-', ' ')}");
+ Console.WriteLine();
+
+ Console.WriteLine(" Backup Header:");
+ Console.WriteLine(" -------------------------");
+ Console.WriteLine($" Magic ID: {DCIH_ID_BackupHeader.MagicID}");
+ Console.WriteLine($" Content size in media units: {DCIH_ID_BackupHeader.ContentSizeInMediaUnits}");
+ Console.WriteLine($" Partition ID: {DCIH_ID_BackupHeader.PartitionId}");
+ Console.WriteLine($" Maker code: {DCIH_ID_BackupHeader.MakerCode}");
+ Console.WriteLine($" Version: {DCIH_ID_BackupHeader.Version}");
+ Console.WriteLine($" Verification hash: {DCIH_ID_BackupHeader.VerificationHash}");
+ Console.WriteLine($" Program ID: {BitConverter.ToString(DCIH_ID_BackupHeader.ProgramId).Replace('-', ' ')}");
+ Console.WriteLine($" Reserved 1: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved1).Replace('-', ' ')}");
+ Console.WriteLine($" Logo region SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.LogoRegionHash).Replace('-', ' ')}");
+ Console.WriteLine($" Product code: {DCIH_ID_BackupHeader.ProductCode}");
+ Console.WriteLine($" Extended header SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.ExtendedHeaderHash).Replace('-', ' ')}");
+ Console.WriteLine($" Extended header size in bytes: {DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes}");
+ Console.WriteLine($" Reserved 2: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved2).Replace('-', ' ')}");
+ Console.WriteLine($" Flags: {DCIH_ID_BackupHeader.Flags}");
+ Console.WriteLine($" Plain region offset, in media units: {DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits}");
+ Console.WriteLine($" Plain region size, in media units: {DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits}");
+ Console.WriteLine($" Logo region offset, in media units: {DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits}");
+ Console.WriteLine($" Logo region size, in media units: {DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits}");
+ Console.WriteLine($" ExeFS offset, in media units: {DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits}");
+ Console.WriteLine($" ExeFS size, in media units: {DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits}");
+ Console.WriteLine($" ExeFS hash region size, in media units: {DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits}");
+ Console.WriteLine($" Reserved 3: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved3).Replace('-', ' ')}");
+ Console.WriteLine($" RomFS offset, in media units: {DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits}");
+ Console.WriteLine($" RomFS size, in media units: {DCIH_ID_BackupHeader.RomFSSizeInMediaUnits}");
+ Console.WriteLine($" RomFS hash region size, in media units: {DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits}");
+ Console.WriteLine($" Reserved 4: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved4).Replace('-', ' ')}");
+ Console.WriteLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.ExeFSSuperblockHash).Replace('-', ' ')}");
+ Console.WriteLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.RomFSSuperblockHash).Replace('-', ' ')}");
+
// TODO: Print Backup Header?
Console.WriteLine();
@@ -413,35 +446,54 @@ namespace BurnOutSharp.Wrappers
{
var partitionHeader = Partitions[i];
Console.WriteLine($" NCCH Partition Header {i}");
- Console.WriteLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(partitionHeader.RSA2048Signature).Replace('-', ' ')}");
- Console.WriteLine($" Magic ID: {partitionHeader.MagicID}");
- Console.WriteLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits}");
- Console.WriteLine($" Partition ID: {partitionHeader.PartitionId}");
- Console.WriteLine($" Maker code: {partitionHeader.MakerCode}");
- Console.WriteLine($" Version: {partitionHeader.Version}");
- Console.WriteLine($" Verification hash: {partitionHeader.VerificationHash}");
- Console.WriteLine($" Program ID: {BitConverter.ToString(partitionHeader.ProgramId).Replace('-', ' ')}");
- Console.WriteLine($" Reserved 1: {BitConverter.ToString(partitionHeader.Reserved1).Replace('-', ' ')}");
- Console.WriteLine($" Logo region SHA-256 hash: {BitConverter.ToString(partitionHeader.LogoRegionHash).Replace('-', ' ')}");
- Console.WriteLine($" Product code: {BitConverter.ToString(partitionHeader.ProductCode).Replace('-', ' ')}");
- Console.WriteLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}");
- Console.WriteLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes}");
- Console.WriteLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}");
- Console.WriteLine($" Flags: {partitionHeader.Flags}");
- Console.WriteLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits}");
- Console.WriteLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits}");
- Console.WriteLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits}");
- Console.WriteLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits}");
- Console.WriteLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits}");
- Console.WriteLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits}");
- Console.WriteLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits}");
- Console.WriteLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}");
- Console.WriteLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits}");
- Console.WriteLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits}");
- Console.WriteLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits}");
- Console.WriteLine($" Reserved 4: {BitConverter.ToString(partitionHeader.Reserved4).Replace('-', ' ')}");
- Console.WriteLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.ExeFSSuperblockHash).Replace('-', ' ')}");
- Console.WriteLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.RomFSSuperblockHash).Replace('-', ' ')}");
+ if (partitionHeader.MagicID == string.Empty)
+ {
+ Console.WriteLine($" Empty partition, no data can be parsed");
+ }
+ else if (partitionHeader.MagicID != Models.N3DS.Constants.NCCHMagicNumber)
+ {
+ Console.WriteLine($" Unrecognized partition data, no data can be parsed");
+ }
+ else
+ {
+ Console.WriteLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(partitionHeader.RSA2048Signature).Replace('-', ' ')}");
+ Console.WriteLine($" Magic ID: {partitionHeader.MagicID}");
+ Console.WriteLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits}");
+ Console.WriteLine($" Partition ID: {partitionHeader.PartitionId}");
+ Console.WriteLine($" Maker code: {partitionHeader.MakerCode}");
+ Console.WriteLine($" Version: {partitionHeader.Version}");
+ Console.WriteLine($" Verification hash: {partitionHeader.VerificationHash}");
+ Console.WriteLine($" Program ID: {BitConverter.ToString(partitionHeader.ProgramId).Replace('-', ' ')}");
+ Console.WriteLine($" Reserved 1: {BitConverter.ToString(partitionHeader.Reserved1).Replace('-', ' ')}");
+ Console.WriteLine($" Logo region SHA-256 hash: {BitConverter.ToString(partitionHeader.LogoRegionHash).Replace('-', ' ')}");
+ Console.WriteLine($" Product code: {partitionHeader.ProductCode}");
+ Console.WriteLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}");
+ Console.WriteLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes}");
+ Console.WriteLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}");
+ Console.WriteLine(" Flags:");
+ Console.WriteLine($" Reserved 0: {partitionHeader.Flags.Reserved0}");
+ Console.WriteLine($" Reserved 1: {partitionHeader.Flags.Reserved1}");
+ Console.WriteLine($" Reserved 2: {partitionHeader.Flags.Reserved2}");
+ Console.WriteLine($" Crypto method: {partitionHeader.Flags.CryptoMethod}");
+ Console.WriteLine($" Content platform: {partitionHeader.Flags.ContentPlatform}");
+ Console.WriteLine($" Content type: {partitionHeader.Flags.MediaPlatformIndex}");
+ Console.WriteLine($" Content unit size: {partitionHeader.Flags.ContentUnitSize}");
+ Console.WriteLine($" Bitmasks: {partitionHeader.Flags.BitMasks}");
+ Console.WriteLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits}");
+ Console.WriteLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits}");
+ Console.WriteLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits}");
+ Console.WriteLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits}");
+ Console.WriteLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits}");
+ Console.WriteLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits}");
+ Console.WriteLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits}");
+ Console.WriteLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}");
+ Console.WriteLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits}");
+ Console.WriteLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits}");
+ Console.WriteLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits}");
+ Console.WriteLine($" Reserved 4: {BitConverter.ToString(partitionHeader.Reserved4).Replace('-', ' ')}");
+ Console.WriteLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.ExeFSSuperblockHash).Replace('-', ' ')}");
+ Console.WriteLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.RomFSSuperblockHash).Replace('-', ' ')}");
+ }
}
}
Console.WriteLine();