From ea6b0f1ca34047624a97c3fae949be591b0eb3e6 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 15 Sep 2023 00:47:44 -0400 Subject: [PATCH] Port Nitro to new printing --- BinaryObjectScanner.Printing/Extensions.cs | 207 +++++++------ BinaryObjectScanner.Printing/N3DS.cs | 76 ++--- BinaryObjectScanner.Printing/NCF.cs | 2 +- BinaryObjectScanner.Printing/NewExecutable.cs | 8 + BinaryObjectScanner.Printing/Nitro.cs | 282 ++++++++++++++++++ BinaryObjectScanner.Wrappers/Nitro.cs | 263 +--------------- 6 files changed, 443 insertions(+), 395 deletions(-) create mode 100644 BinaryObjectScanner.Printing/Nitro.cs diff --git a/BinaryObjectScanner.Printing/Extensions.cs b/BinaryObjectScanner.Printing/Extensions.cs index a10a28a8..aa5056bb 100644 --- a/BinaryObjectScanner.Printing/Extensions.cs +++ b/BinaryObjectScanner.Printing/Extensions.cs @@ -3,110 +3,23 @@ using System.Text; namespace BinaryObjectScanner.Printing { + // TODO: Add extension for printing enums, if possible internal static class Extensions { /// - /// Append a line containing a UInt8[] value to a StringBuilder + /// Append a line containing a boolean to a StringBuilder /// #if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, byte[] value, string prefixString) + public static StringBuilder AppendLine(this StringBuilder sb, bool value, string prefixString) #else - public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString) + public static StringBuilder AppendLine(this StringBuilder sb, bool? value, string prefixString) #endif { - string valueString = (value == null ? "[NULL]" : BitConverter.ToString(value).Replace('-', ' ')); - return sb.AppendLine($"{prefixString}: {valueString}"); - } +#if NET6_0_OR_GREATER + value ??= false; +#endif - /// - /// Append a line containing a UInt8[] value as a string to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, byte[] value, string prefixString, Encoding encoding) -#else - public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString, Encoding encoding) -#endif - { - string valueString = (value == null ? "[NULL]" : encoding.GetString(value).Replace("\0", string.Empty)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a Int16[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, short[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, short[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a UInt16[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, ushort[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, ushort[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a Int32[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, int[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, int[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a UInt32[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, uint[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, uint[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a Int64[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, long[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, long[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); - } - - /// - /// Append a line containing a UInt64[] value to a StringBuilder - /// -#if NET48 - public static StringBuilder AppendLine(this StringBuilder sb, ulong[] value, string prefixString) -#else - public static StringBuilder AppendLine(this StringBuilder sb, ulong[]? value, string prefixString) -#endif - { - string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); - return sb.AppendLine($"{prefixString}: {valueString}"); + return sb.AppendLine($"{prefixString}: {value.ToString()}"); } /// @@ -280,5 +193,109 @@ namespace BinaryObjectScanner.Printing return sb.AppendLine($"{prefixString}: {value}"); } + + /// + /// Append a line containing a UInt8[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, byte[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : BitConverter.ToString(value).Replace('-', ' ')); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a UInt8[] value as a string to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, byte[] value, string prefixString, Encoding encoding) +#else + public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString, Encoding encoding) +#endif + { + string valueString = (value == null ? "[NULL]" : encoding.GetString(value).Replace("\0", string.Empty)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a Int16[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, short[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, short[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a UInt16[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, ushort[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, ushort[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a Int32[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, int[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, int[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a UInt32[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, uint[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, uint[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a Int64[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, long[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, long[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } + + /// + /// Append a line containing a UInt64[] value to a StringBuilder + /// +#if NET48 + public static StringBuilder AppendLine(this StringBuilder sb, ulong[] value, string prefixString) +#else + public static StringBuilder AppendLine(this StringBuilder sb, ulong[]? value, string prefixString) +#endif + { + string valueString = (value == null ? "[NULL]" : string.Join(", ", value)); + return sb.AppendLine($"{prefixString}: {valueString}"); + } } } \ No newline at end of file diff --git a/BinaryObjectScanner.Printing/N3DS.cs b/BinaryObjectScanner.Printing/N3DS.cs index 250e263e..56d05214 100644 --- a/BinaryObjectScanner.Printing/N3DS.cs +++ b/BinaryObjectScanner.Printing/N3DS.cs @@ -165,45 +165,45 @@ namespace BinaryObjectScanner.Printing builder.AppendLine(header.InitialData.CardSeedAESMAC, " Card seed AES-MAC"); builder.AppendLine(header.InitialData.CardSeedNonce, " Card seed nonce"); builder.AppendLine(header.InitialData.Reserved, " Reserved"); - } - builder.AppendLine(); + builder.AppendLine(); - builder.AppendLine(" Backup Header:"); - builder.AppendLine(" -------------------------"); - if (header.InitialData.BackupHeader == null) - { - builder.AppendLine(" No backup header"); - } - else - { - builder.AppendLine(header.InitialData.BackupHeader.MagicID, " Magic ID"); - builder.AppendLine(header.InitialData.BackupHeader.ContentSizeInMediaUnits, " Content size in media units"); - builder.AppendLine(header.InitialData.BackupHeader.PartitionId, " Partition ID"); - builder.AppendLine(header.InitialData.BackupHeader.MakerCode, " Maker code"); - builder.AppendLine(header.InitialData.BackupHeader.Version, " Version"); - builder.AppendLine(header.InitialData.BackupHeader.VerificationHash, " Verification hash"); - builder.AppendLine(header.InitialData.BackupHeader.ProgramId, " Program ID"); - builder.AppendLine(header.InitialData.BackupHeader.Reserved1, " Reserved 1"); - builder.AppendLine(header.InitialData.BackupHeader.LogoRegionHash, " Logo region SHA-256 hash"); - builder.AppendLine(header.InitialData.BackupHeader.ProductCode, " Product code"); - builder.AppendLine(header.InitialData.BackupHeader.ExtendedHeaderHash, " Extended header SHA-256 hash"); - builder.AppendLine(header.InitialData.BackupHeader.ExtendedHeaderSizeInBytes, " Extended header size in bytes"); - builder.AppendLine(header.InitialData.BackupHeader.Reserved2, " Reserved 2"); - builder.AppendLine($" Flags: {header.InitialData.BackupHeader.Flags} (0x{header.InitialData.BackupHeader.Flags:X})"); - builder.AppendLine(header.InitialData.BackupHeader.PlainRegionOffsetInMediaUnits, " Plain region offset, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.PlainRegionSizeInMediaUnits, " Plain region size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.LogoRegionOffsetInMediaUnits, " Logo region offset, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.LogoRegionSizeInMediaUnits, " Logo region size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.ExeFSOffsetInMediaUnits, " ExeFS offset, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.ExeFSSizeInMediaUnits, " ExeFS size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.ExeFSHashRegionSizeInMediaUnits, " ExeFS hash region size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.Reserved3, " Reserved 3"); - builder.AppendLine(header.InitialData.BackupHeader.RomFSOffsetInMediaUnits, " RomFS offset, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.RomFSSizeInMediaUnits, " RomFS size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.RomFSHashRegionSizeInMediaUnits, " RomFS hash region size, in media units"); - builder.AppendLine(header.InitialData.BackupHeader.Reserved4, " Reserved 4"); - builder.AppendLine(header.InitialData.BackupHeader.ExeFSSuperblockHash, " ExeFS superblock SHA-256 hash"); - builder.AppendLine(header.InitialData.BackupHeader.RomFSSuperblockHash, " RomFS superblock SHA-256 hash"); + builder.AppendLine(" Backup Header:"); + builder.AppendLine(" -------------------------"); + if (header.InitialData.BackupHeader == null) + { + builder.AppendLine(" No backup header"); + } + else + { + builder.AppendLine(header.InitialData.BackupHeader.MagicID, " Magic ID"); + builder.AppendLine(header.InitialData.BackupHeader.ContentSizeInMediaUnits, " Content size in media units"); + builder.AppendLine(header.InitialData.BackupHeader.PartitionId, " Partition ID"); + builder.AppendLine(header.InitialData.BackupHeader.MakerCode, " Maker code"); + builder.AppendLine(header.InitialData.BackupHeader.Version, " Version"); + builder.AppendLine(header.InitialData.BackupHeader.VerificationHash, " Verification hash"); + builder.AppendLine(header.InitialData.BackupHeader.ProgramId, " Program ID"); + builder.AppendLine(header.InitialData.BackupHeader.Reserved1, " Reserved 1"); + builder.AppendLine(header.InitialData.BackupHeader.LogoRegionHash, " Logo region SHA-256 hash"); + builder.AppendLine(header.InitialData.BackupHeader.ProductCode, " Product code"); + builder.AppendLine(header.InitialData.BackupHeader.ExtendedHeaderHash, " Extended header SHA-256 hash"); + builder.AppendLine(header.InitialData.BackupHeader.ExtendedHeaderSizeInBytes, " Extended header size in bytes"); + builder.AppendLine(header.InitialData.BackupHeader.Reserved2, " Reserved 2"); + builder.AppendLine($" Flags: {header.InitialData.BackupHeader.Flags} (0x{header.InitialData.BackupHeader.Flags:X})"); + builder.AppendLine(header.InitialData.BackupHeader.PlainRegionOffsetInMediaUnits, " Plain region offset, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.PlainRegionSizeInMediaUnits, " Plain region size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.LogoRegionOffsetInMediaUnits, " Logo region offset, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.LogoRegionSizeInMediaUnits, " Logo region size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.ExeFSOffsetInMediaUnits, " ExeFS offset, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.ExeFSSizeInMediaUnits, " ExeFS size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.ExeFSHashRegionSizeInMediaUnits, " ExeFS hash region size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.Reserved3, " Reserved 3"); + builder.AppendLine(header.InitialData.BackupHeader.RomFSOffsetInMediaUnits, " RomFS offset, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.RomFSSizeInMediaUnits, " RomFS size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.RomFSHashRegionSizeInMediaUnits, " RomFS hash region size, in media units"); + builder.AppendLine(header.InitialData.BackupHeader.Reserved4, " Reserved 4"); + builder.AppendLine(header.InitialData.BackupHeader.ExeFSSuperblockHash, " ExeFS superblock SHA-256 hash"); + builder.AppendLine(header.InitialData.BackupHeader.RomFSSuperblockHash, " RomFS superblock SHA-256 hash"); + } } builder.AppendLine(); diff --git a/BinaryObjectScanner.Printing/NCF.cs b/BinaryObjectScanner.Printing/NCF.cs index 98cb34aa..eae97efd 100644 --- a/BinaryObjectScanner.Printing/NCF.cs +++ b/BinaryObjectScanner.Printing/NCF.cs @@ -345,7 +345,7 @@ namespace BinaryObjectScanner.Printing #if NET48 private static void Print(StringBuilder builder, ChecksumMapEntry[] entries) #else - private static void Print(StringBuilder builder, ChecksumMapEntry[]? entries) + private static void Print(StringBuilder builder, ChecksumMapEntry?[]? entries) #endif { builder.AppendLine(" Checksum Map Entries Information:"); diff --git a/BinaryObjectScanner.Printing/NewExecutable.cs b/BinaryObjectScanner.Printing/NewExecutable.cs index f8979a1e..cd1373d8 100644 --- a/BinaryObjectScanner.Printing/NewExecutable.cs +++ b/BinaryObjectScanner.Printing/NewExecutable.cs @@ -41,6 +41,7 @@ namespace BinaryObjectScanner.Printing { builder.AppendLine(" No MS-DOS stub header"); builder.AppendLine(); + return; } builder.AppendLine(header.Magic, " Magic number"); @@ -77,6 +78,13 @@ namespace BinaryObjectScanner.Printing { builder.AppendLine(" Header Information:"); builder.AppendLine(" -------------------------"); + if (header == null) + { + builder.AppendLine(" No header"); + builder.AppendLine(); + return; + } + builder.AppendLine(header.Magic, " Magic number"); builder.AppendLine(header.LinkerVersion, " Linker version"); builder.AppendLine(header.LinkerRevision, " Linker revision"); diff --git a/BinaryObjectScanner.Printing/Nitro.cs b/BinaryObjectScanner.Printing/Nitro.cs new file mode 100644 index 00000000..ced0afb4 --- /dev/null +++ b/BinaryObjectScanner.Printing/Nitro.cs @@ -0,0 +1,282 @@ +using System.Text; +using SabreTools.Models.Nitro; + +namespace BinaryObjectScanner.Printing +{ + public static class Nitro + { + public static void Print(StringBuilder builder, Cart cart) + { + builder.AppendLine("NDS Cart Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + Print(builder, cart.CommonHeader); + Print(builder, cart.ExtendedDSiHeader); + Print(builder, cart.SecureArea); + Print(builder, cart.NameTable); + Print(builder, cart.FileAllocationTable); + } + +#if NET48 + private static void Print(StringBuilder builder, CommonHeader header) +#else + private static void Print(StringBuilder builder, CommonHeader? header) +#endif + { + builder.AppendLine(" Common Header Information:"); + builder.AppendLine(" -------------------------"); + if (header == null) + { + builder.AppendLine(" No common header"); + builder.AppendLine(); + return; + } + + builder.AppendLine(header.GameTitle, " Game title"); + builder.AppendLine(header.GameCode, " Game code"); + builder.AppendLine(header.MakerCode, " Maker code"); + builder.AppendLine($" Unit code: {header.UnitCode} (0x{header.UnitCode:X})"); + builder.AppendLine(header.EncryptionSeedSelect, " Encryption seed select"); + builder.AppendLine(header.DeviceCapacity, " Device capacity"); + builder.AppendLine(header.Reserved1, " Reserved 1"); + builder.AppendLine(header.GameRevision, " Game revision"); + builder.AppendLine(header.RomVersion, " Rom version"); + builder.AppendLine(header.ARM9RomOffset, " ARM9 rom offset"); + builder.AppendLine(header.ARM9EntryAddress, " ARM9 entry address"); + builder.AppendLine(header.ARM9LoadAddress, " ARM9 load address"); + builder.AppendLine(header.ARM9Size, " ARM9 size"); + builder.AppendLine(header.ARM7RomOffset, " ARM7 rom offset"); + builder.AppendLine(header.ARM7EntryAddress, " ARM7 entry address"); + builder.AppendLine(header.ARM7LoadAddress, " ARM7 load address"); + builder.AppendLine(header.ARM7Size, " ARM7 size"); + builder.AppendLine(header.FileNameTableOffset, " File name table offset"); + builder.AppendLine(header.FileNameTableLength, " File name table length"); + builder.AppendLine(header.FileAllocationTableOffset, " File allocation table offset"); + builder.AppendLine(header.FileAllocationTableLength, " File allocation table length"); + builder.AppendLine(header.ARM9OverlayOffset, " ARM9 overlay offset"); + builder.AppendLine(header.ARM9OverlayLength, " ARM9 overlay length"); + builder.AppendLine(header.ARM7OverlayOffset, " ARM7 overlay offset"); + builder.AppendLine(header.ARM7OverlayLength, " ARM7 overlay length"); + builder.AppendLine(header.NormalCardControlRegisterSettings, " Normal card control register settings"); + builder.AppendLine(header.SecureCardControlRegisterSettings, " Secure card control register settings"); + builder.AppendLine(header.IconBannerOffset, " Icon banner offset"); + builder.AppendLine(header.SecureAreaCRC, " Secure area CRC"); + builder.AppendLine(header.SecureTransferTimeout, " Secure transfer timeout"); + builder.AppendLine(header.ARM9Autoload, " ARM9 autoload"); + builder.AppendLine(header.ARM7Autoload, " ARM7 autoload"); + builder.AppendLine(header.SecureDisable, " Secure disable"); + builder.AppendLine(header.NTRRegionRomSize, " NTR region rom size"); + builder.AppendLine(header.HeaderSize, " Header size"); + builder.AppendLine(header.Reserved2, " Reserved 2"); + builder.AppendLine(header.NintendoLogo, " Nintendo logo"); + builder.AppendLine(header.NintendoLogoCRC, " Nintendo logo CRC"); + builder.AppendLine(header.HeaderCRC, " Header CRC"); + builder.AppendLine(header.DebuggerReserved, " Debugger reserved"); + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, ExtendedDSiHeader header) +#else + private static void Print(StringBuilder builder, ExtendedDSiHeader? header) +#endif + { + builder.AppendLine(" Extended DSi Header Information:"); + builder.AppendLine(" -------------------------"); + if (header == null) + { + builder.AppendLine(" No extended DSi header"); + builder.AppendLine(); + return; + } + + builder.AppendLine(header.GlobalMBK15Settings, " Global MBK1..MBK5 settings"); + builder.AppendLine(header.LocalMBK68SettingsARM9, " Local MBK6..MBK8 settings for ARM9"); + builder.AppendLine(header.LocalMBK68SettingsARM7, " Local MBK6..MBK8 settings for ARM7"); + builder.AppendLine(header.GlobalMBK9Setting, " Global MBK9 setting"); + builder.AppendLine(header.RegionFlags, " Region flags"); + builder.AppendLine(header.AccessControl, " Access control"); + builder.AppendLine(header.ARM7SCFGEXTMask, " ARM7 SCFG EXT mask"); + builder.AppendLine(header.ReservedFlags, " Reserved/flags?"); + builder.AppendLine(header.ARM9iRomOffset, " ARM9i rom offset"); + builder.AppendLine(header.Reserved3, " Reserved 3"); + builder.AppendLine(header.ARM9iLoadAddress, " ARM9i load address"); + builder.AppendLine(header.ARM9iSize, " ARM9i size"); + builder.AppendLine(header.ARM7iRomOffset, " ARM7i rom offset"); + builder.AppendLine(header.Reserved4, " Reserved 4"); + builder.AppendLine(header.ARM7iLoadAddress, " ARM7i load address"); + builder.AppendLine(header.ARM7iSize, " ARM7i size"); + builder.AppendLine(header.DigestNTRRegionOffset, " Digest NTR region offset"); + builder.AppendLine(header.DigestNTRRegionLength, " Digest NTR region length"); + builder.AppendLine(header.DigestTWLRegionOffset, " Digest TWL region offset"); + builder.AppendLine(header.DigestTWLRegionLength, " Digest TWL region length"); + builder.AppendLine(header.DigestSectorHashtableRegionOffset, " Digest sector hashtable region offset"); + builder.AppendLine(header.DigestSectorHashtableRegionLength, " Digest sector hashtable region length"); + builder.AppendLine(header.DigestBlockHashtableRegionOffset, " Digest block hashtable region offset"); + builder.AppendLine(header.DigestBlockHashtableRegionLength, " Digest block hashtable region length"); + builder.AppendLine(header.DigestSectorSize, " Digest sector size"); + builder.AppendLine(header.DigestBlockSectorCount, " Digest block sector count"); + builder.AppendLine(header.IconBannerSize, " Icon banner size"); + builder.AppendLine(header.Unknown1, " Unknown 1"); + builder.AppendLine(header.ModcryptArea1Offset, " Modcrypt area 1 offset"); + builder.AppendLine(header.ModcryptArea1Size, " Modcrypt area 1 size"); + builder.AppendLine(header.ModcryptArea2Offset, " Modcrypt area 2 offset"); + builder.AppendLine(header.ModcryptArea2Size, " Modcrypt area 2 size"); + builder.AppendLine(header.TitleID, " Title ID"); + builder.AppendLine(header.DSiWarePublicSavSize, " DSiWare 'public.sav' size"); + builder.AppendLine(header.DSiWarePrivateSavSize, " DSiWare 'private.sav' size"); + builder.AppendLine(header.ReservedZero, " Reserved (zero)"); + builder.AppendLine(header.Unknown2, " Unknown 2"); + builder.AppendLine(header.ARM9WithSecureAreaSHA1HMACHash, " ARM9 (with encrypted secure area) SHA1 HMAC hash"); + builder.AppendLine(header.ARM7SHA1HMACHash, " ARM7 SHA1 HMAC hash"); + builder.AppendLine(header.DigestMasterSHA1HMACHash, " Digest master SHA1 HMAC hash"); + builder.AppendLine(header.BannerSHA1HMACHash, " Banner SHA1 HMAC hash"); + builder.AppendLine(header.ARM9iDecryptedSHA1HMACHash, " ARM9i (decrypted) SHA1 HMAC hash"); + builder.AppendLine(header.ARM7iDecryptedSHA1HMACHash, " ARM7i (decrypted) SHA1 HMAC hash"); + builder.AppendLine(header.Reserved5, " Reserved 5"); + builder.AppendLine(header.ARM9NoSecureAreaSHA1HMACHash, " ARM9 (without secure area) SHA1 HMAC hash"); + builder.AppendLine(header.Reserved6, " Reserved 6"); + builder.AppendLine(header.ReservedAndUnchecked, " Reserved and unchecked region"); + builder.AppendLine(header.RSASignature, " RSA signature"); + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, byte[] secureArea) +#else + private static void Print(StringBuilder builder, byte[]? secureArea) +#endif + { + builder.AppendLine(" Secure Area Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine(secureArea, " Secure Area"); + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, NameTable table) +#else + private static void Print(StringBuilder builder, NameTable? table) +#endif + { + builder.AppendLine(" Name Table Information:"); + builder.AppendLine(" -------------------------"); + if (table == null) + { + builder.AppendLine(" No name table"); + builder.AppendLine(); + return; + } + builder.AppendLine(); + + Print(builder, table.FolderAllocationTable); + Print(builder, table.NameList); + } + +#if NET48 + private static void Print(StringBuilder builder, FolderAllocationTableEntry[] entries) +#else + private static void Print(StringBuilder builder, FolderAllocationTableEntry?[]? entries) +#endif + { + builder.AppendLine(" Folder Allocation Table:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No folder allocation table entries"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Folder Allocation Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.StartOffset, " Start offset"); + builder.AppendLine(entry.FirstFileIndex, " First file index"); + if (entry.Unknown == 0xF0) + { + builder.AppendLine(entry.ParentFolderIndex, " Parent folder index"); + builder.AppendLine(entry.Unknown, " Unknown"); + } + else + { + ushort totalEntries = (ushort)((entry.Unknown << 8) | entry.ParentFolderIndex); + builder.AppendLine(totalEntries, " Total entries"); + } + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, NameListEntry[] entries) +#else + private static void Print(StringBuilder builder, NameListEntry?[]? entries) +#endif + { + builder.AppendLine(" Name List:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No name list entries"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Name List Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.Folder, " Folder"); + builder.AppendLine(entry.Name, " Name"); + if (entry.Folder) + builder.AppendLine(entry.Index, " Index"); + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, FileAllocationTableEntry[] entries) +#else + private static void Print(StringBuilder builder, FileAllocationTableEntry?[]? entries) +#endif + { + builder.AppendLine(" File Allocation Table:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No file allocation table entries"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" File Allocation Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.StartOffset, " Start offset"); + builder.AppendLine(entry.EndOffset, " End offset"); + } + builder.AppendLine(); + } + } +} \ No newline at end of file diff --git a/BinaryObjectScanner.Wrappers/Nitro.cs b/BinaryObjectScanner.Wrappers/Nitro.cs index 308b9453..0aaa0141 100644 --- a/BinaryObjectScanner.Wrappers/Nitro.cs +++ b/BinaryObjectScanner.Wrappers/Nitro.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using System.Text; namespace BinaryObjectScanner.Wrappers @@ -650,268 +649,10 @@ namespace BinaryObjectScanner.Wrappers public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); - - builder.AppendLine("NDS Cart Information:"); - builder.AppendLine("-------------------------"); - builder.AppendLine(); - - PrintCommonHeader(builder); - PrintExtendedDSiHeader(builder); - PrintSecureArea(builder); - PrintNameTable(builder); - PrintFileAllocationTable(builder); - + Printing.Nitro.Print(builder, _model); return builder; } - /// - /// Print common header information - /// - /// StringBuilder to append information to - private void PrintCommonHeader(StringBuilder builder) - { - builder.AppendLine(" Common Header Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine($" Game title: {GameTitle ?? "[NULL]"}"); - builder.AppendLine($" Game code: {GameCode} (0x{GameCode:X})"); - builder.AppendLine($" Maker code: {MakerCode ?? "[NULL]"}"); - builder.AppendLine($" Unit code: {UnitCode} (0x{UnitCode:X})"); - builder.AppendLine($" Encryption seed select: {EncryptionSeedSelect} (0x{EncryptionSeedSelect:X})"); - builder.AppendLine($" Device capacity: {DeviceCapacity} (0x{DeviceCapacity:X})"); - builder.AppendLine($" Reserved 1: {(Reserved1 == null ? "[NULL]" : BitConverter.ToString(Reserved1).Replace('-', ' '))}"); - builder.AppendLine($" Game revision: {GameRevision} (0x{GameRevision:X})"); - builder.AppendLine($" Rom version: {RomVersion} (0x{RomVersion:X})"); - builder.AppendLine($" ARM9 rom offset: {ARM9RomOffset} (0x{ARM9RomOffset:X})"); - builder.AppendLine($" ARM9 entry address: {ARM9EntryAddress} (0x{ARM9EntryAddress:X})"); - builder.AppendLine($" ARM9 load address: {ARM9LoadAddress} (0x{ARM9LoadAddress:X})"); - builder.AppendLine($" ARM9 size: {ARM9Size} (0x{ARM9Size:X})"); - builder.AppendLine($" ARM7 rom offset: {ARM7RomOffset} (0x{ARM7RomOffset:X})"); - builder.AppendLine($" ARM7 entry address: {ARM7EntryAddress} (0x{ARM7EntryAddress:X})"); - builder.AppendLine($" ARM7 load address: {ARM7LoadAddress} (0x{ARM7LoadAddress:X})"); - builder.AppendLine($" ARM7 size: {ARM7Size} (0x{ARM7Size:X})"); - builder.AppendLine($" File name table offset: {FileNameTableOffset} (0x{FileNameTableOffset:X})"); - builder.AppendLine($" File name table length: {FileNameTableLength} (0x{FileNameTableLength:X})"); - builder.AppendLine($" File allocation table offset: {FileAllocationTableOffset} (0x{FileAllocationTableOffset:X})"); - builder.AppendLine($" File allocation table length: {FileAllocationTableLength} (0x{FileAllocationTableLength:X})"); - builder.AppendLine($" ARM9 overlay offset: {ARM9OverlayOffset} (0x{ARM9OverlayOffset:X})"); - builder.AppendLine($" ARM9 overlay length: {ARM9OverlayLength} (0x{ARM9OverlayLength:X})"); - builder.AppendLine($" ARM7 overlay offset: {ARM7OverlayOffset} (0x{ARM7OverlayOffset:X})"); - builder.AppendLine($" ARM7 overlay length: {ARM7OverlayLength} (0x{ARM7OverlayLength:X})"); - builder.AppendLine($" Normal card control register settings: {NormalCardControlRegisterSettings} (0x{NormalCardControlRegisterSettings:X})"); - builder.AppendLine($" Secure card control register settings: {SecureCardControlRegisterSettings} (0x{SecureCardControlRegisterSettings:X})"); - builder.AppendLine($" Icon banner offset: {IconBannerOffset} (0x{IconBannerOffset:X})"); - builder.AppendLine($" Secure area CRC: {SecureAreaCRC} (0x{SecureAreaCRC:X})"); - builder.AppendLine($" Secure transfer timeout: {SecureTransferTimeout} (0x{SecureTransferTimeout:X})"); - builder.AppendLine($" ARM9 autoload: {ARM9Autoload} (0x{ARM9Autoload:X})"); - builder.AppendLine($" ARM7 autoload: {ARM7Autoload} (0x{ARM7Autoload:X})"); - builder.AppendLine($" Secure disable: {SecureDisable} (0x{SecureDisable:X})"); - builder.AppendLine($" NTR region rom size: {NTRRegionRomSize} (0x{NTRRegionRomSize:X})"); - builder.AppendLine($" Header size: {HeaderSize} (0x{HeaderSize:X})"); - builder.AppendLine($" Reserved 2: {(Reserved2 == null ? "[NULL]" : BitConverter.ToString(Reserved2).Replace('-', ' '))}"); - builder.AppendLine($" Nintendo logo: {(NintendoLogo == null ? "[NULL]" : BitConverter.ToString(NintendoLogo).Replace('-', ' '))}"); - builder.AppendLine($" Nintendo logo CRC: {NintendoLogoCRC} (0x{NintendoLogoCRC:X})"); - builder.AppendLine($" Header CRC: {HeaderCRC} (0x{HeaderCRC:X})"); - builder.AppendLine($" Debugger reserved: {(DebuggerReserved == null ? "[NULL]" : BitConverter.ToString(DebuggerReserved).Replace('-', ' '))}"); - builder.AppendLine(); - } - - /// - /// Print extended DSi header information - /// - /// StringBuilder to append information to - private void PrintExtendedDSiHeader(StringBuilder builder) - { - builder.AppendLine(" Extended DSi Header Information:"); - builder.AppendLine(" -------------------------"); - if (_model.ExtendedDSiHeader == null) - { - builder.AppendLine(" No extended DSi header"); - } - else - { - builder.AppendLine($" Global MBK1..MBK5 settings: {(GlobalMBK15Settings == null ? "[NULL]" : string.Join(", ", GlobalMBK15Settings))}"); - builder.AppendLine($" Local MBK6..MBK8 settings for ARM9: {(LocalMBK68SettingsARM9 == null ? "[NULL]" : string.Join(", ", LocalMBK68SettingsARM9))}"); - builder.AppendLine($" Local MBK6..MBK8 settings for ARM7: {(LocalMBK68SettingsARM7 == null ? "[NULL]" : string.Join(", ", LocalMBK68SettingsARM7))}"); - builder.AppendLine($" Global MBK9 setting: {GlobalMBK9Setting} (0x{GlobalMBK9Setting:X})"); - builder.AppendLine($" Region flags: {RegionFlags} (0x{RegionFlags:X})"); - builder.AppendLine($" Access control: {AccessControl} (0x{AccessControl:X})"); - builder.AppendLine($" ARM7 SCFG EXT mask: {ARM7SCFGEXTMask} (0x{ARM7SCFGEXTMask:X})"); - builder.AppendLine($" Reserved/flags?: {ReservedFlags} (0x{ReservedFlags:X})"); - builder.AppendLine($" ARM9i rom offset: {ARM9iRomOffset} (0x{ARM9iRomOffset:X})"); - builder.AppendLine($" Reserved 3: {Reserved3} (0x{Reserved3:X})"); - builder.AppendLine($" ARM9i load address: {ARM9iLoadAddress} (0x{ARM9iLoadAddress:X})"); - builder.AppendLine($" ARM9i size: {ARM9iSize} (0x{ARM9iSize:X})"); - builder.AppendLine($" ARM7i rom offset: {ARM7iRomOffset} (0x{ARM7iRomOffset:X})"); - builder.AppendLine($" Reserved 4: {Reserved4} (0x{Reserved4:X})"); - builder.AppendLine($" ARM7i load address: {ARM7iLoadAddress} (0x{ARM7iLoadAddress:X})"); - builder.AppendLine($" ARM7i size: {ARM7iSize} (0x{ARM7iSize:X})"); - builder.AppendLine($" Digest NTR region offset: {DigestNTRRegionOffset} (0x{DigestNTRRegionOffset:X})"); - builder.AppendLine($" Digest NTR region length: {DigestNTRRegionLength} (0x{DigestNTRRegionLength:X})"); - builder.AppendLine($" Digest TWL region offset: {DigestTWLRegionOffset} (0x{DigestTWLRegionOffset:X})"); - builder.AppendLine($" Digest TWL region length: {DigestTWLRegionLength} (0x{DigestTWLRegionLength:X})"); - builder.AppendLine($" Digest sector hashtable region offset: {DigestSectorHashtableRegionOffset} (0x{DigestSectorHashtableRegionOffset:X})"); - builder.AppendLine($" Digest sector hashtable region length: {DigestSectorHashtableRegionLength} (0x{DigestSectorHashtableRegionLength:X})"); - builder.AppendLine($" Digest block hashtable region offset: {DigestBlockHashtableRegionOffset} (0x{DigestBlockHashtableRegionOffset:X})"); - builder.AppendLine($" Digest block hashtable region length: {DigestBlockHashtableRegionLength} (0x{DigestBlockHashtableRegionLength:X})"); - builder.AppendLine($" Digest sector size: {DigestSectorSize} (0x{DigestSectorSize:X})"); - builder.AppendLine($" Digest block sector count: {DigestBlockSectorCount} (0x{DigestBlockSectorCount:X})"); - builder.AppendLine($" Icon banner size: {IconBannerSize} (0x{IconBannerSize:X})"); - builder.AppendLine($" Unknown 1: {Unknown1} (0x{Unknown1:X})"); - builder.AppendLine($" Modcrypt area 1 offset: {ModcryptArea1Offset} (0x{ModcryptArea1Offset:X})"); - builder.AppendLine($" Modcrypt area 1 size: {ModcryptArea1Size} (0x{ModcryptArea1Size:X})"); - builder.AppendLine($" Modcrypt area 2 offset: {ModcryptArea2Offset} (0x{ModcryptArea2Offset:X})"); - builder.AppendLine($" Modcrypt area 2 size: {ModcryptArea2Size} (0x{ModcryptArea2Size:X})"); - builder.AppendLine($" Title ID: {(TitleID == null ? "[NULL]" : BitConverter.ToString(TitleID).Replace('-', ' '))}"); - builder.AppendLine($" DSiWare 'public.sav' size: {DSiWarePublicSavSize} (0x{DSiWarePublicSavSize:X})"); - builder.AppendLine($" DSiWare 'private.sav' size: {DSiWarePrivateSavSize} (0x{DSiWarePrivateSavSize:X})"); - builder.AppendLine($" Reserved (zero): {(ReservedZero == null ? "[NULL]" : BitConverter.ToString(ReservedZero).Replace('-', ' '))}"); - builder.AppendLine($" Unknown 2: {(Unknown2 == null ? "[NULL]" : BitConverter.ToString(Unknown2).Replace('-', ' '))}"); - builder.AppendLine($" ARM9 (with encrypted secure area) SHA1 HMAC hash: {(ARM9WithSecureAreaSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(ARM9WithSecureAreaSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" ARM7 SHA1 HMAC hash: {(ARM7SHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(ARM7SHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" Digest master SHA1 HMAC hash: {(DigestMasterSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(DigestMasterSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" Banner SHA1 HMAC hash: {(BannerSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(BannerSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" ARM9i (decrypted) SHA1 HMAC hash: {(ARM9iDecryptedSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(ARM9iDecryptedSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" ARM7i (decrypted) SHA1 HMAC hash: {(ARM7iDecryptedSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(ARM7iDecryptedSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" Reserved 5: {(Reserved5 == null ? "[NULL]" : BitConverter.ToString(Reserved5).Replace('-', ' '))}"); - builder.AppendLine($" ARM9 (without secure area) SHA1 HMAC hash: {(ARM9NoSecureAreaSHA1HMACHash == null ? "[NULL]" : BitConverter.ToString(ARM9NoSecureAreaSHA1HMACHash).Replace('-', ' '))}"); - builder.AppendLine($" Reserved 6: {(Reserved6 == null ? "[NULL]" : BitConverter.ToString(Reserved6).Replace('-', ' '))}"); - builder.AppendLine($" Reserved and unchecked region: {(ReservedAndUnchecked == null ? "[NULL]" : BitConverter.ToString(ReservedAndUnchecked).Replace('-', ' '))}"); - builder.AppendLine($" RSA signature: {(RSASignature == null ? "[NULL]" : BitConverter.ToString(RSASignature).Replace('-', ' '))}"); - } - builder.AppendLine(); - } - - /// - /// Print secure area information - /// - /// StringBuilder to append information to - private void PrintSecureArea(StringBuilder builder) - { - builder.AppendLine(" Secure Area Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine($" {(SecureArea == null ? "[NULL]" : BitConverter.ToString(SecureArea).Replace('-', ' '))}"); - builder.AppendLine(); - } - - /// - /// Print name table information - /// - /// StringBuilder to append information to - private void PrintNameTable(StringBuilder builder) - { - builder.AppendLine(" Name Table Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine(); - - PrintFolderAllocationTable(builder); - PrintNameList(builder); - } - - /// - /// Print folder allocation table information - /// - /// StringBuilder to append information to - private void PrintFolderAllocationTable(StringBuilder builder) - { - builder.AppendLine($" Folder Allocation Table:"); - builder.AppendLine(" -------------------------"); - if (FolderAllocationTable == null || FolderAllocationTable.Length == 0) - { - builder.AppendLine(" No folder allocation table entries"); - } - else - { - for (int i = 0; i < FolderAllocationTable.Length; i++) - { - var entry = FolderAllocationTable[i]; - builder.AppendLine($" Folder Allocation Table Entry {i}"); - if (entry == null) - { - builder.AppendLine(" [NULL]"); - continue; - } - - builder.AppendLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); - builder.AppendLine($" First file index: {entry.FirstFileIndex} (0x{entry.FirstFileIndex:X})"); - if (entry.Unknown == 0xF0) - { - builder.AppendLine($" Parent folder index: {entry.ParentFolderIndex} (0x{entry.ParentFolderIndex:X})"); - builder.AppendLine($" Unknown: {entry.Unknown} (0x{entry.Unknown:X})"); - } - else - { - ushort totalEntries = (ushort)((entry.Unknown << 8) | entry.ParentFolderIndex); - builder.AppendLine($" Total entries: {totalEntries} (0x{totalEntries:X})"); - } - } - } - builder.AppendLine(); - } - - /// - /// Print folder allocation table information - /// - /// StringBuilder to append information to - private void PrintNameList(StringBuilder builder) - { - builder.AppendLine($" Name List:"); - builder.AppendLine(" -------------------------"); - if (NameList == null || NameList.Length == 0) - { - builder.AppendLine(" No name list entries"); - } - else - { - for (int i = 0; i < NameList.Length; i++) - { - var entry = NameList[i]; - builder.AppendLine($" Name List Entry {i}"); - if (entry == null) - { - builder.AppendLine(" [NULL]"); - continue; - } - - builder.AppendLine($" Folder: {entry.Folder} (0x{entry.Folder:X})"); - builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); - if (entry.Folder) - builder.AppendLine($" Index: {entry.Index} (0x{entry.Index:X})"); - } - } - builder.AppendLine(); - } - - /// - /// Print file allocation table information - /// - /// StringBuilder to append information to - private void PrintFileAllocationTable(StringBuilder builder) - { - builder.AppendLine($" File Allocation Table:"); - builder.AppendLine(" -------------------------"); - if (FileAllocationTable == null || FileAllocationTable.Length == 0) - { - builder.AppendLine(" No file allocation table entries"); - } - else - { - for (int i = 0; i < FileAllocationTable.Length; i++) - { - var entry = FileAllocationTable[i]; - builder.AppendLine($" File Allocation Table Entry {i}"); - if (entry == null) - { - builder.AppendLine(" [NULL]"); - continue; - } - - builder.AppendLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); - builder.AppendLine($" End offset: {entry.EndOffset} (0x{entry.EndOffset:X})"); - } - } - builder.AppendLine(); - } - #if NET6_0_OR_GREATER ///