From 3a694f0e312ccd251feca7c8f5ea2494562d8adb Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 13 Jan 2023 14:04:21 -0800 Subject: [PATCH] Pretty print uses StringBuildernow --- BurnOutSharp.Wrappers/AACSMediaKeyBlock.cs | 120 +- BurnOutSharp.Wrappers/BDPlusSVM.cs | 40 +- BurnOutSharp.Wrappers/BFPK.cs | 58 +- BurnOutSharp.Wrappers/BSP.cs | 89 +- BurnOutSharp.Wrappers/CFB.cs | 148 +- BurnOutSharp.Wrappers/CIA.cs | 443 +++--- BurnOutSharp.Wrappers/GCF.cs | 445 +++--- BurnOutSharp.Wrappers/LinearExecutable.cs | 570 +++---- BurnOutSharp.Wrappers/MSDOS.cs | 72 +- BurnOutSharp.Wrappers/MicrosoftCabinet.cs | 146 +- BurnOutSharp.Wrappers/N3DS.cs | 588 ++++---- BurnOutSharp.Wrappers/NCF.cs | 287 ++-- BurnOutSharp.Wrappers/NewExecutable.cs | 324 ++-- BurnOutSharp.Wrappers/Nitro.cs | 304 ++-- BurnOutSharp.Wrappers/PAK.cs | 52 +- BurnOutSharp.Wrappers/PortableExecutable.cs | 1491 ++++++++++--------- BurnOutSharp.Wrappers/Quantum.cs | 74 +- BurnOutSharp.Wrappers/SGA.cs | 230 +-- BurnOutSharp.Wrappers/VBSP.cs | 54 +- BurnOutSharp.Wrappers/VPK.cs | 114 +- BurnOutSharp.Wrappers/WAD.cs | 89 +- BurnOutSharp.Wrappers/WrapperBase.cs | 4 +- BurnOutSharp.Wrappers/XZP.cs | 140 +- Test/Printer.cs | 6 +- 24 files changed, 3068 insertions(+), 2820 deletions(-) diff --git a/BurnOutSharp.Wrappers/AACSMediaKeyBlock.cs b/BurnOutSharp.Wrappers/AACSMediaKeyBlock.cs index 273e8bc5..700f2602 100644 --- a/BurnOutSharp.Wrappers/AACSMediaKeyBlock.cs +++ b/BurnOutSharp.Wrappers/AACSMediaKeyBlock.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -82,135 +83,140 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("AACS Media Key Block Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintRecords(); + builder.AppendLine("AACS Media Key Block Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintRecords(builder); + + return builder; } /// /// Print records information /// - private void PrintRecords() + /// StringBuilder to append information to + private void PrintRecords(StringBuilder builder) { - Console.WriteLine(" Records Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Records Information:"); + builder.AppendLine(" -------------------------"); if (Records == null || Records.Length == 0) { - Console.WriteLine(" No records"); + builder.AppendLine(" No records"); } else { for (int i = 0; i < Records.Length; i++) { var record = Records[i]; - Console.WriteLine($" Record Entry {i}"); - Console.WriteLine($" Record type: {record.RecordType} (0x{record.RecordType:X})"); - Console.WriteLine($" Record length: {record.RecordLength} (0x{record.RecordLength:X})"); + builder.AppendLine($" Record Entry {i}"); + builder.AppendLine($" Record type: {record.RecordType} (0x{record.RecordType:X})"); + builder.AppendLine($" Record length: {record.RecordLength} (0x{record.RecordLength:X})"); switch (record.RecordType) { case Models.AACS.RecordType.EndOfMediaKeyBlock: var eomkb = record as Models.AACS.EndOfMediaKeyBlockRecord; - Console.WriteLine($" Signature data: {BitConverter.ToString(eomkb.SignatureData ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine($" Signature data: {BitConverter.ToString(eomkb.SignatureData ?? new byte[0]).Replace('-', ' ')}"); break; case Models.AACS.RecordType.ExplicitSubsetDifference: var esd = record as Models.AACS.ExplicitSubsetDifferenceRecord; - Console.WriteLine($" Subset Differences:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Subset Differences:"); + builder.AppendLine(" -------------------------"); if (esd.SubsetDifferences == null || esd.SubsetDifferences.Length == 0) { - Console.WriteLine($" No subset differences"); + builder.AppendLine($" No subset differences"); } else { for (int j = 0; j < esd.SubsetDifferences.Length; j++) { var sd = esd.SubsetDifferences[j]; - Console.WriteLine($" Subset Difference {j}"); - Console.WriteLine($" Mask: {sd.Mask} (0x{sd.Mask:X})"); - Console.WriteLine($" Number: {sd.Number} (0x{sd.Number:X})"); + builder.AppendLine($" Subset Difference {j}"); + builder.AppendLine($" Mask: {sd.Mask} (0x{sd.Mask:X})"); + builder.AppendLine($" Number: {sd.Number} (0x{sd.Number:X})"); } } break; case Models.AACS.RecordType.MediaKeyData: var mkd = record as Models.AACS.MediaKeyDataRecord; - Console.WriteLine($" Media Keys:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Media Keys:"); + builder.AppendLine(" -------------------------"); if (mkd.MediaKeyData == null || mkd.MediaKeyData.Length == 0) { - Console.WriteLine($" No media keys"); + builder.AppendLine($" No media keys"); } else { for (int j = 0; j < mkd.MediaKeyData.Length; j++) { var mk = mkd.MediaKeyData[j]; - Console.WriteLine($" Media key {j}: {BitConverter.ToString(mk ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine($" Media key {j}: {BitConverter.ToString(mk ?? new byte[0]).Replace('-', ' ')}"); } } break; case Models.AACS.RecordType.SubsetDifferenceIndex: var sdi = record as Models.AACS.SubsetDifferenceIndexRecord; - Console.WriteLine($" Span: {sdi.Span} (0x{sdi.Span:X})"); - Console.WriteLine($" Offsets:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Span: {sdi.Span} (0x{sdi.Span:X})"); + builder.AppendLine($" Offsets:"); + builder.AppendLine(" -------------------------"); if (sdi.Offsets == null || sdi.Offsets.Length == 0) { - Console.WriteLine($" No offsets"); + builder.AppendLine($" No offsets"); } else { for (int j = 0; j < sdi.Offsets.Length; j++) { var offset = sdi.Offsets[j]; - Console.WriteLine($" Offset {j}: {offset} (0x{offset:X})"); + builder.AppendLine($" Offset {j}: {offset} (0x{offset:X})"); } } break; case Models.AACS.RecordType.TypeAndVersion: var tav = record as Models.AACS.TypeAndVersionRecord; - Console.WriteLine($" Media key block type: {tav.MediaKeyBlockType} (0x{tav.MediaKeyBlockType:X})"); - Console.WriteLine($" Version number: {tav.VersionNumber} (0x{tav.VersionNumber:X})"); + builder.AppendLine($" Media key block type: {tav.MediaKeyBlockType} (0x{tav.MediaKeyBlockType:X})"); + builder.AppendLine($" Version number: {tav.VersionNumber} (0x{tav.VersionNumber:X})"); break; case Models.AACS.RecordType.DriveRevocationList: var drl = record as Models.AACS.DriveRevocationListRecord; - Console.WriteLine($" Total number of entries: {drl.TotalNumberOfEntries} (0x{drl.TotalNumberOfEntries:X})"); - Console.WriteLine($" Signature Blocks:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Total number of entries: {drl.TotalNumberOfEntries} (0x{drl.TotalNumberOfEntries:X})"); + builder.AppendLine($" Signature Blocks:"); + builder.AppendLine(" -------------------------"); if (drl.SignatureBlocks == null || drl.SignatureBlocks.Length == 0) { - Console.WriteLine($" No signature blocks"); + builder.AppendLine($" No signature blocks"); } else { for (int j = 0; j < drl.SignatureBlocks.Length; j++) { var block = drl.SignatureBlocks[j]; - Console.WriteLine($" Signature Block {j}"); - Console.WriteLine($" Number of entries: {block.NumberOfEntries}"); - Console.WriteLine($" Entry Fields:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Signature Block {j}"); + builder.AppendLine($" Number of entries: {block.NumberOfEntries}"); + builder.AppendLine($" Entry Fields:"); + builder.AppendLine(" -------------------------"); if (block.EntryFields == null || block.EntryFields.Length == 0) { - Console.WriteLine($" No entry fields"); + builder.AppendLine($" No entry fields"); } else { for (int k = 0; k < block.EntryFields.Length; k++) { var ef = block.EntryFields[k]; - Console.WriteLine($" Entry {k}"); - Console.WriteLine($" Range: {ef.Range} (0x{ef.Range:X})"); - Console.WriteLine($" Drive ID: {BitConverter.ToString(ef.DriveID ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine($" Entry {k}"); + builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); + builder.AppendLine($" Drive ID: {BitConverter.ToString(ef.DriveID ?? new byte[0]).Replace('-', ' ')}"); } } } @@ -219,34 +225,34 @@ namespace BurnOutSharp.Wrappers case Models.AACS.RecordType.HostRevocationList: var hrl = record as Models.AACS.HostRevocationListRecord; - Console.WriteLine($" Total number of entries: {hrl.TotalNumberOfEntries} (0x{hrl.TotalNumberOfEntries:X})"); - Console.WriteLine($" Signature Blocks:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Total number of entries: {hrl.TotalNumberOfEntries} (0x{hrl.TotalNumberOfEntries:X})"); + builder.AppendLine($" Signature Blocks:"); + builder.AppendLine(" -------------------------"); if (hrl.SignatureBlocks == null || hrl.SignatureBlocks.Length == 0) { - Console.WriteLine($" No signature blocks"); + builder.AppendLine($" No signature blocks"); } else { for (int j = 0; j < hrl.SignatureBlocks.Length; j++) { var block = hrl.SignatureBlocks[j]; - Console.WriteLine($" Signature Block {j}"); - Console.WriteLine($" Number of entries: {block.NumberOfEntries}"); - Console.WriteLine($" Entry Fields:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Signature Block {j}"); + builder.AppendLine($" Number of entries: {block.NumberOfEntries}"); + builder.AppendLine($" Entry Fields:"); + builder.AppendLine(" -------------------------"); if (block.EntryFields == null || block.EntryFields.Length == 0) { - Console.WriteLine($" No entry fields"); + builder.AppendLine($" No entry fields"); } else { for (int k = 0; k < block.EntryFields.Length; k++) { var ef = block.EntryFields[k]; - Console.WriteLine($" Entry {k}"); - Console.WriteLine($" Range: {ef.Range} (0x{ef.Range:X})"); - Console.WriteLine($" Host ID: {BitConverter.ToString(ef.HostID ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine($" Entry {k}"); + builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); + builder.AppendLine($" Host ID: {BitConverter.ToString(ef.HostID ?? new byte[0]).Replace('-', ' ')}"); } } } @@ -255,17 +261,17 @@ namespace BurnOutSharp.Wrappers case Models.AACS.RecordType.VerifyMediaKey: var vmk = record as Models.AACS.VerifyMediaKeyRecord; - Console.WriteLine($" Ciphertext value: {BitConverter.ToString(vmk.CiphertextValue ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine($" Ciphertext value: {BitConverter.ToString(vmk.CiphertextValue ?? new byte[0]).Replace('-', ' ')}"); break; case Models.AACS.RecordType.Copyright: var c = record as Models.AACS.CopyrightRecord; - Console.WriteLine($" Copyright: {c.Copyright ?? "[NULL]"}"); + builder.AppendLine($" Copyright: {c.Copyright ?? "[NULL]"}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/BDPlusSVM.cs b/BurnOutSharp.Wrappers/BDPlusSVM.cs index c7538c99..6e04e206 100644 --- a/BurnOutSharp.Wrappers/BDPlusSVM.cs +++ b/BurnOutSharp.Wrappers/BDPlusSVM.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -99,31 +100,36 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("BD+ Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("BD+ Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); - PrintSVM(); + PrintSVM(builder); + + return builder; } /// /// Print SVM information /// - private void PrintSVM() + /// StringBuilder to append information to + private void PrintSVM(StringBuilder builder) { - Console.WriteLine(" SVM Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Unknown 1: {BitConverter.ToString(Unknown1).Replace('-', ' ')}"); - Console.WriteLine($" Year: {Year} (0x{Year:X})"); - Console.WriteLine($" Month: {Month} (0x{Month:X})"); - Console.WriteLine($" Day: {Day} (0x{Day:X})"); - Console.WriteLine($" Unknown 2: {BitConverter.ToString(Unknown2).Replace('-', ' ')}"); - Console.WriteLine($" Length: {Length} (0x{Length:X})"); - //Console.WriteLine($" Data: {BitConverter.ToString(Data ?? new byte[0]).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" SVM Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Unknown 1: {BitConverter.ToString(Unknown1).Replace('-', ' ')}"); + builder.AppendLine($" Year: {Year} (0x{Year:X})"); + builder.AppendLine($" Month: {Month} (0x{Month:X})"); + builder.AppendLine($" Day: {Day} (0x{Day:X})"); + builder.AppendLine($" Unknown 2: {BitConverter.ToString(Unknown2).Replace('-', ' ')}"); + builder.AppendLine($" Length: {Length} (0x{Length:X})"); + //builder.AppendLine($" Data: {BitConverter.ToString(Data ?? new byte[0]).Replace('-', ' ')}"); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/BFPK.cs b/BurnOutSharp.Wrappers/BFPK.cs index 42d200bd..410b5c5c 100644 --- a/BurnOutSharp.Wrappers/BFPK.cs +++ b/BurnOutSharp.Wrappers/BFPK.cs @@ -1,5 +1,5 @@ -using System; -using System.IO; +using System.IO; +using System.Text; using SharpCompress.Compressors; using SharpCompress.Compressors.Deflate; @@ -185,54 +185,60 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("BFPK Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintFileTable(); + builder.AppendLine("BFPK Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintFileTable(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic: {Magic}"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine($" Files: {Files} (0x{Files:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic: {Magic}"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine($" Files: {Files} (0x{Files:X})"); + builder.AppendLine(); } /// /// Print file table information /// - private void PrintFileTable() + /// StringBuilder to append information to + private void PrintFileTable(StringBuilder builder) { - Console.WriteLine(" File Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" File Table Information:"); + builder.AppendLine(" -------------------------"); if (Files == 0 || FileTable == null || FileTable.Length == 0) { - Console.WriteLine(" No file table items"); + builder.AppendLine(" No file table items"); } else { for (int i = 0; i < FileTable.Length; i++) { var entry = FileTable[i]; - Console.WriteLine($" File Table Entry {i}"); - Console.WriteLine($" Name size: {entry.NameSize} (0x{entry.NameSize:X})"); - Console.WriteLine($" Name: {entry.Name}"); - Console.WriteLine($" Uncompressed size: {entry.UncompressedSize} (0x{entry.UncompressedSize:X})"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); - Console.WriteLine($" Compressed Size: {entry.CompressedSize} (0x{entry.CompressedSize:X})"); + builder.AppendLine($" File Table Entry {i}"); + builder.AppendLine($" Name size: {entry.NameSize} (0x{entry.NameSize:X})"); + builder.AppendLine($" Name: {entry.Name}"); + builder.AppendLine($" Uncompressed size: {entry.UncompressedSize} (0x{entry.UncompressedSize:X})"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Compressed Size: {entry.CompressedSize} (0x{entry.CompressedSize:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/BSP.cs b/BurnOutSharp.Wrappers/BSP.cs index bd93a657..3d3e296d 100644 --- a/BurnOutSharp.Wrappers/BSP.cs +++ b/BurnOutSharp.Wrappers/BSP.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using static BurnOutSharp.Models.BSP.Constants; namespace BurnOutSharp.Wrappers @@ -108,39 +109,45 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("BSP Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("BSP Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); - PrintHeader(); - PrintLumps(); - PrintTextureHeader(); - PrintTextures(); + PrintHeader(builder); + PrintLumps(builder); + PrintTextureHeader(builder); + PrintTextures(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine(); } /// /// Print lumps information /// - private void PrintLumps() + /// StringBuilder to append information to + private void PrintLumps(StringBuilder builder) { - Console.WriteLine(" Lumps Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Lumps Information:"); + builder.AppendLine(" -------------------------"); if (Lumps == null || Lumps.Length == 0) { - Console.WriteLine(" No lumps"); + builder.AppendLine(" No lumps"); } else { @@ -158,61 +165,63 @@ namespace BurnOutSharp.Wrappers break; } - Console.WriteLine($" Lump {i}{specialLumpName}"); - Console.WriteLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); - Console.WriteLine($" Length: {lump.Length} (0x{lump.Length:X})"); + builder.AppendLine($" Lump {i}{specialLumpName}"); + builder.AppendLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); + builder.AppendLine($" Length: {lump.Length} (0x{lump.Length:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print texture header information /// - private void PrintTextureHeader() + /// StringBuilder to append information to + private void PrintTextureHeader(StringBuilder builder) { - Console.WriteLine(" Texture Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Texture count: {TextureCount}"); - Console.WriteLine($" Offsets:"); + builder.AppendLine(" Texture Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Texture count: {TextureCount}"); + builder.AppendLine($" Offsets:"); for (int i = 0; i < Offsets.Length; i++) { - Console.WriteLine($" Offset {i}: {Offsets[i]} (0x{Offsets[i]:X})"); + builder.AppendLine($" Offset {i}: {Offsets[i]} (0x{Offsets[i]:X})"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print textures information /// - private void PrintTextures() + /// StringBuilder to append information to + private void PrintTextures(StringBuilder builder) { - Console.WriteLine(" Textures Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Textures Information:"); + builder.AppendLine(" -------------------------"); if (Textures == null || Textures.Length == 0) { - Console.WriteLine(" No textures"); + builder.AppendLine(" No textures"); } else { for (int i = 0; i < Textures.Length; i++) { var texture = Textures[i]; - Console.WriteLine($" Texture {i}"); - Console.WriteLine($" Name: {texture.Name}"); - Console.WriteLine($" Width: {texture.Width} (0x{texture.Width:X})"); - Console.WriteLine($" Height: {texture.Height} (0x{texture.Height:X})"); - Console.WriteLine($" Offsets:"); + builder.AppendLine($" Texture {i}"); + builder.AppendLine($" Name: {texture.Name}"); + builder.AppendLine($" Width: {texture.Width} (0x{texture.Width:X})"); + builder.AppendLine($" Height: {texture.Height} (0x{texture.Height:X})"); + builder.AppendLine($" Offsets:"); for (int j = 0; j < texture.Offsets.Length; j++) { - Console.WriteLine($" Offset {j}: {Offsets[i]} (0x{texture.Offsets[j]:X})"); + builder.AppendLine($" Offset {j}: {Offsets[i]} (0x{texture.Offsets[j]:X})"); } // Skip texture data - Console.WriteLine($" Palette size: {texture.PaletteSize} (0x{texture.PaletteSize:X})"); + builder.AppendLine($" Palette size: {texture.PaletteSize} (0x{texture.PaletteSize:X})"); // Skip palette data } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/CFB.cs b/BurnOutSharp.Wrappers/CFB.cs index 3b389da3..d660ddf8 100644 --- a/BurnOutSharp.Wrappers/CFB.cs +++ b/BurnOutSharp.Wrappers/CFB.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -344,147 +345,156 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("Compound File Binary Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("Compound File Binary Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); - PrintFileHeader(); - PrintFATSectorNumbers(); - PrintMiniFATSectorNumbers(); - PrintDIFATSectorNumbers(); - PrintDirectoryEntries(); + PrintFileHeader(builder); + PrintFATSectorNumbers(builder); + PrintMiniFATSectorNumbers(builder); + PrintDIFATSectorNumbers(builder); + PrintDirectoryEntries(builder); + + return builder; } /// /// Print header information /// - private void PrintFileHeader() + /// StringBuilder to append information to + private void PrintFileHeader(StringBuilder builder) { - Console.WriteLine(" File Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature} (0x{Signature:X})"); - Console.WriteLine($" CLSID: {CLSID}"); - Console.WriteLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); - Console.WriteLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); - Console.WriteLine($" Byte order: {ByteOrder} (0x{ByteOrder:X})"); - Console.WriteLine($" Sector shift: {SectorShift} (0x{SectorShift:X}) => {SectorSize}"); - Console.WriteLine($" Mini sector shift: {MiniSectorShift} (0x{MiniSectorShift:X}) => {MiniSectorSize}"); - Console.WriteLine($" Reserved: {BitConverter.ToString(Reserved).Replace('-', ' ')}"); - Console.WriteLine($" Number of directory sectors: {NumberOfDirectorySectors} (0x{NumberOfDirectorySectors:X})"); - Console.WriteLine($" Number of FAT sectors: {NumberOfFATSectors} (0x{NumberOfFATSectors:X})"); - Console.WriteLine($" First directory sector location: {FirstDirectorySectorLocation} (0x{FirstDirectorySectorLocation:X})"); - Console.WriteLine($" Transaction signature number: {TransactionSignatureNumber} (0x{TransactionSignatureNumber:X})"); - Console.WriteLine($" Mini stream cutoff size: {MiniStreamCutoffSize} (0x{MiniStreamCutoffSize:X})"); - Console.WriteLine($" First mini FAT sector location: {FirstMiniFATSectorLocation} (0x{FirstMiniFATSectorLocation:X})"); - Console.WriteLine($" Number of mini FAT sectors: {NumberOfMiniFATSectors} (0x{NumberOfMiniFATSectors:X})"); - Console.WriteLine($" First DIFAT sector location: {FirstDIFATSectorLocation} (0x{FirstDIFATSectorLocation:X})"); - Console.WriteLine($" Number of DIFAT sectors: {NumberOfDIFATSectors} (0x{NumberOfDIFATSectors:X})"); - Console.WriteLine($" DIFAT:"); + builder.AppendLine(" File Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature} (0x{Signature:X})"); + builder.AppendLine($" CLSID: {CLSID}"); + builder.AppendLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); + builder.AppendLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); + builder.AppendLine($" Byte order: {ByteOrder} (0x{ByteOrder:X})"); + builder.AppendLine($" Sector shift: {SectorShift} (0x{SectorShift:X}) => {SectorSize}"); + builder.AppendLine($" Mini sector shift: {MiniSectorShift} (0x{MiniSectorShift:X}) => {MiniSectorSize}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(Reserved).Replace('-', ' ')}"); + builder.AppendLine($" Number of directory sectors: {NumberOfDirectorySectors} (0x{NumberOfDirectorySectors:X})"); + builder.AppendLine($" Number of FAT sectors: {NumberOfFATSectors} (0x{NumberOfFATSectors:X})"); + builder.AppendLine($" First directory sector location: {FirstDirectorySectorLocation} (0x{FirstDirectorySectorLocation:X})"); + builder.AppendLine($" Transaction signature number: {TransactionSignatureNumber} (0x{TransactionSignatureNumber:X})"); + builder.AppendLine($" Mini stream cutoff size: {MiniStreamCutoffSize} (0x{MiniStreamCutoffSize:X})"); + builder.AppendLine($" First mini FAT sector location: {FirstMiniFATSectorLocation} (0x{FirstMiniFATSectorLocation:X})"); + builder.AppendLine($" Number of mini FAT sectors: {NumberOfMiniFATSectors} (0x{NumberOfMiniFATSectors:X})"); + builder.AppendLine($" First DIFAT sector location: {FirstDIFATSectorLocation} (0x{FirstDIFATSectorLocation:X})"); + builder.AppendLine($" Number of DIFAT sectors: {NumberOfDIFATSectors} (0x{NumberOfDIFATSectors:X})"); + builder.AppendLine($" DIFAT:"); for (int i = 0; i < DIFAT.Length; i++) { - Console.WriteLine($" DIFAT Entry {i}: {DIFAT[i]} (0x{DIFAT[i]:X})"); + builder.AppendLine($" DIFAT Entry {i}: {DIFAT[i]} (0x{DIFAT[i]:X})"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print FAT sector numbers /// - private void PrintFATSectorNumbers() + /// StringBuilder to append information to + private void PrintFATSectorNumbers(StringBuilder builder) { - Console.WriteLine(" FAT Sectors Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" FAT Sectors Information:"); + builder.AppendLine(" -------------------------"); if (FATSectorNumbers == null || FATSectorNumbers.Length == 0) { - Console.WriteLine(" No FAT sectors"); + builder.AppendLine(" No FAT sectors"); } else { for (int i = 0; i < FATSectorNumbers.Length; i++) { - Console.WriteLine($" FAT Sector Entry {i}: {FATSectorNumbers[i]} (0x{FATSectorNumbers[i]:X})"); + builder.AppendLine($" FAT Sector Entry {i}: {FATSectorNumbers[i]} (0x{FATSectorNumbers[i]:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print mini FAT sector numbers /// - private void PrintMiniFATSectorNumbers() + /// StringBuilder to append information to + private void PrintMiniFATSectorNumbers(StringBuilder builder) { - Console.WriteLine(" Mini FAT Sectors Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Mini FAT Sectors Information:"); + builder.AppendLine(" -------------------------"); if (MiniFATSectorNumbers == null || MiniFATSectorNumbers.Length == 0) { - Console.WriteLine(" No mini FAT sectors"); + builder.AppendLine(" No mini FAT sectors"); } else { for (int i = 0; i < MiniFATSectorNumbers.Length; i++) { - Console.WriteLine($" Mini FAT Sector Entry {i}: {MiniFATSectorNumbers[i]} (0x{MiniFATSectorNumbers[i]:X})"); + builder.AppendLine($" Mini FAT Sector Entry {i}: {MiniFATSectorNumbers[i]} (0x{MiniFATSectorNumbers[i]:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print DIFAT sector numbers /// - private void PrintDIFATSectorNumbers() + /// StringBuilder to append information to + private void PrintDIFATSectorNumbers(StringBuilder builder) { - Console.WriteLine(" DIFAT Sectors Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" DIFAT Sectors Information:"); + builder.AppendLine(" -------------------------"); if (DIFATSectorNumbers == null || DIFATSectorNumbers.Length == 0) { - Console.WriteLine(" No DIFAT sectors"); + builder.AppendLine(" No DIFAT sectors"); } else { for (int i = 0; i < DIFATSectorNumbers.Length; i++) { - Console.WriteLine($" DIFAT Sector Entry {i}: {DIFATSectorNumbers[i]} (0x{DIFATSectorNumbers[i]:X})"); + builder.AppendLine($" DIFAT Sector Entry {i}: {DIFATSectorNumbers[i]} (0x{DIFATSectorNumbers[i]:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } // /// Print directory entries /// - private void PrintDirectoryEntries() + /// StringBuilder to append information to + private void PrintDirectoryEntries(StringBuilder builder) { - Console.WriteLine(" Directory Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryEntries == null || DirectoryEntries.Length == 0) { - Console.WriteLine(" No directory entries"); + builder.AppendLine(" No directory entries"); } else { for (int i = 0; i < DirectoryEntries.Length; i++) { var directoryEntry = DirectoryEntries[i]; - Console.WriteLine($" Directory Entry {i}"); - Console.WriteLine($" Name: {directoryEntry.Name}"); - Console.WriteLine($" Name length: {directoryEntry.NameLength} (0x{directoryEntry.NameLength:X})"); - Console.WriteLine($" Object type: {directoryEntry.ObjectType} (0x{directoryEntry.ObjectType:X})"); - Console.WriteLine($" Color flag: {directoryEntry.ColorFlag} (0x{directoryEntry.ColorFlag:X})"); - Console.WriteLine($" Left sibling ID: {directoryEntry.LeftSiblingID} (0x{directoryEntry.LeftSiblingID:X})"); - Console.WriteLine($" Right sibling ID: {directoryEntry.RightSiblingID} (0x{directoryEntry.RightSiblingID:X})"); - Console.WriteLine($" Child ID: {directoryEntry.ChildID} (0x{directoryEntry.ChildID:X})"); - Console.WriteLine($" CLSID: {directoryEntry.CLSID}"); - Console.WriteLine($" State bits: {directoryEntry.StateBits} (0x{directoryEntry.StateBits:X})"); - Console.WriteLine($" Creation time: {directoryEntry.CreationTime} (0x{directoryEntry.CreationTime:X})"); - Console.WriteLine($" Modification time: {directoryEntry.ModifiedTime} (0x{directoryEntry.ModifiedTime:X})"); - Console.WriteLine($" Staring sector location: {directoryEntry.StartingSectorLocation} (0x{directoryEntry.StartingSectorLocation:X})"); - Console.WriteLine($" Stream size: {directoryEntry.StreamSize} (0x{directoryEntry.StreamSize:X})"); + builder.AppendLine($" Directory Entry {i}"); + builder.AppendLine($" Name: {directoryEntry.Name}"); + builder.AppendLine($" Name length: {directoryEntry.NameLength} (0x{directoryEntry.NameLength:X})"); + builder.AppendLine($" Object type: {directoryEntry.ObjectType} (0x{directoryEntry.ObjectType:X})"); + builder.AppendLine($" Color flag: {directoryEntry.ColorFlag} (0x{directoryEntry.ColorFlag:X})"); + builder.AppendLine($" Left sibling ID: {directoryEntry.LeftSiblingID} (0x{directoryEntry.LeftSiblingID:X})"); + builder.AppendLine($" Right sibling ID: {directoryEntry.RightSiblingID} (0x{directoryEntry.RightSiblingID:X})"); + builder.AppendLine($" Child ID: {directoryEntry.ChildID} (0x{directoryEntry.ChildID:X})"); + builder.AppendLine($" CLSID: {directoryEntry.CLSID}"); + builder.AppendLine($" State bits: {directoryEntry.StateBits} (0x{directoryEntry.StateBits:X})"); + builder.AppendLine($" Creation time: {directoryEntry.CreationTime} (0x{directoryEntry.CreationTime:X})"); + builder.AppendLine($" Modification time: {directoryEntry.ModifiedTime} (0x{directoryEntry.ModifiedTime:X})"); + builder.AppendLine($" Staring sector location: {directoryEntry.StartingSectorLocation} (0x{directoryEntry.StartingSectorLocation:X})"); + builder.AppendLine($" Stream size: {directoryEntry.StreamSize} (0x{directoryEntry.StreamSize:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/CIA.cs b/BurnOutSharp.Wrappers/CIA.cs index 93a848f2..7da0b8e0 100644 --- a/BurnOutSharp.Wrappers/CIA.cs +++ b/BurnOutSharp.Wrappers/CIA.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -318,49 +319,55 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("CIA Archive Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintCertificateChain(); - PrintTicket(); - PrintTitleMetadata(); - PrintPartitions(); - PrintMetaData(); + builder.AppendLine("CIA Archive Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintCertificateChain(builder); + PrintTicket(builder); + PrintTitleMetadata(builder); + PrintPartitions(builder); + PrintMetaData(builder); + + return builder; } /// /// Print CIA header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" CIA Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Header size: {HeaderSize} (0x{HeaderSize:X})"); - Console.WriteLine($" Type: {Type} (0x{Type:X})"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine($" Certificate chain size: {CertificateChainSize} (0x{CertificateChainSize:X})"); - Console.WriteLine($" Ticket size: {TicketSize} (0x{TicketSize:X})"); - Console.WriteLine($" TMD file size: {TMDFileSize} (0x{TMDFileSize:X})"); - Console.WriteLine($" Meta size: {MetaSize} (0x{MetaSize:X})"); - Console.WriteLine($" Content size: {ContentSize} (0x{ContentSize:X})"); - Console.WriteLine($" Content index: {BitConverter.ToString(ContentIndex).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" CIA Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Header size: {HeaderSize} (0x{HeaderSize:X})"); + builder.AppendLine($" Type: {Type} (0x{Type:X})"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine($" Certificate chain size: {CertificateChainSize} (0x{CertificateChainSize:X})"); + builder.AppendLine($" Ticket size: {TicketSize} (0x{TicketSize:X})"); + builder.AppendLine($" TMD file size: {TMDFileSize} (0x{TMDFileSize:X})"); + builder.AppendLine($" Meta size: {MetaSize} (0x{MetaSize:X})"); + builder.AppendLine($" Content size: {ContentSize} (0x{ContentSize:X})"); + builder.AppendLine($" Content index: {BitConverter.ToString(ContentIndex).Replace('-', ' ')}"); + builder.AppendLine(); } /// /// Print NCCH partition header information /// - private void PrintCertificateChain() + /// StringBuilder to append information to + private void PrintCertificateChain(StringBuilder builder) { - Console.WriteLine(" Certificate Chain Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Certificate Chain Information:"); + builder.AppendLine(" -------------------------"); if (CertificateChain == null || CertificateChain.Length == 0) { - Console.WriteLine(" No certificates, expected 3"); + builder.AppendLine(" No certificates, expected 3"); } else { @@ -376,80 +383,81 @@ namespace BurnOutSharp.Wrappers case 2: certificateName = " (TMD)"; break; } - Console.WriteLine($" Certificate {i}{certificateName}"); - Console.WriteLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); - Console.WriteLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); - Console.WriteLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); - Console.WriteLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); - Console.WriteLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); - Console.WriteLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); - Console.WriteLine($" Name: {certificate.Name ?? "[NULL]"}"); - Console.WriteLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); + builder.AppendLine($" Certificate {i}{certificateName}"); + builder.AppendLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); + builder.AppendLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); + builder.AppendLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); + builder.AppendLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); + builder.AppendLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); + builder.AppendLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); + builder.AppendLine($" Name: {certificate.Name ?? "[NULL]"}"); + builder.AppendLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); switch (certificate.KeyType) { case Models.N3DS.PublicKeyType.RSA_4096: case Models.N3DS.PublicKeyType.RSA_2048: - Console.WriteLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); - Console.WriteLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); + builder.AppendLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); + builder.AppendLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); break; case Models.N3DS.PublicKeyType.EllipticCurve: - Console.WriteLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); + builder.AppendLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print ticket information /// - private void PrintTicket() + /// StringBuilder to append information to + private void PrintTicket(StringBuilder builder) { - Console.WriteLine(" Ticket Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature type: {T_SignatureType} (0x{T_SignatureType:X})"); - Console.WriteLine($" Signature size: {T_SignatureSize} (0x{T_SignatureSize:X})"); - Console.WriteLine($" Padding size: {T_PaddingSize} (0x{T_PaddingSize:X})"); - Console.WriteLine($" Signature: {BitConverter.ToString(T_Signature).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(T_Padding).Replace('-', ' ')}"); - Console.WriteLine($" Issuer: {T_Issuer ?? "[NULL]"}"); - Console.WriteLine($" ECC public key: {BitConverter.ToString(T_ECCPublicKey).Replace('-', ' ')}"); - Console.WriteLine($" Version: {T_Version} (0x{T_Version:X})"); - Console.WriteLine($" CaCrlVersion: {T_CaCrlVersion} (0x{T_CaCrlVersion:X})"); - Console.WriteLine($" SignerCrlVersion: {T_SignerCrlVersion} (0x{T_SignerCrlVersion:X})"); - Console.WriteLine($" Title key: {BitConverter.ToString(T_TitleKey).Replace('-', ' ')}"); - Console.WriteLine($" Reserved 1: {T_Reserved1} (0x{T_Reserved1:X})"); - Console.WriteLine($" Ticket ID: {T_TicketID} (0x{T_TicketID:X})"); - Console.WriteLine($" Console ID: {T_ConsoleID} (0x{T_ConsoleID:X})"); - Console.WriteLine($" Title ID {T_TitleID} (0x{T_TitleID:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(T_Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Ticket title version: {T_TicketTitleVersion} (0x{T_TicketTitleVersion:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(T_Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" License type: {T_LicenseType} (0x{T_LicenseType:X})"); - Console.WriteLine($" Common keY index: {T_CommonKeyYIndex} (0x{T_CommonKeyYIndex:X})"); - Console.WriteLine($" Reserved 4: {BitConverter.ToString(T_Reserved4).Replace('-', ' ')}"); - Console.WriteLine($" eShop Account ID?: {T_eShopAccountID} (0x{T_eShopAccountID:X})"); - Console.WriteLine($" Reserved 5: {T_Reserved5} (0x{T_Reserved5:X})"); - Console.WriteLine($" Audit: {T_Audit} (0x{T_Audit:X})"); - Console.WriteLine($" Reserved 6: {BitConverter.ToString(T_Reserved6).Replace('-', ' ')}"); - Console.WriteLine($" Limits:"); + builder.AppendLine(" Ticket Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature type: {T_SignatureType} (0x{T_SignatureType:X})"); + builder.AppendLine($" Signature size: {T_SignatureSize} (0x{T_SignatureSize:X})"); + builder.AppendLine($" Padding size: {T_PaddingSize} (0x{T_PaddingSize:X})"); + builder.AppendLine($" Signature: {BitConverter.ToString(T_Signature).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(T_Padding).Replace('-', ' ')}"); + builder.AppendLine($" Issuer: {T_Issuer ?? "[NULL]"}"); + builder.AppendLine($" ECC public key: {BitConverter.ToString(T_ECCPublicKey).Replace('-', ' ')}"); + builder.AppendLine($" Version: {T_Version} (0x{T_Version:X})"); + builder.AppendLine($" CaCrlVersion: {T_CaCrlVersion} (0x{T_CaCrlVersion:X})"); + builder.AppendLine($" SignerCrlVersion: {T_SignerCrlVersion} (0x{T_SignerCrlVersion:X})"); + builder.AppendLine($" Title key: {BitConverter.ToString(T_TitleKey).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 1: {T_Reserved1} (0x{T_Reserved1:X})"); + builder.AppendLine($" Ticket ID: {T_TicketID} (0x{T_TicketID:X})"); + builder.AppendLine($" Console ID: {T_ConsoleID} (0x{T_ConsoleID:X})"); + builder.AppendLine($" Title ID {T_TitleID} (0x{T_TitleID:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(T_Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Ticket title version: {T_TicketTitleVersion} (0x{T_TicketTitleVersion:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(T_Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" License type: {T_LicenseType} (0x{T_LicenseType:X})"); + builder.AppendLine($" Common keY index: {T_CommonKeyYIndex} (0x{T_CommonKeyYIndex:X})"); + builder.AppendLine($" Reserved 4: {BitConverter.ToString(T_Reserved4).Replace('-', ' ')}"); + builder.AppendLine($" eShop Account ID?: {T_eShopAccountID} (0x{T_eShopAccountID:X})"); + builder.AppendLine($" Reserved 5: {T_Reserved5} (0x{T_Reserved5:X})"); + builder.AppendLine($" Audit: {T_Audit} (0x{T_Audit:X})"); + builder.AppendLine($" Reserved 6: {BitConverter.ToString(T_Reserved6).Replace('-', ' ')}"); + builder.AppendLine($" Limits:"); for (int i = 0; i < T_Limits.Length; i++) { - Console.WriteLine($" Limit {i}: {T_Limits[i]} (0x{T_Limits[i]:X})"); + builder.AppendLine($" Limit {i}: {T_Limits[i]} (0x{T_Limits[i]:X})"); } - Console.WriteLine($" Content index size: {T_ContentIndexSize} (0x{T_ContentIndexSize:X})"); - Console.WriteLine($" Content index: {BitConverter.ToString(T_ContentIndex).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine($" Content index size: {T_ContentIndexSize} (0x{T_ContentIndexSize:X})"); + builder.AppendLine($" Content index: {BitConverter.ToString(T_ContentIndex).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine(" Ticket Certificate Chain Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Ticket Certificate Chain Information:"); + builder.AppendLine(" -------------------------"); if (T_CertificateChain == null || T_CertificateChain.Length == 0) { - Console.WriteLine(" No certificates, expected 2"); + builder.AppendLine(" No certificates, expected 2"); } else { @@ -464,113 +472,114 @@ namespace BurnOutSharp.Wrappers case 1: certificateName = " (CA)"; break; } - Console.WriteLine($" Certificate {i}{certificateName}"); - Console.WriteLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); - Console.WriteLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); - Console.WriteLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); - Console.WriteLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); - Console.WriteLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); - Console.WriteLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); - Console.WriteLine($" Name: {certificate.Name ?? "[NULL]"}"); - Console.WriteLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); + builder.AppendLine($" Certificate {i}{certificateName}"); + builder.AppendLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); + builder.AppendLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); + builder.AppendLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); + builder.AppendLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); + builder.AppendLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); + builder.AppendLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); + builder.AppendLine($" Name: {certificate.Name ?? "[NULL]"}"); + builder.AppendLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); switch (certificate.KeyType) { case Models.N3DS.PublicKeyType.RSA_4096: case Models.N3DS.PublicKeyType.RSA_2048: - Console.WriteLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); - Console.WriteLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); + builder.AppendLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); + builder.AppendLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); break; case Models.N3DS.PublicKeyType.EllipticCurve: - Console.WriteLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); + builder.AppendLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print title metadata information /// - private void PrintTitleMetadata() + /// StringBuilder to append information to + private void PrintTitleMetadata(StringBuilder builder) { - Console.WriteLine(" Title Metadata Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature type: {TMD_SignatureType} (0x{TMD_SignatureType:X})"); - Console.WriteLine($" Signature size: {TMD_SignatureSize} (0x{TMD_SignatureSize:X})"); - Console.WriteLine($" Padding size: {TMD_PaddingSize} (0x{TMD_PaddingSize:X})"); - Console.WriteLine($" Signature: {BitConverter.ToString(TMD_Signature).Replace('-', ' ')}"); - Console.WriteLine($" Padding 1: {BitConverter.ToString(TMD_Padding1).Replace('-', ' ')}"); - Console.WriteLine($" Issuer: {TMD_Issuer ?? "[NULL]"}"); - Console.WriteLine($" Version: {TMD_Version} (0x{TMD_Version:X})"); - Console.WriteLine($" CaCrlVersion: {TMD_CaCrlVersion} (0x{TMD_CaCrlVersion:X})"); - Console.WriteLine($" SignerCrlVersion: {TMD_SignerCrlVersion} (0x{TMD_SignerCrlVersion:X})"); - Console.WriteLine($" Reserved 1: {TMD_Reserved1} (0x{TMD_Reserved1:X})"); - Console.WriteLine($" System version: {TMD_SystemVersion} (0x{TMD_SystemVersion:X})"); - Console.WriteLine($" Title ID: {TMD_TitleID} (0x{TMD_TitleID:X})"); - Console.WriteLine($" Title type: {TMD_TitleType} (0x{TMD_TitleType:X})"); - Console.WriteLine($" Group ID: {TMD_GroupID} (0x{TMD_GroupID:X})"); - Console.WriteLine($" Save data size: {TMD_SaveDataSize} (0x{TMD_SaveDataSize:X})"); - Console.WriteLine($" SRL private save data size: {TMD_SRLPrivateSaveDataSize} (0x{TMD_SRLPrivateSaveDataSize:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(TMD_Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" SRL flag: {TMD_SRLFlag} (0x{TMD_SRLFlag:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(TMD_Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" Access rights: {TMD_AccessRights} (0x{TMD_AccessRights:X})"); - Console.WriteLine($" Title version: {TMD_TitleVersion} (0x{TMD_TitleVersion:X})"); - Console.WriteLine($" Content count: {TMD_ContentCount} (0x{TMD_ContentCount:X})"); - Console.WriteLine($" Boot content: {TMD_BootContent} (0x{TMD_BootContent:X})"); - Console.WriteLine($" Padding 2: {BitConverter.ToString(TMD_Padding2).Replace('-', ' ')}"); - Console.WriteLine($" SHA-256 hash of the content info records: {BitConverter.ToString(TMD_SHA256HashContentInfoRecords).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" Title Metadata Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature type: {TMD_SignatureType} (0x{TMD_SignatureType:X})"); + builder.AppendLine($" Signature size: {TMD_SignatureSize} (0x{TMD_SignatureSize:X})"); + builder.AppendLine($" Padding size: {TMD_PaddingSize} (0x{TMD_PaddingSize:X})"); + builder.AppendLine($" Signature: {BitConverter.ToString(TMD_Signature).Replace('-', ' ')}"); + builder.AppendLine($" Padding 1: {BitConverter.ToString(TMD_Padding1).Replace('-', ' ')}"); + builder.AppendLine($" Issuer: {TMD_Issuer ?? "[NULL]"}"); + builder.AppendLine($" Version: {TMD_Version} (0x{TMD_Version:X})"); + builder.AppendLine($" CaCrlVersion: {TMD_CaCrlVersion} (0x{TMD_CaCrlVersion:X})"); + builder.AppendLine($" SignerCrlVersion: {TMD_SignerCrlVersion} (0x{TMD_SignerCrlVersion:X})"); + builder.AppendLine($" Reserved 1: {TMD_Reserved1} (0x{TMD_Reserved1:X})"); + builder.AppendLine($" System version: {TMD_SystemVersion} (0x{TMD_SystemVersion:X})"); + builder.AppendLine($" Title ID: {TMD_TitleID} (0x{TMD_TitleID:X})"); + builder.AppendLine($" Title type: {TMD_TitleType} (0x{TMD_TitleType:X})"); + builder.AppendLine($" Group ID: {TMD_GroupID} (0x{TMD_GroupID:X})"); + builder.AppendLine($" Save data size: {TMD_SaveDataSize} (0x{TMD_SaveDataSize:X})"); + builder.AppendLine($" SRL private save data size: {TMD_SRLPrivateSaveDataSize} (0x{TMD_SRLPrivateSaveDataSize:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(TMD_Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" SRL flag: {TMD_SRLFlag} (0x{TMD_SRLFlag:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(TMD_Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" Access rights: {TMD_AccessRights} (0x{TMD_AccessRights:X})"); + builder.AppendLine($" Title version: {TMD_TitleVersion} (0x{TMD_TitleVersion:X})"); + builder.AppendLine($" Content count: {TMD_ContentCount} (0x{TMD_ContentCount:X})"); + builder.AppendLine($" Boot content: {TMD_BootContent} (0x{TMD_BootContent:X})"); + builder.AppendLine($" Padding 2: {BitConverter.ToString(TMD_Padding2).Replace('-', ' ')}"); + builder.AppendLine($" SHA-256 hash of the content info records: {BitConverter.ToString(TMD_SHA256HashContentInfoRecords).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine(" Ticket Content Info Records Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Ticket Content Info Records Information:"); + builder.AppendLine(" -------------------------"); if (TMD_ContentInfoRecords == null || TMD_ContentInfoRecords.Length == 0) { - Console.WriteLine(" No content info records, expected 64"); + builder.AppendLine(" No content info records, expected 64"); } else { for (int i = 0; i < TMD_ContentInfoRecords.Length; i++) { var contentInfoRecord = TMD_ContentInfoRecords[i]; - Console.WriteLine($" Content Info Record {i}"); - Console.WriteLine($" Content index offset: {contentInfoRecord.ContentIndexOffset} (0x{contentInfoRecord.ContentIndexOffset:X})"); - Console.WriteLine($" Content command count: {contentInfoRecord.ContentCommandCount} (0x{contentInfoRecord.ContentCommandCount:X})"); - Console.WriteLine($" SHA-256 hash of the next {contentInfoRecord.ContentCommandCount} records not hashed: {BitConverter.ToString(contentInfoRecord.UnhashedContentRecordsSHA256Hash).Replace('-', ' ')}"); + builder.AppendLine($" Content Info Record {i}"); + builder.AppendLine($" Content index offset: {contentInfoRecord.ContentIndexOffset} (0x{contentInfoRecord.ContentIndexOffset:X})"); + builder.AppendLine($" Content command count: {contentInfoRecord.ContentCommandCount} (0x{contentInfoRecord.ContentCommandCount:X})"); + builder.AppendLine($" SHA-256 hash of the next {contentInfoRecord.ContentCommandCount} records not hashed: {BitConverter.ToString(contentInfoRecord.UnhashedContentRecordsSHA256Hash).Replace('-', ' ')}"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Ticket Content Chunk Records Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Ticket Content Chunk Records Information:"); + builder.AppendLine(" -------------------------"); if (TMD_ContentChunkRecords == null || TMD_ContentChunkRecords.Length == 0) { - Console.WriteLine($" No content chunk records, expected {TMD_ContentCount}"); + builder.AppendLine($" No content chunk records, expected {TMD_ContentCount}"); } else { for (int i = 0; i < TMD_ContentChunkRecords.Length; i++) { var contentChunkRecord = TMD_ContentChunkRecords[i]; - Console.WriteLine($" Content Chunk Record {i}"); - Console.WriteLine($" Content ID: {contentChunkRecord.ContentId} (0x{contentChunkRecord.ContentId:X})"); - Console.WriteLine($" Content index: {contentChunkRecord.ContentIndex} (0x{contentChunkRecord.ContentIndex:X})"); - Console.WriteLine($" Content type: {contentChunkRecord.ContentType} (0x{contentChunkRecord.ContentType:X})"); - Console.WriteLine($" Content size: {contentChunkRecord.ContentSize} (0x{contentChunkRecord.ContentSize:X})"); - Console.WriteLine($" SHA-256 hash: {BitConverter.ToString(contentChunkRecord.SHA256Hash).Replace('-', ' ')}"); + builder.AppendLine($" Content Chunk Record {i}"); + builder.AppendLine($" Content ID: {contentChunkRecord.ContentId} (0x{contentChunkRecord.ContentId:X})"); + builder.AppendLine($" Content index: {contentChunkRecord.ContentIndex} (0x{contentChunkRecord.ContentIndex:X})"); + builder.AppendLine($" Content type: {contentChunkRecord.ContentType} (0x{contentChunkRecord.ContentType:X})"); + builder.AppendLine($" Content size: {contentChunkRecord.ContentSize} (0x{contentChunkRecord.ContentSize:X})"); + builder.AppendLine($" SHA-256 hash: {BitConverter.ToString(contentChunkRecord.SHA256Hash).Replace('-', ' ')}"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Ticket Certificate Chain Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Ticket Certificate Chain Information:"); + builder.AppendLine(" -------------------------"); if (TMD_CertificateChain == null || TMD_CertificateChain.Length == 0) { - Console.WriteLine(" No certificates, expected 2"); + builder.AppendLine(" No certificates, expected 2"); } else { @@ -585,124 +594,126 @@ namespace BurnOutSharp.Wrappers case 1: certificateName = " (CA)"; break; } - Console.WriteLine($" Certificate {i}{certificateName}"); - Console.WriteLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); - Console.WriteLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); - Console.WriteLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); - Console.WriteLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); - Console.WriteLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); - Console.WriteLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); - Console.WriteLine($" Name: {certificate.Name ?? "[NULL]"}"); - Console.WriteLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); + builder.AppendLine($" Certificate {i}{certificateName}"); + builder.AppendLine($" Signature type: {certificate.SignatureType} (0x{certificate.SignatureType:X})"); + builder.AppendLine($" Signature size: {certificate.SignatureSize} (0x{certificate.SignatureSize:X})"); + builder.AppendLine($" Padding size: {certificate.PaddingSize} (0x{certificate.PaddingSize:X})"); + builder.AppendLine($" Signature: {BitConverter.ToString(certificate.Signature).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.Padding).Replace('-', ' ')}"); + builder.AppendLine($" Issuer: {certificate.Issuer ?? "[NULL]"}"); + builder.AppendLine($" Key type: {certificate.KeyType} (0x{certificate.KeyType:X})"); + builder.AppendLine($" Name: {certificate.Name ?? "[NULL]"}"); + builder.AppendLine($" Expiration time: {certificate.ExpirationTime} (0x{certificate.ExpirationTime:X})"); switch (certificate.KeyType) { case Models.N3DS.PublicKeyType.RSA_4096: case Models.N3DS.PublicKeyType.RSA_2048: - Console.WriteLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); - Console.WriteLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); + builder.AppendLine($" Modulus: {BitConverter.ToString(certificate.RSAModulus).Replace('-', ' ')}"); + builder.AppendLine($" Public exponent: {certificate.RSAPublicExponent} (0x{certificate.RSAPublicExponent:X})"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.RSAPadding).Replace('-', ' ')}"); break; case Models.N3DS.PublicKeyType.EllipticCurve: - Console.WriteLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); - Console.WriteLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); + builder.AppendLine($" Public key: {BitConverter.ToString(certificate.ECCPublicKey).Replace('-', ' ')}"); + builder.AppendLine($" Padding: {BitConverter.ToString(certificate.ECCPadding).Replace('-', ' ')}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print NCCH partition header information /// - private void PrintPartitions() + /// StringBuilder to append information to + private void PrintPartitions(StringBuilder builder) { - Console.WriteLine(" NCCH Partition Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" NCCH Partition Header Information:"); + builder.AppendLine(" -------------------------"); if (Partitions == null || Partitions.Length == 0) { - Console.WriteLine(" No NCCH partition headers"); + builder.AppendLine(" No NCCH partition headers"); } else { for (int i = 0; i < Partitions.Length; i++) { var partitionHeader = Partitions[i]; - Console.WriteLine($" NCCH Partition Header {i}"); + builder.AppendLine($" NCCH Partition Header {i}"); if (partitionHeader.MagicID == string.Empty) { - Console.WriteLine($" Empty partition, no data can be parsed"); + builder.AppendLine($" 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"); + builder.AppendLine($" 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} (0x{partitionHeader.MagicID:X})"); - Console.WriteLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits} (0x{partitionHeader.ContentSizeInMediaUnits:X})"); - Console.WriteLine($" Partition ID: {partitionHeader.PartitionId} (0x{partitionHeader.PartitionId:X})"); - Console.WriteLine($" Maker code: {partitionHeader.MakerCode} (0x{partitionHeader.MakerCode:X})"); - Console.WriteLine($" Version: {partitionHeader.Version} (0x{partitionHeader.Version:X})"); - Console.WriteLine($" Verification hash: {partitionHeader.VerificationHash} (0x{partitionHeader.VerificationHash:X})"); - 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} (0x{partitionHeader.ProductCode:X})"); - Console.WriteLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}"); - Console.WriteLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}"); - Console.WriteLine(" Flags:"); - Console.WriteLine($" Reserved 0: {partitionHeader.Flags.Reserved0} (0x{partitionHeader.Flags.Reserved0:X})"); - Console.WriteLine($" Reserved 1: {partitionHeader.Flags.Reserved1} (0x{partitionHeader.Flags.Reserved1:X})"); - Console.WriteLine($" Reserved 2: {partitionHeader.Flags.Reserved2} (0x{partitionHeader.Flags.Reserved2:X})"); - Console.WriteLine($" Crypto method: {partitionHeader.Flags.CryptoMethod} (0x{partitionHeader.Flags.CryptoMethod:X})"); - Console.WriteLine($" Content platform: {partitionHeader.Flags.ContentPlatform} (0x{partitionHeader.Flags.ContentPlatform:X})"); - Console.WriteLine($" Content type: {partitionHeader.Flags.MediaPlatformIndex} (0x{partitionHeader.Flags.MediaPlatformIndex:X})"); - Console.WriteLine($" Content unit size: {partitionHeader.Flags.ContentUnitSize} (0x{partitionHeader.Flags.ContentUnitSize:X})"); - Console.WriteLine($" Bitmasks: {partitionHeader.Flags.BitMasks} (0x{partitionHeader.Flags.BitMasks:X})"); - Console.WriteLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits} (0x{partitionHeader.PlainRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits} (0x{partitionHeader.PlainRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits} (0x{partitionHeader.LogoRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits} (0x{partitionHeader.LogoRegionSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits} (0x{partitionHeader.ExeFSOffsetInMediaUnits:X})"); - Console.WriteLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits} (0x{partitionHeader.ExeFSSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits} (0x{partitionHeader.ExeFSHashRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits} (0x{partitionHeader.RomFSOffsetInMediaUnits:X})"); - Console.WriteLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits} (0x{partitionHeader.RomFSSizeInMediaUnits:X})"); - Console.WriteLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits} (0x{partitionHeader.RomFSHashRegionSizeInMediaUnits:X})"); - 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('-', ' ')}"); + builder.AppendLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(partitionHeader.RSA2048Signature).Replace('-', ' ')}"); + builder.AppendLine($" Magic ID: {partitionHeader.MagicID} (0x{partitionHeader.MagicID:X})"); + builder.AppendLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits} (0x{partitionHeader.ContentSizeInMediaUnits:X})"); + builder.AppendLine($" Partition ID: {partitionHeader.PartitionId} (0x{partitionHeader.PartitionId:X})"); + builder.AppendLine($" Maker code: {partitionHeader.MakerCode} (0x{partitionHeader.MakerCode:X})"); + builder.AppendLine($" Version: {partitionHeader.Version} (0x{partitionHeader.Version:X})"); + builder.AppendLine($" Verification hash: {partitionHeader.VerificationHash} (0x{partitionHeader.VerificationHash:X})"); + builder.AppendLine($" Program ID: {BitConverter.ToString(partitionHeader.ProgramId).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(partitionHeader.Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Logo region SHA-256 hash: {BitConverter.ToString(partitionHeader.LogoRegionHash).Replace('-', ' ')}"); + builder.AppendLine($" Product code: {partitionHeader.ProductCode} (0x{partitionHeader.ProductCode:X})"); + builder.AppendLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}"); + builder.AppendLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}"); + builder.AppendLine(" Flags:"); + builder.AppendLine($" Reserved 0: {partitionHeader.Flags.Reserved0} (0x{partitionHeader.Flags.Reserved0:X})"); + builder.AppendLine($" Reserved 1: {partitionHeader.Flags.Reserved1} (0x{partitionHeader.Flags.Reserved1:X})"); + builder.AppendLine($" Reserved 2: {partitionHeader.Flags.Reserved2} (0x{partitionHeader.Flags.Reserved2:X})"); + builder.AppendLine($" Crypto method: {partitionHeader.Flags.CryptoMethod} (0x{partitionHeader.Flags.CryptoMethod:X})"); + builder.AppendLine($" Content platform: {partitionHeader.Flags.ContentPlatform} (0x{partitionHeader.Flags.ContentPlatform:X})"); + builder.AppendLine($" Content type: {partitionHeader.Flags.MediaPlatformIndex} (0x{partitionHeader.Flags.MediaPlatformIndex:X})"); + builder.AppendLine($" Content unit size: {partitionHeader.Flags.ContentUnitSize} (0x{partitionHeader.Flags.ContentUnitSize:X})"); + builder.AppendLine($" Bitmasks: {partitionHeader.Flags.BitMasks} (0x{partitionHeader.Flags.BitMasks:X})"); + builder.AppendLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits} (0x{partitionHeader.PlainRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits} (0x{partitionHeader.PlainRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits} (0x{partitionHeader.LogoRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits} (0x{partitionHeader.LogoRegionSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits} (0x{partitionHeader.ExeFSOffsetInMediaUnits:X})"); + builder.AppendLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits} (0x{partitionHeader.ExeFSSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits} (0x{partitionHeader.ExeFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits} (0x{partitionHeader.RomFSOffsetInMediaUnits:X})"); + builder.AppendLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits} (0x{partitionHeader.RomFSSizeInMediaUnits:X})"); + builder.AppendLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits} (0x{partitionHeader.RomFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 4: {BitConverter.ToString(partitionHeader.Reserved4).Replace('-', ' ')}"); + builder.AppendLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.ExeFSSuperblockHash).Replace('-', ' ')}"); + builder.AppendLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.RomFSSuperblockHash).Replace('-', ' ')}"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print metadata information /// - private void PrintMetaData() + /// StringBuilder to append information to + private void PrintMetaData(StringBuilder builder) { - Console.WriteLine(" Meta Data Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Meta Data Information:"); + builder.AppendLine(" -------------------------"); if (_cia.MetaData == null || MetaSize == 0) { - Console.WriteLine(value: " No meta file data"); + builder.AppendLine(value: " No meta file data"); } else { - Console.WriteLine(value: $" Title ID dependency list: {BitConverter.ToString(MD_TitleIDDependencyList).Replace('-', ' ')}"); - Console.WriteLine($" Reserved 1: {BitConverter.ToString(MD_Reserved1).Replace('-', ' ')}"); - Console.WriteLine($" Core version: {MD_CoreVersion} (0x{MD_CoreVersion:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(MD_Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Icon data: {BitConverter.ToString(MD_IconData).Replace('-', ' ')}"); + builder.AppendLine(value: $" Title ID dependency list: {BitConverter.ToString(MD_TitleIDDependencyList).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(MD_Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Core version: {MD_CoreVersion} (0x{MD_CoreVersion:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(MD_Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Icon data: {BitConverter.ToString(MD_IconData).Replace('-', ' ')}"); } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/GCF.cs b/BurnOutSharp.Wrappers/GCF.cs index ee6c3b60..1445907d 100644 --- a/BurnOutSharp.Wrappers/GCF.cs +++ b/BurnOutSharp.Wrappers/GCF.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -469,474 +470,498 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("GCF Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("GCF Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Header - PrintHeader(); + PrintHeader(builder); // Block Entries - PrintBlockEntryHeader(); - PrintBlockEntries(); + PrintBlockEntryHeader(builder); + PrintBlockEntries(builder); // Fragmentation Maps - PrintFragmentationMapHeader(); - PrintFragmentationMaps(); + PrintFragmentationMapHeader(builder); + PrintFragmentationMaps(builder); // Block Entry Maps - PrintBlockEntryMapHeader(); - PrintBlockEntryMaps(); + PrintBlockEntryMapHeader(builder); + PrintBlockEntryMaps(builder); // Directory and Directory Maps - PrintDirectoryHeader(); - PrintDirectoryEntries(); + PrintDirectoryHeader(builder); + PrintDirectoryEntries(builder); // TODO: Should we print out the entire string table? - PrintDirectoryInfo1Entries(); - PrintDirectoryInfo2Entries(); - PrintDirectoryCopyEntries(); - PrintDirectoryLocalEntries(); - PrintDirectoryMapHeader(); - PrintDirectoryMapEntries(); + PrintDirectoryInfo1Entries(builder); + PrintDirectoryInfo2Entries(builder); + PrintDirectoryCopyEntries(builder); + PrintDirectoryLocalEntries(builder); + PrintDirectoryMapHeader(builder); + PrintDirectoryMapEntries(builder); // Checksums and Checksum Maps - PrintChecksumHeader(); - PrintChecksumMapHeader(); - PrintChecksumMapEntries(); - PrintChecksumEntries(); + PrintChecksumHeader(builder); + PrintChecksumMapHeader(builder); + PrintChecksumMapEntries(builder); + PrintChecksumEntries(builder); // Data Blocks - PrintDataBlockHeader(); + PrintDataBlockHeader(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); - Console.WriteLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); - Console.WriteLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); - Console.WriteLine($" Cache ID: {CacheID} (0x{CacheID:X})"); - Console.WriteLine($" Last version played: {LastVersionPlayed} (0x{LastVersionPlayed:X})"); - Console.WriteLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); - Console.WriteLine($" Dummy 2: {Dummy2} (0x{Dummy2:X})"); - Console.WriteLine($" File size: {FileSize} (0x{FileSize:X})"); - Console.WriteLine($" Block size: {BlockSize} (0x{BlockSize:X})"); - Console.WriteLine($" Block count: {BlockCount} (0x{BlockCount:X})"); - Console.WriteLine($" Dummy 3: {Dummy3} (0x{Dummy3:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); + builder.AppendLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); + builder.AppendLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); + builder.AppendLine($" Cache ID: {CacheID} (0x{CacheID:X})"); + builder.AppendLine($" Last version played: {LastVersionPlayed} (0x{LastVersionPlayed:X})"); + builder.AppendLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); + builder.AppendLine($" Dummy 2: {Dummy2} (0x{Dummy2:X})"); + builder.AppendLine($" File size: {FileSize} (0x{FileSize:X})"); + builder.AppendLine($" Block size: {BlockSize} (0x{BlockSize:X})"); + builder.AppendLine($" Block count: {BlockCount} (0x{BlockCount:X})"); + builder.AppendLine($" Dummy 3: {Dummy3} (0x{Dummy3:X})"); + builder.AppendLine(); } /// /// Print block entry header information /// - private void PrintBlockEntryHeader() + /// StringBuilder to append information to + private void PrintBlockEntryHeader(StringBuilder builder) { - Console.WriteLine(" Block Entry Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Block count: {BEH_BlockCount} (0x{BEH_BlockCount:X})"); - Console.WriteLine($" Blocks used: {BEH_BlocksUsed} (0x{BEH_BlocksUsed:X})"); - Console.WriteLine($" Dummy 0: {BEH_Dummy0} (0x{BEH_Dummy0:X})"); - Console.WriteLine($" Dummy 1: {BEH_Dummy1} (0x{BEH_Dummy1:X})"); - Console.WriteLine($" Dummy 2: {BEH_Dummy2} (0x{BEH_Dummy2:X})"); - Console.WriteLine($" Dummy 3: {BEH_Dummy3} (0x{BEH_Dummy3:X})"); - Console.WriteLine($" Dummy 4: {BEH_Dummy4} (0x{BEH_Dummy4:X})"); - Console.WriteLine($" Checksum: {BEH_Checksum} (0x{BEH_Checksum:X})"); - Console.WriteLine(); + builder.AppendLine(" Block Entry Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Block count: {BEH_BlockCount} (0x{BEH_BlockCount:X})"); + builder.AppendLine($" Blocks used: {BEH_BlocksUsed} (0x{BEH_BlocksUsed:X})"); + builder.AppendLine($" Dummy 0: {BEH_Dummy0} (0x{BEH_Dummy0:X})"); + builder.AppendLine($" Dummy 1: {BEH_Dummy1} (0x{BEH_Dummy1:X})"); + builder.AppendLine($" Dummy 2: {BEH_Dummy2} (0x{BEH_Dummy2:X})"); + builder.AppendLine($" Dummy 3: {BEH_Dummy3} (0x{BEH_Dummy3:X})"); + builder.AppendLine($" Dummy 4: {BEH_Dummy4} (0x{BEH_Dummy4:X})"); + builder.AppendLine($" Checksum: {BEH_Checksum} (0x{BEH_Checksum:X})"); + builder.AppendLine(); } /// /// Print block entries information /// - private void PrintBlockEntries() + /// StringBuilder to append information to + private void PrintBlockEntries(StringBuilder builder) { - Console.WriteLine(" Block Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Block Entries Information:"); + builder.AppendLine(" -------------------------"); if (BlockEntries == null || BlockEntries.Length == 0) { - Console.WriteLine(" No block entries"); + builder.AppendLine(" No block entries"); } else { for (int i = 0; i < BlockEntries.Length; i++) { var blockEntry = BlockEntries[i]; - Console.WriteLine($" Block Entry {i}"); - Console.WriteLine($" Entry flags: {blockEntry.EntryFlags} (0x{blockEntry.EntryFlags:X})"); - Console.WriteLine($" File data offset: {blockEntry.FileDataOffset} (0x{blockEntry.FileDataOffset:X})"); - Console.WriteLine($" File data size: {blockEntry.FileDataSize} (0x{blockEntry.FileDataSize:X})"); - Console.WriteLine($" First data block index: {blockEntry.FirstDataBlockIndex} (0x{blockEntry.FirstDataBlockIndex:X})"); - Console.WriteLine($" Next block entry index: {blockEntry.NextBlockEntryIndex} (0x{blockEntry.NextBlockEntryIndex:X})"); - Console.WriteLine($" Previous block entry index: {blockEntry.PreviousBlockEntryIndex} (0x{blockEntry.PreviousBlockEntryIndex:X})"); - Console.WriteLine($" Directory index: {blockEntry.DirectoryIndex} (0x{blockEntry.DirectoryIndex:X})"); + builder.AppendLine($" Block Entry {i}"); + builder.AppendLine($" Entry flags: {blockEntry.EntryFlags} (0x{blockEntry.EntryFlags:X})"); + builder.AppendLine($" File data offset: {blockEntry.FileDataOffset} (0x{blockEntry.FileDataOffset:X})"); + builder.AppendLine($" File data size: {blockEntry.FileDataSize} (0x{blockEntry.FileDataSize:X})"); + builder.AppendLine($" First data block index: {blockEntry.FirstDataBlockIndex} (0x{blockEntry.FirstDataBlockIndex:X})"); + builder.AppendLine($" Next block entry index: {blockEntry.NextBlockEntryIndex} (0x{blockEntry.NextBlockEntryIndex:X})"); + builder.AppendLine($" Previous block entry index: {blockEntry.PreviousBlockEntryIndex} (0x{blockEntry.PreviousBlockEntryIndex:X})"); + builder.AppendLine($" Directory index: {blockEntry.DirectoryIndex} (0x{blockEntry.DirectoryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print fragmentation map header information /// - private void PrintFragmentationMapHeader() + /// StringBuilder to append information to + private void PrintFragmentationMapHeader(StringBuilder builder) { - Console.WriteLine(" Fragmentation Map Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Block count: {FMH_BlockCount} (0x{FMH_BlockCount:X})"); - Console.WriteLine($" First unused entry: {FMH_FirstUnusedEntry} (0x{FMH_FirstUnusedEntry:X})"); - Console.WriteLine($" Terminator: {FMH_Terminator} (0x{FMH_Terminator:X})"); - Console.WriteLine($" Checksum: {FMH_Checksum} (0x{FMH_Checksum:X})"); - Console.WriteLine(); + builder.AppendLine(" Fragmentation Map Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Block count: {FMH_BlockCount} (0x{FMH_BlockCount:X})"); + builder.AppendLine($" First unused entry: {FMH_FirstUnusedEntry} (0x{FMH_FirstUnusedEntry:X})"); + builder.AppendLine($" Terminator: {FMH_Terminator} (0x{FMH_Terminator:X})"); + builder.AppendLine($" Checksum: {FMH_Checksum} (0x{FMH_Checksum:X})"); + builder.AppendLine(); } /// /// Print fragmentation maps information /// - private void PrintFragmentationMaps() + /// StringBuilder to append information to + private void PrintFragmentationMaps(StringBuilder builder) { - Console.WriteLine(" Fragmentation Maps Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Fragmentation Maps Information:"); + builder.AppendLine(" -------------------------"); if (FragmentationMaps == null || FragmentationMaps.Length == 0) { - Console.WriteLine(" No fragmentation maps"); + builder.AppendLine(" No fragmentation maps"); } else { for (int i = 0; i < FragmentationMaps.Length; i++) { var fragmentationMap = FragmentationMaps[i]; - Console.WriteLine($" Fragmentation Map {i}"); - Console.WriteLine($" Next data block index: {fragmentationMap.NextDataBlockIndex} (0x{fragmentationMap.NextDataBlockIndex:X})"); + builder.AppendLine($" Fragmentation Map {i}"); + builder.AppendLine($" Next data block index: {fragmentationMap.NextDataBlockIndex} (0x{fragmentationMap.NextDataBlockIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print block entry map header information /// - private void PrintBlockEntryMapHeader() + /// StringBuilder to append information to + private void PrintBlockEntryMapHeader(StringBuilder builder) { - Console.WriteLine(" Block Entry Map Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Block Entry Map Header Information:"); + builder.AppendLine(" -------------------------"); if (_file.BlockEntryMapHeader == null) { - Console.WriteLine($" No block entry map header"); + builder.AppendLine($" No block entry map header"); } else { - Console.WriteLine($" Block count: {BEMH_BlockCount} (0x{BEMH_BlockCount:X})"); - Console.WriteLine($" First block entry index: {BEMH_FirstBlockEntryIndex} (0x{BEMH_FirstBlockEntryIndex:X})"); - Console.WriteLine($" Last block entry index: {BEMH_LastBlockEntryIndex} (0x{BEMH_LastBlockEntryIndex:X})"); - Console.WriteLine($" Dummy 0: {BEMH_Dummy0} (0x{BEMH_Dummy0:X})"); - Console.WriteLine($" Checksum: {BEMH_Checksum} (0x{BEMH_Checksum:X})"); + builder.AppendLine($" Block count: {BEMH_BlockCount} (0x{BEMH_BlockCount:X})"); + builder.AppendLine($" First block entry index: {BEMH_FirstBlockEntryIndex} (0x{BEMH_FirstBlockEntryIndex:X})"); + builder.AppendLine($" Last block entry index: {BEMH_LastBlockEntryIndex} (0x{BEMH_LastBlockEntryIndex:X})"); + builder.AppendLine($" Dummy 0: {BEMH_Dummy0} (0x{BEMH_Dummy0:X})"); + builder.AppendLine($" Checksum: {BEMH_Checksum} (0x{BEMH_Checksum:X})"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print block entry maps information /// - private void PrintBlockEntryMaps() + /// StringBuilder to append information to + private void PrintBlockEntryMaps(StringBuilder builder) { - Console.WriteLine(" Block Entry Maps Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Block Entry Maps Information:"); + builder.AppendLine(" -------------------------"); if (BlockEntryMaps == null || BlockEntryMaps.Length == 0) { - Console.WriteLine(" No block entry maps"); + builder.AppendLine(" No block entry maps"); } else { for (int i = 0; i < BlockEntryMaps.Length; i++) { var blockEntryMap = BlockEntryMaps[i]; - Console.WriteLine($" Block Entry Map {i}"); - Console.WriteLine($" Previous data block index: {blockEntryMap.PreviousBlockEntryIndex} (0x{blockEntryMap.PreviousBlockEntryIndex:X})"); - Console.WriteLine($" Next data block index: {blockEntryMap.NextBlockEntryIndex} (0x{blockEntryMap.NextBlockEntryIndex:X})"); + builder.AppendLine($" Block Entry Map {i}"); + builder.AppendLine($" Previous data block index: {blockEntryMap.PreviousBlockEntryIndex} (0x{blockEntryMap.PreviousBlockEntryIndex:X})"); + builder.AppendLine($" Next data block index: {blockEntryMap.NextBlockEntryIndex} (0x{blockEntryMap.NextBlockEntryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory header information /// - private void PrintDirectoryHeader() + /// StringBuilder to append information to + private void PrintDirectoryHeader(StringBuilder builder) { - Console.WriteLine(" Directory Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {DH_Dummy0} (0x{DH_Dummy0:X})"); - Console.WriteLine($" Cache ID: {DH_CacheID} (0x{DH_CacheID:X})"); - Console.WriteLine($" Last version played: {DH_LastVersionPlayed} (0x{DH_LastVersionPlayed:X})"); - Console.WriteLine($" Item count: {DH_ItemCount} (0x{DH_ItemCount:X})"); - Console.WriteLine($" File count: {DH_FileCount} (0x{DH_FileCount:X})"); - Console.WriteLine($" Dummy 1: {DH_Dummy1} (0x{DH_Dummy1:X})"); - Console.WriteLine($" Directory size: {DH_DirectorySize} (0x{DH_DirectorySize:X})"); - Console.WriteLine($" Name size: {DH_NameSize} (0x{DH_NameSize:X})"); - Console.WriteLine($" Info 1 count: {DH_Info1Count} (0x{DH_Info1Count:X})"); - Console.WriteLine($" Copy count: {DH_CopyCount} (0x{DH_CopyCount:X})"); - Console.WriteLine($" Local count: {DH_LocalCount} (0x{DH_LocalCount:X})"); - Console.WriteLine($" Dummy 2: {DH_Dummy2} (0x{DH_Dummy2:X})"); - Console.WriteLine($" Dummy 3: {DH_Dummy3} (0x{DH_Dummy3:X})"); - Console.WriteLine($" Checksum: {DH_Checksum} (0x{DH_Checksum:X})"); - Console.WriteLine(); + builder.AppendLine(" Directory Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {DH_Dummy0} (0x{DH_Dummy0:X})"); + builder.AppendLine($" Cache ID: {DH_CacheID} (0x{DH_CacheID:X})"); + builder.AppendLine($" Last version played: {DH_LastVersionPlayed} (0x{DH_LastVersionPlayed:X})"); + builder.AppendLine($" Item count: {DH_ItemCount} (0x{DH_ItemCount:X})"); + builder.AppendLine($" File count: {DH_FileCount} (0x{DH_FileCount:X})"); + builder.AppendLine($" Dummy 1: {DH_Dummy1} (0x{DH_Dummy1:X})"); + builder.AppendLine($" Directory size: {DH_DirectorySize} (0x{DH_DirectorySize:X})"); + builder.AppendLine($" Name size: {DH_NameSize} (0x{DH_NameSize:X})"); + builder.AppendLine($" Info 1 count: {DH_Info1Count} (0x{DH_Info1Count:X})"); + builder.AppendLine($" Copy count: {DH_CopyCount} (0x{DH_CopyCount:X})"); + builder.AppendLine($" Local count: {DH_LocalCount} (0x{DH_LocalCount:X})"); + builder.AppendLine($" Dummy 2: {DH_Dummy2} (0x{DH_Dummy2:X})"); + builder.AppendLine($" Dummy 3: {DH_Dummy3} (0x{DH_Dummy3:X})"); + builder.AppendLine($" Checksum: {DH_Checksum} (0x{DH_Checksum:X})"); + builder.AppendLine(); } /// /// Print directory entries information /// - private void PrintDirectoryEntries() + /// StringBuilder to append information to + private void PrintDirectoryEntries(StringBuilder builder) { - Console.WriteLine(" Directory Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryEntries == null || DirectoryEntries.Length == 0) { - Console.WriteLine(" No directory entries"); + builder.AppendLine(" No directory entries"); } else { for (int i = 0; i < DirectoryEntries.Length; i++) { var directoryEntry = DirectoryEntries[i]; - Console.WriteLine($" Directory Entry {i}"); - Console.WriteLine($" Name offset: {directoryEntry.NameOffset} (0x{directoryEntry.NameOffset:X})"); - Console.WriteLine($" Name: {directoryEntry.Name ?? "[NULL]"}"); - Console.WriteLine($" Item size: {directoryEntry.ItemSize} (0x{directoryEntry.ItemSize:X})"); - Console.WriteLine($" Checksum index: {directoryEntry.ChecksumIndex} (0x{directoryEntry.ChecksumIndex:X})"); - Console.WriteLine($" Directory flags: {directoryEntry.DirectoryFlags} (0x{directoryEntry.DirectoryFlags:X})"); - Console.WriteLine($" Parent index: {directoryEntry.ParentIndex} (0x{directoryEntry.ParentIndex:X})"); - Console.WriteLine($" Next index: {directoryEntry.NextIndex} (0x{directoryEntry.NextIndex:X})"); - Console.WriteLine($" First index: {directoryEntry.FirstIndex} (0x{directoryEntry.FirstIndex:X})"); + builder.AppendLine($" Directory Entry {i}"); + builder.AppendLine($" Name offset: {directoryEntry.NameOffset} (0x{directoryEntry.NameOffset:X})"); + builder.AppendLine($" Name: {directoryEntry.Name ?? "[NULL]"}"); + builder.AppendLine($" Item size: {directoryEntry.ItemSize} (0x{directoryEntry.ItemSize:X})"); + builder.AppendLine($" Checksum index: {directoryEntry.ChecksumIndex} (0x{directoryEntry.ChecksumIndex:X})"); + builder.AppendLine($" Directory flags: {directoryEntry.DirectoryFlags} (0x{directoryEntry.DirectoryFlags:X})"); + builder.AppendLine($" Parent index: {directoryEntry.ParentIndex} (0x{directoryEntry.ParentIndex:X})"); + builder.AppendLine($" Next index: {directoryEntry.NextIndex} (0x{directoryEntry.NextIndex:X})"); + builder.AppendLine($" First index: {directoryEntry.FirstIndex} (0x{directoryEntry.FirstIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory info 1 entries information /// - private void PrintDirectoryInfo1Entries() + /// StringBuilder to append information to + private void PrintDirectoryInfo1Entries(StringBuilder builder) { - Console.WriteLine(" Directory Info 1 Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Info 1 Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryInfo1Entries == null || DirectoryInfo1Entries.Length == 0) { - Console.WriteLine(" No directory info 1 entries"); + builder.AppendLine(" No directory info 1 entries"); } else { for (int i = 0; i < DirectoryInfo1Entries.Length; i++) { var directoryInfoEntry = DirectoryInfo1Entries[i]; - Console.WriteLine($" Directory Info 1 Entry {i}"); - Console.WriteLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); + builder.AppendLine($" Directory Info 1 Entry {i}"); + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory info 2 entries information /// - private void PrintDirectoryInfo2Entries() + /// StringBuilder to append information to + private void PrintDirectoryInfo2Entries(StringBuilder builder) { - Console.WriteLine(" Directory Info 2 Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Info 2 Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryInfo2Entries == null || DirectoryInfo2Entries.Length == 0) { - Console.WriteLine(" No directory info 2 entries"); + builder.AppendLine(" No directory info 2 entries"); } else { for (int i = 0; i < DirectoryInfo2Entries.Length; i++) { var directoryInfoEntry = DirectoryInfo2Entries[i]; - Console.WriteLine($" Directory Info 2 Entry {i}"); - Console.WriteLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); + builder.AppendLine($" Directory Info 2 Entry {i}"); + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory copy entries information /// - private void PrintDirectoryCopyEntries() + /// StringBuilder to append information to + private void PrintDirectoryCopyEntries(StringBuilder builder) { - Console.WriteLine(" Directory Copy Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Directory Copy Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (DirectoryCopyEntries == null || DirectoryCopyEntries.Length == 0) { - Console.WriteLine(" No directory copy entries"); + builder.AppendLine(" No directory copy entries"); } else { for (int i = 0; i < DirectoryCopyEntries.Length; i++) { var directoryCopyEntry = DirectoryCopyEntries[i]; - Console.WriteLine($" Directory Copy Entry {i}"); - Console.WriteLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); + builder.AppendLine($" Directory Copy Entry {i}"); + builder.AppendLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory local entries information /// - private void PrintDirectoryLocalEntries() + /// StringBuilder to append information to + private void PrintDirectoryLocalEntries(StringBuilder builder) { - Console.WriteLine(" Directory Local Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Directory Local Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (DirectoryLocalEntries == null || DirectoryLocalEntries.Length == 0) { - Console.WriteLine(" No directory local entries"); + builder.AppendLine(" No directory local entries"); } else { for (int i = 0; i < DirectoryLocalEntries.Length; i++) { var directoryLocalEntry = DirectoryLocalEntries[i]; - Console.WriteLine($" Directory Local Entry {i}"); - Console.WriteLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); + builder.AppendLine($" Directory Local Entry {i}"); + builder.AppendLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory map header information /// - private void PrintDirectoryMapHeader() + /// StringBuilder to append information to + private void PrintDirectoryMapHeader(StringBuilder builder) { - Console.WriteLine(" Directory Map Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Map Header Information:"); + builder.AppendLine(" -------------------------"); if (_file.DirectoryMapHeader == null) { - Console.WriteLine($" No directory map header"); + builder.AppendLine($" No directory map header"); } else { - Console.WriteLine($" Dummy 0: {DMH_Dummy0} (0x{DMH_Dummy0:X})"); - Console.WriteLine($" Dummy 1: {DMH_Dummy1} (0x{DMH_Dummy1:X})"); + builder.AppendLine($" Dummy 0: {DMH_Dummy0} (0x{DMH_Dummy0:X})"); + builder.AppendLine($" Dummy 1: {DMH_Dummy1} (0x{DMH_Dummy1:X})"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory map entries information /// - private void PrintDirectoryMapEntries() + /// StringBuilder to append information to + private void PrintDirectoryMapEntries(StringBuilder builder) { - Console.WriteLine(" Directory Map Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Directory Map Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (DirectoryMapEntries == null || DirectoryMapEntries.Length == 0) { - Console.WriteLine(" No directory map entries"); + builder.AppendLine(" No directory map entries"); } else { for (int i = 0; i < DirectoryMapEntries.Length; i++) { var directoryMapEntry = DirectoryMapEntries[i]; - Console.WriteLine($" Directory Map Entry {i}"); - Console.WriteLine($" First block index: {directoryMapEntry.FirstBlockIndex} (0x{directoryMapEntry.FirstBlockIndex:X})"); + builder.AppendLine($" Directory Map Entry {i}"); + builder.AppendLine($" First block index: {directoryMapEntry.FirstBlockIndex} (0x{directoryMapEntry.FirstBlockIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print checksum header information /// - private void PrintChecksumHeader() + /// StringBuilder to append information to + private void PrintChecksumHeader(StringBuilder builder) { - Console.WriteLine(" Checksum Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {CH_Dummy0} (0x{CH_Dummy0:X})"); - Console.WriteLine($" Checksum size: {CH_ChecksumSize} (0x{CH_ChecksumSize:X})"); - Console.WriteLine(); + builder.AppendLine(" Checksum Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {CH_Dummy0} (0x{CH_Dummy0:X})"); + builder.AppendLine($" Checksum size: {CH_ChecksumSize} (0x{CH_ChecksumSize:X})"); + builder.AppendLine(); } /// /// Print checksum map header information /// - private void PrintChecksumMapHeader() + /// StringBuilder to append information to + private void PrintChecksumMapHeader(StringBuilder builder) { - Console.WriteLine(" Checksum Map Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {CMH_Dummy0} (0x{CMH_Dummy0:X})"); - Console.WriteLine($" Dummy 1: {CMH_Dummy1} (0x{CMH_Dummy1:X})"); - Console.WriteLine($" Item count: {CMH_ItemCount} (0x{CMH_ItemCount:X})"); - Console.WriteLine($" Checksum count: {CMH_ChecksumCount} (0x{CMH_ChecksumCount:X})"); - Console.WriteLine(); + builder.AppendLine(" Checksum Map Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {CMH_Dummy0} (0x{CMH_Dummy0:X})"); + builder.AppendLine($" Dummy 1: {CMH_Dummy1} (0x{CMH_Dummy1:X})"); + builder.AppendLine($" Item count: {CMH_ItemCount} (0x{CMH_ItemCount:X})"); + builder.AppendLine($" Checksum count: {CMH_ChecksumCount} (0x{CMH_ChecksumCount:X})"); + builder.AppendLine(); } /// /// Print checksum map entries information /// - private void PrintChecksumMapEntries() + /// StringBuilder to append information to + private void PrintChecksumMapEntries(StringBuilder builder) { - Console.WriteLine(" Checksum Map Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Checksum Map Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (ChecksumMapEntries == null || ChecksumMapEntries.Length == 0) { - Console.WriteLine(" No checksum map entries"); + builder.AppendLine(" No checksum map entries"); } else { for (int i = 0; i < ChecksumMapEntries.Length; i++) { var checksumMapEntry = ChecksumMapEntries[i]; - Console.WriteLine($" Checksum Map Entry {i}"); - Console.WriteLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); - Console.WriteLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); + builder.AppendLine($" Checksum Map Entry {i}"); + builder.AppendLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); + builder.AppendLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print checksum entries information /// - private void PrintChecksumEntries() + /// StringBuilder to append information to + private void PrintChecksumEntries(StringBuilder builder) { - Console.WriteLine(" Checksum Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Checksum Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (ChecksumEntries == null || ChecksumEntries.Length == 0) { - Console.WriteLine(" No checksum entries"); + builder.AppendLine(" No checksum entries"); } else { for (int i = 0; i < ChecksumEntries.Length; i++) { var checksumEntry = ChecksumEntries[i]; - Console.WriteLine($" Checksum Entry {i}"); - Console.WriteLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); + builder.AppendLine($" Checksum Entry {i}"); + builder.AppendLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print data block header information /// - private void PrintDataBlockHeader() + /// StringBuilder to append information to + private void PrintDataBlockHeader(StringBuilder builder) { - Console.WriteLine(" Data Block Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Last version played: {DBH_LastVersionPlayed} (0x{DBH_LastVersionPlayed:X})"); - Console.WriteLine($" Block count: {DBH_BlockCount} (0x{DBH_BlockCount:X})"); - Console.WriteLine($" Block size: {DBH_BlockSize} (0x{DBH_BlockSize:X})"); - Console.WriteLine($" First block offset: {DBH_FirstBlockOffset} (0x{DBH_FirstBlockOffset:X})"); - Console.WriteLine($" Blocks used: {DBH_BlocksUsed} (0x{DBH_BlocksUsed:X})"); - Console.WriteLine($" Checksum: {DBH_Checksum} (0x{DBH_Checksum:X})"); - Console.WriteLine(); + builder.AppendLine(" Data Block Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Last version played: {DBH_LastVersionPlayed} (0x{DBH_LastVersionPlayed:X})"); + builder.AppendLine($" Block count: {DBH_BlockCount} (0x{DBH_BlockCount:X})"); + builder.AppendLine($" Block size: {DBH_BlockSize} (0x{DBH_BlockSize:X})"); + builder.AppendLine($" First block offset: {DBH_FirstBlockOffset} (0x{DBH_FirstBlockOffset:X})"); + builder.AppendLine($" Blocks used: {DBH_BlocksUsed} (0x{DBH_BlocksUsed:X})"); + builder.AppendLine($" Checksum: {DBH_Checksum} (0x{DBH_Checksum:X})"); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/LinearExecutable.cs b/BurnOutSharp.Wrappers/LinearExecutable.cs index 6ec557a2..ccb9e6e5 100644 --- a/BurnOutSharp.Wrappers/LinearExecutable.cs +++ b/BurnOutSharp.Wrappers/LinearExecutable.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -348,431 +349,447 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("New Executable Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("New Executable Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Stub - PrintStubHeader(); - PrintStubExtendedHeader(); + PrintStubHeader(builder); + PrintStubExtendedHeader(builder); // Information Block - PrintInformationBlock(); + PrintInformationBlock(builder); // Tables - PrintObjectTable(); - PrintObjectPageMap(); - PrintResourceTable(); - PrintResidentNamesTable(); - PrintEntryTable(); - PrintModuleFormatDirectivesTable(); - PrintVerifyRecordDirectiveTable(); - PrintFixupPageTable(); - PrintFixupRecordTable(); - PrintImportModuleNameTable(); - PrintImportModuleProcedureNameTable(); - PrintPerPageChecksumTable(); - PrintNonResidentNamesTable(); + PrintObjectTable(builder); + PrintObjectPageMap(builder); + PrintResourceTable(builder); + PrintResidentNamesTable(builder); + PrintEntryTable(builder); + PrintModuleFormatDirectivesTable(builder); + PrintVerifyRecordDirectiveTable(builder); + PrintFixupPageTable(builder); + PrintFixupRecordTable(builder); + PrintImportModuleNameTable(builder); + PrintImportModuleProcedureNameTable(builder); + PrintPerPageChecksumTable(builder); + PrintNonResidentNamesTable(builder); // Debug - PrintDebugInformation(); + PrintDebugInformation(builder); + + return builder; } /// /// Print stub header information /// - private void PrintStubHeader() + /// StringBuilder to append information to + private void PrintStubHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {Stub_Magic}"); - Console.WriteLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); - Console.WriteLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); - Console.WriteLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); - Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); - Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); - Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); - Console.WriteLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); - Console.WriteLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); - Console.WriteLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); - Console.WriteLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); - Console.WriteLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); - Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); - Console.WriteLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic number: {Stub_Magic}"); + builder.AppendLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); + builder.AppendLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); + builder.AppendLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); + builder.AppendLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); + builder.AppendLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); + builder.AppendLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); + builder.AppendLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); + builder.AppendLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); + builder.AppendLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); + builder.AppendLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); + builder.AppendLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); + builder.AppendLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); + builder.AppendLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); + builder.AppendLine(); } /// /// Print stub extended header information /// - private void PrintStubExtendedHeader() + /// StringBuilder to append information to + private void PrintStubExtendedHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Extended Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); - Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); - Console.WriteLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); - Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Extended Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + builder.AppendLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); + builder.AppendLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + builder.AppendLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); + builder.AppendLine(); } /// /// Print information block information /// - private void PrintInformationBlock() + /// StringBuilder to append information to + private void PrintInformationBlock(StringBuilder builder) { - Console.WriteLine(" Information Block Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Byte order: {ByteOrder} (0x{ByteOrder:X})"); - Console.WriteLine($" Word order: {WordOrder} (0x{WordOrder:X})"); - Console.WriteLine($" Executable format level: {ExecutableFormatLevel} (0x{ExecutableFormatLevel:X})"); - Console.WriteLine($" CPU type: {CPUType} (0x{CPUType:X})"); - Console.WriteLine($" Module OS: {ModuleOS} (0x{ModuleOS:X})"); - Console.WriteLine($" Module version: {ModuleVersion} (0x{ModuleVersion:X})"); - Console.WriteLine($" Module type flags: {ModuleTypeFlags} (0x{ModuleTypeFlags:X})"); - Console.WriteLine($" Module number pages: {ModuleNumberPages} (0x{ModuleNumberPages:X})"); - Console.WriteLine($" Initial object CS: {InitialObjectCS} (0x{InitialObjectCS:X})"); - Console.WriteLine($" Initial EIP: {InitialEIP} (0x{InitialEIP:X})"); - Console.WriteLine($" Initial object SS: {InitialObjectSS} (0x{InitialObjectSS:X})"); - Console.WriteLine($" Initial ESP: {InitialESP} (0x{InitialESP:X})"); - Console.WriteLine($" Memory page size: {MemoryPageSize} (0x{MemoryPageSize:X})"); - Console.WriteLine($" Bytes on last page: {BytesOnLastPage} (0x{BytesOnLastPage:X})"); - Console.WriteLine($" Fix-up section size: {FixupSectionSize} (0x{FixupSectionSize:X})"); - Console.WriteLine($" Fix-up section checksum: {FixupSectionChecksum} (0x{FixupSectionChecksum:X})"); - Console.WriteLine($" Loader section size: {LoaderSectionSize} (0x{LoaderSectionSize:X})"); - Console.WriteLine($" Loader section checksum: {LoaderSectionChecksum} (0x{LoaderSectionChecksum:X})"); - Console.WriteLine($" Object table offset: {ObjectTableOffset} (0x{ObjectTableOffset:X})"); - Console.WriteLine($" Object table count: {ObjectTableCount} (0x{ObjectTableCount:X})"); - Console.WriteLine($" Object page map offset: {ObjectPageMapOffset} (0x{ObjectPageMapOffset:X})"); - Console.WriteLine($" Object iterate data map offset: {ObjectIterateDataMapOffset} (0x{ObjectIterateDataMapOffset:X})"); - Console.WriteLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); - Console.WriteLine($" Resource table count: {ResourceTableCount} (0x{ResourceTableCount:X})"); - Console.WriteLine($" Resident names table offset: {ResidentNamesTableOffset} (0x{ResidentNamesTableOffset:X})"); - Console.WriteLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); - Console.WriteLine($" Module directives table offset: {ModuleDirectivesTableOffset} (0x{ModuleDirectivesTableOffset:X})"); - Console.WriteLine($" Module directives table count: {ModuleDirectivesCount} (0x{ModuleDirectivesCount:X})"); - Console.WriteLine($" Fix-up page table offset: {FixupPageTableOffset} (0x{FixupPageTableOffset:X})"); - Console.WriteLine($" Fix-up record table offset: {FixupRecordTableOffset} (0x{FixupRecordTableOffset:X})"); - Console.WriteLine($" Imported modules name table offset: {ImportedModulesNameTableOffset} (0x{ImportedModulesNameTableOffset:X})"); - Console.WriteLine($" Imported modules count: {ImportedModulesCount} (0x{ImportedModulesCount:X})"); - Console.WriteLine($" Imported procedure name table count: {ImportProcedureNameTableOffset} (0x{ImportProcedureNameTableOffset:X})"); - Console.WriteLine($" Per-page checksum table offset: {PerPageChecksumTableOffset} (0x{PerPageChecksumTableOffset:X})"); - Console.WriteLine($" Data pages offset: {DataPagesOffset} (0x{DataPagesOffset:X})"); - Console.WriteLine($" Preload page count: {PreloadPageCount} (0x{PreloadPageCount:X})"); - Console.WriteLine($" Non-resident names table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); - Console.WriteLine($" Non-resident names table length: {NonResidentNamesTableLength} (0x{NonResidentNamesTableLength:X})"); - Console.WriteLine($" Non-resident names table checksum: {NonResidentNamesTableChecksum} (0x{NonResidentNamesTableChecksum:X})"); - Console.WriteLine($" Automatic data object: {AutomaticDataObject} (0x{AutomaticDataObject:X})"); - Console.WriteLine($" Debug information offset: {DebugInformationOffset} (0x{DebugInformationOffset:X})"); - Console.WriteLine($" Debug information length: {DebugInformationLength} (0x{DebugInformationLength:X})"); - Console.WriteLine($" Preload instance pages number: {PreloadInstancePagesNumber} (0x{PreloadInstancePagesNumber:X})"); - Console.WriteLine($" Demand instance pages number: {DemandInstancePagesNumber} (0x{DemandInstancePagesNumber:X})"); - Console.WriteLine($" Extra heap allocation: {ExtraHeapAllocation} (0x{ExtraHeapAllocation:X})"); - Console.WriteLine(); + builder.AppendLine(" Information Block Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Byte order: {ByteOrder} (0x{ByteOrder:X})"); + builder.AppendLine($" Word order: {WordOrder} (0x{WordOrder:X})"); + builder.AppendLine($" Executable format level: {ExecutableFormatLevel} (0x{ExecutableFormatLevel:X})"); + builder.AppendLine($" CPU type: {CPUType} (0x{CPUType:X})"); + builder.AppendLine($" Module OS: {ModuleOS} (0x{ModuleOS:X})"); + builder.AppendLine($" Module version: {ModuleVersion} (0x{ModuleVersion:X})"); + builder.AppendLine($" Module type flags: {ModuleTypeFlags} (0x{ModuleTypeFlags:X})"); + builder.AppendLine($" Module number pages: {ModuleNumberPages} (0x{ModuleNumberPages:X})"); + builder.AppendLine($" Initial object CS: {InitialObjectCS} (0x{InitialObjectCS:X})"); + builder.AppendLine($" Initial EIP: {InitialEIP} (0x{InitialEIP:X})"); + builder.AppendLine($" Initial object SS: {InitialObjectSS} (0x{InitialObjectSS:X})"); + builder.AppendLine($" Initial ESP: {InitialESP} (0x{InitialESP:X})"); + builder.AppendLine($" Memory page size: {MemoryPageSize} (0x{MemoryPageSize:X})"); + builder.AppendLine($" Bytes on last page: {BytesOnLastPage} (0x{BytesOnLastPage:X})"); + builder.AppendLine($" Fix-up section size: {FixupSectionSize} (0x{FixupSectionSize:X})"); + builder.AppendLine($" Fix-up section checksum: {FixupSectionChecksum} (0x{FixupSectionChecksum:X})"); + builder.AppendLine($" Loader section size: {LoaderSectionSize} (0x{LoaderSectionSize:X})"); + builder.AppendLine($" Loader section checksum: {LoaderSectionChecksum} (0x{LoaderSectionChecksum:X})"); + builder.AppendLine($" Object table offset: {ObjectTableOffset} (0x{ObjectTableOffset:X})"); + builder.AppendLine($" Object table count: {ObjectTableCount} (0x{ObjectTableCount:X})"); + builder.AppendLine($" Object page map offset: {ObjectPageMapOffset} (0x{ObjectPageMapOffset:X})"); + builder.AppendLine($" Object iterate data map offset: {ObjectIterateDataMapOffset} (0x{ObjectIterateDataMapOffset:X})"); + builder.AppendLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); + builder.AppendLine($" Resource table count: {ResourceTableCount} (0x{ResourceTableCount:X})"); + builder.AppendLine($" Resident names table offset: {ResidentNamesTableOffset} (0x{ResidentNamesTableOffset:X})"); + builder.AppendLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); + builder.AppendLine($" Module directives table offset: {ModuleDirectivesTableOffset} (0x{ModuleDirectivesTableOffset:X})"); + builder.AppendLine($" Module directives table count: {ModuleDirectivesCount} (0x{ModuleDirectivesCount:X})"); + builder.AppendLine($" Fix-up page table offset: {FixupPageTableOffset} (0x{FixupPageTableOffset:X})"); + builder.AppendLine($" Fix-up record table offset: {FixupRecordTableOffset} (0x{FixupRecordTableOffset:X})"); + builder.AppendLine($" Imported modules name table offset: {ImportedModulesNameTableOffset} (0x{ImportedModulesNameTableOffset:X})"); + builder.AppendLine($" Imported modules count: {ImportedModulesCount} (0x{ImportedModulesCount:X})"); + builder.AppendLine($" Imported procedure name table count: {ImportProcedureNameTableOffset} (0x{ImportProcedureNameTableOffset:X})"); + builder.AppendLine($" Per-page checksum table offset: {PerPageChecksumTableOffset} (0x{PerPageChecksumTableOffset:X})"); + builder.AppendLine($" Data pages offset: {DataPagesOffset} (0x{DataPagesOffset:X})"); + builder.AppendLine($" Preload page count: {PreloadPageCount} (0x{PreloadPageCount:X})"); + builder.AppendLine($" Non-resident names table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); + builder.AppendLine($" Non-resident names table length: {NonResidentNamesTableLength} (0x{NonResidentNamesTableLength:X})"); + builder.AppendLine($" Non-resident names table checksum: {NonResidentNamesTableChecksum} (0x{NonResidentNamesTableChecksum:X})"); + builder.AppendLine($" Automatic data object: {AutomaticDataObject} (0x{AutomaticDataObject:X})"); + builder.AppendLine($" Debug information offset: {DebugInformationOffset} (0x{DebugInformationOffset:X})"); + builder.AppendLine($" Debug information length: {DebugInformationLength} (0x{DebugInformationLength:X})"); + builder.AppendLine($" Preload instance pages number: {PreloadInstancePagesNumber} (0x{PreloadInstancePagesNumber:X})"); + builder.AppendLine($" Demand instance pages number: {DemandInstancePagesNumber} (0x{DemandInstancePagesNumber:X})"); + builder.AppendLine($" Extra heap allocation: {ExtraHeapAllocation} (0x{ExtraHeapAllocation:X})"); + builder.AppendLine(); } /// /// Print object table information /// - private void PrintObjectTable() + /// StringBuilder to append information to + private void PrintObjectTable(StringBuilder builder) { - Console.WriteLine(" Object Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Object Table Information:"); + builder.AppendLine(" -------------------------"); if (ObjectTable == null || ObjectTable.Length == 0) { - Console.WriteLine(" No object table entries"); + builder.AppendLine(" No object table entries"); } else { for (int i = 0; i < ObjectTable.Length; i++) { var entry = ObjectTable[i]; - Console.WriteLine($" Object Table Entry {i}"); - Console.WriteLine($" Virtual segment size: {entry.VirtualSegmentSize} (0x{entry.VirtualSegmentSize:X})"); - Console.WriteLine($" Relocation base address: {entry.RelocationBaseAddress} (0x{entry.RelocationBaseAddress:X})"); - Console.WriteLine($" Object flags: {entry.ObjectFlags} (0x{entry.ObjectFlags:X})"); - Console.WriteLine($" Page table index: {entry.PageTableIndex} (0x{entry.PageTableIndex:X})"); - Console.WriteLine($" Page table entries: {entry.PageTableEntries} (0x{entry.PageTableEntries:X})"); - Console.WriteLine($" Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); + builder.AppendLine($" Object Table Entry {i}"); + builder.AppendLine($" Virtual segment size: {entry.VirtualSegmentSize} (0x{entry.VirtualSegmentSize:X})"); + builder.AppendLine($" Relocation base address: {entry.RelocationBaseAddress} (0x{entry.RelocationBaseAddress:X})"); + builder.AppendLine($" Object flags: {entry.ObjectFlags} (0x{entry.ObjectFlags:X})"); + builder.AppendLine($" Page table index: {entry.PageTableIndex} (0x{entry.PageTableIndex:X})"); + builder.AppendLine($" Page table entries: {entry.PageTableEntries} (0x{entry.PageTableEntries:X})"); + builder.AppendLine($" Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print object page map information /// - private void PrintObjectPageMap() + /// StringBuilder to append information to + private void PrintObjectPageMap(StringBuilder builder) { - Console.WriteLine(" Object Page Map Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Object Page Map Information:"); + builder.AppendLine(" -------------------------"); if (ObjectPageMap == null || ObjectPageMap.Length == 0) { - Console.WriteLine(" No object page map entries"); + builder.AppendLine(" No object page map entries"); } else { for (int i = 0; i < ObjectPageMap.Length; i++) { var entry = ObjectPageMap[i]; - Console.WriteLine($" Object Page Map Entry {i}"); - Console.WriteLine($" Page data offset: {entry.PageDataOffset} (0x{entry.PageDataOffset:X})"); - Console.WriteLine($" Data size: {entry.DataSize} (0x{entry.DataSize:X})"); - Console.WriteLine($" Flags: {entry.Flags} (0x{entry.Flags:X})"); + builder.AppendLine($" Object Page Map Entry {i}"); + builder.AppendLine($" Page data offset: {entry.PageDataOffset} (0x{entry.PageDataOffset:X})"); + builder.AppendLine($" Data size: {entry.DataSize} (0x{entry.DataSize:X})"); + builder.AppendLine($" Flags: {entry.Flags} (0x{entry.Flags:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print resource table information /// - private void PrintResourceTable() + /// StringBuilder to append information to + private void PrintResourceTable(StringBuilder builder) { - Console.WriteLine(" Resource Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Resource Table Information:"); + builder.AppendLine(" -------------------------"); if (ResourceTable == null || ResourceTable.Length == 0) { - Console.WriteLine(" No resource table entries"); + builder.AppendLine(" No resource table entries"); } else { for (int i = 0; i < ResourceTable.Length; i++) { var entry = ResourceTable[i]; - Console.WriteLine($" Resource Table Entry {i}"); - Console.WriteLine($" Type ID: {entry.TypeID} (0x{entry.TypeID:X})"); - Console.WriteLine($" Name ID: {entry.NameID} (0x{entry.NameID:X})"); - Console.WriteLine($" Resource size: {entry.ResourceSize} (0x{entry.ResourceSize:X})"); - Console.WriteLine($" Object number: {entry.ObjectNumber} (0x{entry.ObjectNumber:X})"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Resource Table Entry {i}"); + builder.AppendLine($" Type ID: {entry.TypeID} (0x{entry.TypeID:X})"); + builder.AppendLine($" Name ID: {entry.NameID} (0x{entry.NameID:X})"); + builder.AppendLine($" Resource size: {entry.ResourceSize} (0x{entry.ResourceSize:X})"); + builder.AppendLine($" Object number: {entry.ObjectNumber} (0x{entry.ObjectNumber:X})"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print resident names table information /// - private void PrintResidentNamesTable() + /// StringBuilder to append information to + private void PrintResidentNamesTable(StringBuilder builder) { - Console.WriteLine(" Resident Names Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Resident Names Table Information:"); + builder.AppendLine(" -------------------------"); if (ResidentNamesTable == null || ResidentNamesTable.Length == 0) { - Console.WriteLine(" No resident names table entries"); + builder.AppendLine(" No resident names table entries"); } else { for (int i = 0; i < ResidentNamesTable.Length; i++) { var entry = ResidentNamesTable[i]; - Console.WriteLine($" Resident Names Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); - Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + builder.AppendLine($" Resident Names Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print entry table information /// - private void PrintEntryTable() + /// StringBuilder to append information to + private void PrintEntryTable(StringBuilder builder) { - Console.WriteLine(" Entry Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Entry Table Information:"); + builder.AppendLine(" -------------------------"); if (EntryTable == null || EntryTable.Length == 0) { - Console.WriteLine(" No entry table bundles"); + builder.AppendLine(" No entry table bundles"); } else { for (int i = 0; i < EntryTable.Length; i++) { var bundle = EntryTable[i]; - Console.WriteLine($" Entry Table Bundle {i}"); - Console.WriteLine($" Entries: {bundle.Entries} (0x{bundle.Entries:X})"); - Console.WriteLine($" Bundle type: {bundle.BundleType} (0x{bundle.BundleType:X})"); + builder.AppendLine($" Entry Table Bundle {i}"); + builder.AppendLine($" Entries: {bundle.Entries} (0x{bundle.Entries:X})"); + builder.AppendLine($" Bundle type: {bundle.BundleType} (0x{bundle.BundleType:X})"); if (bundle.TableEntries != null && bundle.TableEntries.Length != 0) { - Console.WriteLine(); - Console.WriteLine($" Entry Table Entries:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine($" Entry Table Entries:"); + builder.AppendLine(" -------------------------"); for (int j = 0; j < bundle.TableEntries.Length; j++) { var entry = bundle.TableEntries[j]; - Console.WriteLine($" Entry Table Entry {j}"); + builder.AppendLine($" Entry Table Entry {j}"); switch (bundle.BundleType & ~Models.LinearExecutable.BundleType.ParameterTypingInformationPresent) { case Models.LinearExecutable.BundleType.UnusedEntry: - Console.WriteLine($" Unused, empty entry"); + builder.AppendLine($" Unused, empty entry"); break; case Models.LinearExecutable.BundleType.SixteenBitEntry: - Console.WriteLine($" Object number: {entry.SixteenBitObjectNumber} (0x{entry.SixteenBitObjectNumber:X})"); - Console.WriteLine($" Entry flags: {entry.SixteenBitEntryFlags} (0x{entry.SixteenBitEntryFlags:X})"); - Console.WriteLine($" Offset: {entry.SixteenBitOffset} (0x{entry.SixteenBitOffset:X})"); + builder.AppendLine($" Object number: {entry.SixteenBitObjectNumber} (0x{entry.SixteenBitObjectNumber:X})"); + builder.AppendLine($" Entry flags: {entry.SixteenBitEntryFlags} (0x{entry.SixteenBitEntryFlags:X})"); + builder.AppendLine($" Offset: {entry.SixteenBitOffset} (0x{entry.SixteenBitOffset:X})"); break; case Models.LinearExecutable.BundleType.TwoEightySixCallGateEntry: - Console.WriteLine($" Object number: {entry.TwoEightySixObjectNumber} (0x{entry.TwoEightySixObjectNumber:X})"); - Console.WriteLine($" Entry flags: {entry.TwoEightySixEntryFlags} (0x{entry.TwoEightySixEntryFlags:X})"); - Console.WriteLine($" Offset: {entry.TwoEightySixOffset} (0x{entry.TwoEightySixOffset:X})"); - Console.WriteLine($" Callgate: {entry.TwoEightySixCallgate} (0x{entry.TwoEightySixCallgate:X})"); + builder.AppendLine($" Object number: {entry.TwoEightySixObjectNumber} (0x{entry.TwoEightySixObjectNumber:X})"); + builder.AppendLine($" Entry flags: {entry.TwoEightySixEntryFlags} (0x{entry.TwoEightySixEntryFlags:X})"); + builder.AppendLine($" Offset: {entry.TwoEightySixOffset} (0x{entry.TwoEightySixOffset:X})"); + builder.AppendLine($" Callgate: {entry.TwoEightySixCallgate} (0x{entry.TwoEightySixCallgate:X})"); break; case Models.LinearExecutable.BundleType.ThirtyTwoBitEntry: - Console.WriteLine($" Object number: {entry.ThirtyTwoBitObjectNumber} (0x{entry.ThirtyTwoBitObjectNumber:X})"); - Console.WriteLine($" Entry flags: {entry.ThirtyTwoBitEntryFlags} (0x{entry.ThirtyTwoBitEntryFlags:X})"); - Console.WriteLine($" Offset: {entry.ThirtyTwoBitOffset} (0x{entry.ThirtyTwoBitOffset:X})"); + builder.AppendLine($" Object number: {entry.ThirtyTwoBitObjectNumber} (0x{entry.ThirtyTwoBitObjectNumber:X})"); + builder.AppendLine($" Entry flags: {entry.ThirtyTwoBitEntryFlags} (0x{entry.ThirtyTwoBitEntryFlags:X})"); + builder.AppendLine($" Offset: {entry.ThirtyTwoBitOffset} (0x{entry.ThirtyTwoBitOffset:X})"); break; case Models.LinearExecutable.BundleType.ForwarderEntry: - Console.WriteLine($" Reserved: {entry.ForwarderReserved} (0x{entry.ForwarderReserved:X})"); - Console.WriteLine($" Forwarder flags: {entry.ForwarderFlags} (0x{entry.ForwarderFlags:X})"); - Console.WriteLine($" Module ordinal number: {entry.ForwarderModuleOrdinalNumber} (0x{entry.ForwarderModuleOrdinalNumber:X})"); - Console.WriteLine($" Procedure name offset: {entry.ProcedureNameOffset} (0x{entry.ProcedureNameOffset:X})"); - Console.WriteLine($" Import ordinal number: {entry.ImportOrdinalNumber} (0x{entry.ImportOrdinalNumber:X})"); + builder.AppendLine($" Reserved: {entry.ForwarderReserved} (0x{entry.ForwarderReserved:X})"); + builder.AppendLine($" Forwarder flags: {entry.ForwarderFlags} (0x{entry.ForwarderFlags:X})"); + builder.AppendLine($" Module ordinal number: {entry.ForwarderModuleOrdinalNumber} (0x{entry.ForwarderModuleOrdinalNumber:X})"); + builder.AppendLine($" Procedure name offset: {entry.ProcedureNameOffset} (0x{entry.ProcedureNameOffset:X})"); + builder.AppendLine($" Import ordinal number: {entry.ImportOrdinalNumber} (0x{entry.ImportOrdinalNumber:X})"); break; default: - Console.WriteLine($" Unknown entry type {bundle.BundleType}"); + builder.AppendLine($" Unknown entry type {bundle.BundleType}"); break; } } } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print module format directives table information /// - private void PrintModuleFormatDirectivesTable() + /// StringBuilder to append information to + private void PrintModuleFormatDirectivesTable(StringBuilder builder) { - Console.WriteLine(" Module Format Directives Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Module Format Directives Table Information:"); + builder.AppendLine(" -------------------------"); if (ModuleFormatDirectivesTable == null || ModuleFormatDirectivesTable.Length == 0) { - Console.WriteLine(" No module format directives table entries"); + builder.AppendLine(" No module format directives table entries"); } else { for (int i = 0; i < ModuleFormatDirectivesTable.Length; i++) { var entry = ModuleFormatDirectivesTable[i]; - Console.WriteLine($" Moduile Format Directives Table Entry {i}"); - Console.WriteLine($" Directive number: {entry.DirectiveNumber} (0x{entry.DirectiveNumber:X})"); - Console.WriteLine($" Directive data length: {entry.DirectiveDataLength} (0x{entry.DirectiveDataLength:X})"); - Console.WriteLine($" Directive data offset: {entry.DirectiveDataOffset} (0x{entry.DirectiveDataOffset:X})"); + builder.AppendLine($" Moduile Format Directives Table Entry {i}"); + builder.AppendLine($" Directive number: {entry.DirectiveNumber} (0x{entry.DirectiveNumber:X})"); + builder.AppendLine($" Directive data length: {entry.DirectiveDataLength} (0x{entry.DirectiveDataLength:X})"); + builder.AppendLine($" Directive data offset: {entry.DirectiveDataOffset} (0x{entry.DirectiveDataOffset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print verify record directive table information /// - private void PrintVerifyRecordDirectiveTable() + /// StringBuilder to append information to + private void PrintVerifyRecordDirectiveTable(StringBuilder builder) { - Console.WriteLine(" Verify Record Directive Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Verify Record Directive Table Information:"); + builder.AppendLine(" -------------------------"); if (VerifyRecordDirectiveTable == null || VerifyRecordDirectiveTable.Length == 0) { - Console.WriteLine(" No verify record directive table entries"); + builder.AppendLine(" No verify record directive table entries"); } else { for (int i = 0; i < VerifyRecordDirectiveTable.Length; i++) { var entry = VerifyRecordDirectiveTable[i]; - Console.WriteLine($" Verify Record Directive Table Entry {i}"); - Console.WriteLine($" Entry count: {entry.EntryCount} (0x{entry.EntryCount:X})"); - Console.WriteLine($" Ordinal index: {entry.OrdinalIndex} (0x{entry.OrdinalIndex:X})"); - Console.WriteLine($" Version: {entry.Version} (0x{entry.Version:X})"); - Console.WriteLine($" Object entries count: {entry.ObjectEntriesCount} (0x{entry.ObjectEntriesCount:X})"); - Console.WriteLine($" Object number in module: {entry.ObjectNumberInModule} (0x{entry.ObjectNumberInModule:X})"); - Console.WriteLine($" Object load base address: {entry.ObjectLoadBaseAddress} (0x{entry.ObjectLoadBaseAddress:X})"); - Console.WriteLine($" Object virtual address size: {entry.ObjectVirtualAddressSize} (0x{entry.ObjectVirtualAddressSize:X})"); + builder.AppendLine($" Verify Record Directive Table Entry {i}"); + builder.AppendLine($" Entry count: {entry.EntryCount} (0x{entry.EntryCount:X})"); + builder.AppendLine($" Ordinal index: {entry.OrdinalIndex} (0x{entry.OrdinalIndex:X})"); + builder.AppendLine($" Version: {entry.Version} (0x{entry.Version:X})"); + builder.AppendLine($" Object entries count: {entry.ObjectEntriesCount} (0x{entry.ObjectEntriesCount:X})"); + builder.AppendLine($" Object number in module: {entry.ObjectNumberInModule} (0x{entry.ObjectNumberInModule:X})"); + builder.AppendLine($" Object load base address: {entry.ObjectLoadBaseAddress} (0x{entry.ObjectLoadBaseAddress:X})"); + builder.AppendLine($" Object virtual address size: {entry.ObjectVirtualAddressSize} (0x{entry.ObjectVirtualAddressSize:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print fix-up page table information /// - private void PrintFixupPageTable() + /// StringBuilder to append information to + private void PrintFixupPageTable(StringBuilder builder) { - Console.WriteLine(" Fix-up Page Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Fix-up Page Table Information:"); + builder.AppendLine(" -------------------------"); if (FixupPageTable == null || FixupPageTable.Length == 0) { - Console.WriteLine(" No fix-up page table entries"); + builder.AppendLine(" No fix-up page table entries"); } else { for (int i = 0; i < FixupPageTable.Length; i++) { var entry = FixupPageTable[i]; - Console.WriteLine($" Fix-up Page Table Entry {i}"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Fix-up Page Table Entry {i}"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print fix-up record table information /// - private void PrintFixupRecordTable() + /// StringBuilder to append information to + private void PrintFixupRecordTable(StringBuilder builder) { - Console.WriteLine(" Fix-up Record Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Fix-up Record Table Information:"); + builder.AppendLine(" -------------------------"); if (FixupRecordTable == null || FixupRecordTable.Length == 0) { - Console.WriteLine(" No fix-up record table entries"); - Console.WriteLine(); + builder.AppendLine(" No fix-up record table entries"); + builder.AppendLine(); } else { for (int i = 0; i < FixupRecordTable.Length; i++) { var entry = FixupRecordTable[i]; - Console.WriteLine($" Fix-up Record Table Entry {i}"); - Console.WriteLine($" Source type: {entry.SourceType} (0x{entry.SourceType:X})"); - Console.WriteLine($" Target flags: {entry.TargetFlags} (0x{entry.TargetFlags:X})"); + builder.AppendLine($" Fix-up Record Table Entry {i}"); + builder.AppendLine($" Source type: {entry.SourceType} (0x{entry.SourceType:X})"); + builder.AppendLine($" Target flags: {entry.TargetFlags} (0x{entry.TargetFlags:X})"); // Source list flag if (entry.SourceType.HasFlag(Models.LinearExecutable.FixupRecordSourceType.SourceListFlag)) - Console.WriteLine($" Source offset list count: {entry.SourceOffsetListCount} (0x{entry.SourceOffsetListCount:X})"); + builder.AppendLine($" Source offset list count: {entry.SourceOffsetListCount} (0x{entry.SourceOffsetListCount:X})"); else - Console.WriteLine($" Source offset: {entry.SourceOffset} (0x{entry.SourceOffset:X})"); + builder.AppendLine($" Source offset: {entry.SourceOffset} (0x{entry.SourceOffset:X})"); // OBJECT / TRGOFF if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.InternalReference)) { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - Console.WriteLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); + builder.AppendLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); else - Console.WriteLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); + builder.AppendLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); // 16-bit Selector fixup if (!entry.SourceType.HasFlag(Models.LinearExecutable.FixupRecordSourceType.SixteenBitSelectorFixup)) { // 32-bit Target Offset Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - Console.WriteLine($" Target offset: {entry.TargetOffsetDWORD} (0x{entry.TargetOffsetDWORD:X})"); + builder.AppendLine($" Target offset: {entry.TargetOffsetDWORD} (0x{entry.TargetOffsetDWORD:X})"); else - Console.WriteLine($" Target offset: {entry.TargetOffsetWORD} (0x{entry.TargetOffsetWORD:X})"); + builder.AppendLine($" Target offset: {entry.TargetOffsetWORD} (0x{entry.TargetOffsetWORD:X})"); } } @@ -781,26 +798,26 @@ namespace BurnOutSharp.Wrappers { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); else - Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); // 8-bit Ordinal Flag & 32-bit Target Offset Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.EightBitOrdinalFlag)) - Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberByte} (0x{entry.ImportedOrdinalNumberByte:X})"); + builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberByte} (0x{entry.ImportedOrdinalNumberByte:X})"); else if (entry.TargetFlags.HasFlag(flag: Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberDWORD} (0x{entry.ImportedOrdinalNumberDWORD:X})"); + builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberDWORD} (0x{entry.ImportedOrdinalNumberDWORD:X})"); else - Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberWORD} (0x{entry.ImportedOrdinalNumberWORD:X})"); + builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberWORD} (0x{entry.ImportedOrdinalNumberWORD:X})"); // Additive Fixup Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } @@ -809,24 +826,24 @@ namespace BurnOutSharp.Wrappers { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); else - Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); // 32-bit Target Offset Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - Console.WriteLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableDWORD} (0x{entry.OffsetImportProcedureNameTableDWORD:X})"); + builder.AppendLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableDWORD} (0x{entry.OffsetImportProcedureNameTableDWORD:X})"); else - Console.WriteLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableWORD} (0x{entry.OffsetImportProcedureNameTableWORD:X})"); + builder.AppendLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableWORD} (0x{entry.OffsetImportProcedureNameTableWORD:X})"); // Additive Fixup Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } @@ -835,42 +852,42 @@ namespace BurnOutSharp.Wrappers { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - Console.WriteLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); + builder.AppendLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); else - Console.WriteLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); + builder.AppendLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); // Additive Fixup Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } // No other top-level flags recognized else { - Console.WriteLine($" Unknown entry format"); + builder.AppendLine($" Unknown entry format"); } - Console.WriteLine(); - Console.WriteLine($" Source Offset List:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine($" Source Offset List:"); + builder.AppendLine(" -------------------------"); if (entry.SourceOffsetList == null || entry.SourceOffsetList.Length == 0) { - Console.WriteLine($" No source offset list entries"); + builder.AppendLine($" No source offset list entries"); } else { for (int j = 0; j < entry.SourceOffsetList.Length; j++) { - Console.WriteLine($" Source Offset List Entry {j}: {entry.SourceOffsetList[j]} (0x{entry.SourceOffsetList[j]:X})"); + builder.AppendLine($" Source Offset List Entry {j}: {entry.SourceOffsetList[j]} (0x{entry.SourceOffsetList[j]:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } } } @@ -878,117 +895,122 @@ namespace BurnOutSharp.Wrappers /// /// Print import module name table information /// - private void PrintImportModuleNameTable() + /// StringBuilder to append information to + private void PrintImportModuleNameTable(StringBuilder builder) { - Console.WriteLine(" Import Module Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Import Module Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ImportModuleNameTable == null || ImportModuleNameTable.Length == 0) { - Console.WriteLine(" No import module name table entries"); + builder.AppendLine(" No import module name table entries"); } else { for (int i = 0; i < ImportModuleNameTable.Length; i++) { var entry = ImportModuleNameTable[i]; - Console.WriteLine($" Import Module Name Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" Import Module Name Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print import module procedure name table information /// - private void PrintImportModuleProcedureNameTable() + /// StringBuilder to append information to + private void PrintImportModuleProcedureNameTable(StringBuilder builder) { - Console.WriteLine(" Import Module Procedure Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Import Module Procedure Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ImportModuleProcedureNameTable == null || ImportModuleProcedureNameTable.Length == 0) { - Console.WriteLine(" No import module procedure name table entries"); + builder.AppendLine(" No import module procedure name table entries"); } else { for (int i = 0; i < ImportModuleProcedureNameTable.Length; i++) { var entry = ImportModuleProcedureNameTable[i]; - Console.WriteLine($" Import Module Procedure Name Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" Import Module Procedure Name Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print per-page checksum table information /// - private void PrintPerPageChecksumTable() + /// StringBuilder to append information to + private void PrintPerPageChecksumTable(StringBuilder builder) { - Console.WriteLine(" Per-Page Checksum Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Per-Page Checksum Table Information:"); + builder.AppendLine(" -------------------------"); if (PerPageChecksumTable == null || PerPageChecksumTable.Length == 0) { - Console.WriteLine(" No per-page checksum table entries"); + builder.AppendLine(" No per-page checksum table entries"); } else { for (int i = 0; i < PerPageChecksumTable.Length; i++) { var entry = PerPageChecksumTable[i]; - Console.WriteLine($" Per-Page Checksum Table Entry {i}"); - Console.WriteLine($" Checksum: {entry.Checksum} (0x{entry.Checksum:X})"); + builder.AppendLine($" Per-Page Checksum Table Entry {i}"); + builder.AppendLine($" Checksum: {entry.Checksum} (0x{entry.Checksum:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print non-resident names table information /// - private void PrintNonResidentNamesTable() + /// StringBuilder to append information to + private void PrintNonResidentNamesTable(StringBuilder builder) { - Console.WriteLine(" Non-Resident Names Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Non-Resident Names Table Information:"); + builder.AppendLine(" -------------------------"); if (NonResidentNamesTable == null || NonResidentNamesTable.Length == 0) { - Console.WriteLine(" No non-resident names table entries"); + builder.AppendLine(" No non-resident names table entries"); } else { for (int i = 0; i < NonResidentNamesTable.Length; i++) { var entry = NonResidentNamesTable[i]; - Console.WriteLine($" Non-Resident Names Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); - Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + builder.AppendLine($" Non-Resident Names Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print debug information /// - private void PrintDebugInformation() + /// StringBuilder to append information to + private void PrintDebugInformation(StringBuilder builder) { - Console.WriteLine(" Debug Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Debug Information:"); + builder.AppendLine(" -------------------------"); if (_executable.DebugInformation == null) { - Console.WriteLine(" No debug information"); + builder.AppendLine(" No debug information"); } else { - Console.WriteLine($" Signature: {DI_Signature ?? "[NULL]"}"); - Console.WriteLine($" Format type: {DI_FormatType} (0x{DI_FormatType:X})"); + builder.AppendLine($" Signature: {DI_Signature ?? "[NULL]"}"); + builder.AppendLine($" Format type: {DI_FormatType} (0x{DI_FormatType:X})"); // Debugger data } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/MSDOS.cs b/BurnOutSharp.Wrappers/MSDOS.cs index 12bc254e..8d159735 100644 --- a/BurnOutSharp.Wrappers/MSDOS.cs +++ b/BurnOutSharp.Wrappers/MSDOS.cs @@ -1,5 +1,5 @@ -using System; -using System.IO; +using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -147,61 +147,67 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("MS-DOS Executable Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintRelocationTable(); + builder.AppendLine("MS-DOS Executable Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintRelocationTable(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {Magic}"); - Console.WriteLine($" Last page bytes: {LastPageBytes} (0x{LastPageBytes:X})"); - Console.WriteLine($" Pages: {Pages} (0x{Pages:X})"); - Console.WriteLine($" Relocation items: {RelocationItems} (0x{RelocationItems:X})"); - Console.WriteLine($" Header paragraph size: {HeaderParagraphSize} (0x{HeaderParagraphSize:X})"); - Console.WriteLine($" Minimum extra paragraphs: {MinimumExtraParagraphs} (0x{MinimumExtraParagraphs:X})"); - Console.WriteLine($" Maximum extra paragraphs: {MaximumExtraParagraphs} (0x{MaximumExtraParagraphs:X})"); - Console.WriteLine($" Initial SS value: {InitialSSValue} (0x{InitialSSValue:X})"); - Console.WriteLine($" Initial SP value: {InitialSPValue} (0x{InitialSPValue:X})"); - Console.WriteLine($" Checksum: {Checksum} (0x{Checksum:X})"); - Console.WriteLine($" Initial IP value: {InitialIPValue} (0x{InitialIPValue:X})"); - Console.WriteLine($" Initial CS value: {InitialCSValue} (0x{InitialCSValue:X})"); - Console.WriteLine($" Relocation table address: {RelocationTableAddr} (0x{RelocationTableAddr:X})"); - Console.WriteLine($" Overlay number: {OverlayNumber} (0x{OverlayNumber:X})"); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic number: {Magic}"); + builder.AppendLine($" Last page bytes: {LastPageBytes} (0x{LastPageBytes:X})"); + builder.AppendLine($" Pages: {Pages} (0x{Pages:X})"); + builder.AppendLine($" Relocation items: {RelocationItems} (0x{RelocationItems:X})"); + builder.AppendLine($" Header paragraph size: {HeaderParagraphSize} (0x{HeaderParagraphSize:X})"); + builder.AppendLine($" Minimum extra paragraphs: {MinimumExtraParagraphs} (0x{MinimumExtraParagraphs:X})"); + builder.AppendLine($" Maximum extra paragraphs: {MaximumExtraParagraphs} (0x{MaximumExtraParagraphs:X})"); + builder.AppendLine($" Initial SS value: {InitialSSValue} (0x{InitialSSValue:X})"); + builder.AppendLine($" Initial SP value: {InitialSPValue} (0x{InitialSPValue:X})"); + builder.AppendLine($" Checksum: {Checksum} (0x{Checksum:X})"); + builder.AppendLine($" Initial IP value: {InitialIPValue} (0x{InitialIPValue:X})"); + builder.AppendLine($" Initial CS value: {InitialCSValue} (0x{InitialCSValue:X})"); + builder.AppendLine($" Relocation table address: {RelocationTableAddr} (0x{RelocationTableAddr:X})"); + builder.AppendLine($" Overlay number: {OverlayNumber} (0x{OverlayNumber:X})"); } /// /// Print relocation table information /// - private void PrintRelocationTable() + /// StringBuilder to append information to + private void PrintRelocationTable(StringBuilder builder) { - Console.WriteLine(" Relocation Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Relocation Table Information:"); + builder.AppendLine(" -------------------------"); if (RelocationItems == 0 || RelocationTable.Length == 0) { - Console.WriteLine(" No relocation table items"); + builder.AppendLine(" No relocation table items"); } else { for (int i = 0; i < RelocationTable.Length; i++) { var entry = RelocationTable[i]; - Console.WriteLine($" Relocation Table Entry {i}"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); - Console.WriteLine($" Segment: {entry.Segment} (0x{entry.Segment:X})"); + builder.AppendLine($" Relocation Table Entry {i}"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Segment: {entry.Segment} (0x{entry.Segment:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/MicrosoftCabinet.cs b/BurnOutSharp.Wrappers/MicrosoftCabinet.cs index 27114c2b..b8708823 100644 --- a/BurnOutSharp.Wrappers/MicrosoftCabinet.cs +++ b/BurnOutSharp.Wrappers/MicrosoftCabinet.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -396,145 +397,152 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("Microsoft Cabinet Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintFolders(); - PrintFiles(); + builder.AppendLine("Microsoft Cabinet Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintFolders(builder); + PrintFiles(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Reserved 1: {Reserved1} (0x{Reserved1:X})"); - Console.WriteLine($" Cabinet size: {CabinetSize} (0x{CabinetSize:X})"); - Console.WriteLine($" Reserved 2: {Reserved2} (0x{Reserved2:X})"); - Console.WriteLine($" Files offset: {FilesOffset} (0x{FilesOffset:X})"); - Console.WriteLine($" Reserved 3: {Reserved3} (0x{Reserved3:X})"); - Console.WriteLine($" Minor version: {VersionMinor} (0x{VersionMinor:X})"); - Console.WriteLine($" Major version: {VersionMajor} (0x{VersionMajor:X})"); - Console.WriteLine($" Folder count: {FolderCount} (0x{FolderCount:X})"); - Console.WriteLine($" File count: {FileCount} (0x{FileCount:X})"); - Console.WriteLine($" Flags: {Flags} (0x{Flags:X})"); - Console.WriteLine($" Set ID: {SetID} (0x{SetID:X})"); - Console.WriteLine($" Cabinet index: {CabinetIndex} (0x{CabinetIndex:X})"); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Reserved 1: {Reserved1} (0x{Reserved1:X})"); + builder.AppendLine($" Cabinet size: {CabinetSize} (0x{CabinetSize:X})"); + builder.AppendLine($" Reserved 2: {Reserved2} (0x{Reserved2:X})"); + builder.AppendLine($" Files offset: {FilesOffset} (0x{FilesOffset:X})"); + builder.AppendLine($" Reserved 3: {Reserved3} (0x{Reserved3:X})"); + builder.AppendLine($" Minor version: {VersionMinor} (0x{VersionMinor:X})"); + builder.AppendLine($" Major version: {VersionMajor} (0x{VersionMajor:X})"); + builder.AppendLine($" Folder count: {FolderCount} (0x{FolderCount:X})"); + builder.AppendLine($" File count: {FileCount} (0x{FileCount:X})"); + builder.AppendLine($" Flags: {Flags} (0x{Flags:X})"); + builder.AppendLine($" Set ID: {SetID} (0x{SetID:X})"); + builder.AppendLine($" Cabinet index: {CabinetIndex} (0x{CabinetIndex:X})"); if (Flags.HasFlag(Models.MicrosoftCabinet.HeaderFlags.RESERVE_PRESENT)) { - Console.WriteLine($" Header reserved size: {HeaderReservedSize} (0x{HeaderReservedSize:X})"); - Console.WriteLine($" Folder reserved size: {FolderReservedSize} (0x{FolderReservedSize:X})"); - Console.WriteLine($" Data reserved size: {DataReservedSize} (0x{DataReservedSize:X})"); + builder.AppendLine($" Header reserved size: {HeaderReservedSize} (0x{HeaderReservedSize:X})"); + builder.AppendLine($" Folder reserved size: {FolderReservedSize} (0x{FolderReservedSize:X})"); + builder.AppendLine($" Data reserved size: {DataReservedSize} (0x{DataReservedSize:X})"); if (ReservedData == null) - Console.WriteLine($" Reserved data = [NULL]"); + builder.AppendLine($" Reserved data = [NULL]"); else - Console.WriteLine($" Reserved data = {BitConverter.ToString(ReservedData).Replace("-", " ")}"); + builder.AppendLine($" Reserved data = {BitConverter.ToString(ReservedData).Replace("-", " ")}"); } if (Flags.HasFlag(Models.MicrosoftCabinet.HeaderFlags.PREV_CABINET)) { - Console.WriteLine($" Previous cabinet: {CabinetPrev}"); - Console.WriteLine($" Previous disk: {DiskPrev}"); + builder.AppendLine($" Previous cabinet: {CabinetPrev}"); + builder.AppendLine($" Previous disk: {DiskPrev}"); } if (Flags.HasFlag(Models.MicrosoftCabinet.HeaderFlags.NEXT_CABINET)) { - Console.WriteLine($" Next cabinet: {CabinetNext}"); - Console.WriteLine($" Next disk: {DiskNext}"); + builder.AppendLine($" Next cabinet: {CabinetNext}"); + builder.AppendLine($" Next disk: {DiskNext}"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print folders information /// - private void PrintFolders() + /// StringBuilder to append information to + private void PrintFolders(StringBuilder builder) { - Console.WriteLine(" Folders:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Folders:"); + builder.AppendLine(" -------------------------"); if (FolderCount == 0 || Folders == null || Folders.Length == 0) { - Console.WriteLine(" No folders"); + builder.AppendLine(" No folders"); } else { for (int i = 0; i < Folders.Length; i++) { var entry = Folders[i]; - Console.WriteLine($" Folder {i}"); - Console.WriteLine($" Cab start offset = {entry.CabStartOffset} (0x{entry.CabStartOffset:X})"); - Console.WriteLine($" Data count = {entry.DataCount} (0x{entry.DataCount:X})"); - Console.WriteLine($" Compression type = {entry.CompressionType} (0x{entry.CompressionType:X})"); - Console.WriteLine($" Masked compression type = {entry.CompressionType & Models.MicrosoftCabinet.CompressionType.MASK_TYPE}"); + builder.AppendLine($" Folder {i}"); + builder.AppendLine($" Cab start offset = {entry.CabStartOffset} (0x{entry.CabStartOffset:X})"); + builder.AppendLine($" Data count = {entry.DataCount} (0x{entry.DataCount:X})"); + builder.AppendLine($" Compression type = {entry.CompressionType} (0x{entry.CompressionType:X})"); + builder.AppendLine($" Masked compression type = {entry.CompressionType & Models.MicrosoftCabinet.CompressionType.MASK_TYPE}"); if (entry.ReservedData == null) - Console.WriteLine($" Reserved data = [NULL]"); + builder.AppendLine($" Reserved data = [NULL]"); else - Console.WriteLine($" Reserved data = {BitConverter.ToString(entry.ReservedData).Replace("-", " ")}"); - Console.WriteLine(); + builder.AppendLine($" Reserved data = {BitConverter.ToString(entry.ReservedData).Replace("-", " ")}"); + builder.AppendLine(); - Console.WriteLine(" Data Blocks"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Data Blocks"); + builder.AppendLine(" -------------------------"); if (entry.DataBlocks == null || entry.DataBlocks.Length == 0) { - Console.WriteLine(" No data blocks"); + builder.AppendLine(" No data blocks"); } else { for (int j = 0; j < entry.DataBlocks.Length; j++) { Models.MicrosoftCabinet.CFDATA dataBlock = entry.DataBlocks[j]; - Console.WriteLine($" Data Block {j}"); - Console.WriteLine($" Checksum = {dataBlock.Checksum} (0x{dataBlock.Checksum:X})"); - Console.WriteLine($" Compressed size = {dataBlock.CompressedSize} (0x{dataBlock.CompressedSize:X})"); - Console.WriteLine($" Uncompressed size = {dataBlock.UncompressedSize} (0x{dataBlock.UncompressedSize:X})"); + builder.AppendLine($" Data Block {j}"); + builder.AppendLine($" Checksum = {dataBlock.Checksum} (0x{dataBlock.Checksum:X})"); + builder.AppendLine($" Compressed size = {dataBlock.CompressedSize} (0x{dataBlock.CompressedSize:X})"); + builder.AppendLine($" Uncompressed size = {dataBlock.UncompressedSize} (0x{dataBlock.UncompressedSize:X})"); if (dataBlock.ReservedData == null) - Console.WriteLine($" Reserved data = [NULL]"); + builder.AppendLine($" Reserved data = [NULL]"); else - Console.WriteLine($" Reserved data = {BitConverter.ToString(dataBlock.ReservedData).Replace("-", " ")}"); - //Console.WriteLine($" Compressed data = {BitConverter.ToString(dataBlock.CompressedData).Replace("-", " ")}"); + builder.AppendLine($" Reserved data = {BitConverter.ToString(dataBlock.ReservedData).Replace("-", " ")}"); + //builder.AppendLine($" Compressed data = {BitConverter.ToString(dataBlock.CompressedData).Replace("-", " ")}"); } } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print files information /// - private void PrintFiles() + /// StringBuilder to append information to + private void PrintFiles(StringBuilder builder) { - Console.WriteLine(" Files:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Files:"); + builder.AppendLine(" -------------------------"); if (FileCount == 0 || Files == null || Files.Length == 0) { - Console.WriteLine(" No files"); + builder.AppendLine(" No files"); } else { for (int i = 0; i < Files.Length; i++) { var entry = Files[i]; - Console.WriteLine($" File {i}"); - Console.WriteLine($" File size = {entry.FileSize} (0x{entry.FileSize:X})"); - Console.WriteLine($" Folder start offset = {entry.FolderStartOffset} (0x{entry.FolderStartOffset:X})"); - Console.WriteLine($" Folder index = {entry.FolderIndex} (0x{entry.FolderIndex:X})"); - Console.WriteLine($" Date = {entry.Date} (0x{entry.Date:X})"); - Console.WriteLine($" Time = {entry.Time} (0x{entry.Time:X})"); - Console.WriteLine($" Attributes = {entry.Attributes} (0x{entry.Attributes:X})"); - Console.WriteLine($" Name = {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" File {i}"); + builder.AppendLine($" File size = {entry.FileSize} (0x{entry.FileSize:X})"); + builder.AppendLine($" Folder start offset = {entry.FolderStartOffset} (0x{entry.FolderStartOffset:X})"); + builder.AppendLine($" Folder index = {entry.FolderIndex} (0x{entry.FolderIndex:X})"); + builder.AppendLine($" Date = {entry.Date} (0x{entry.Date:X})"); + builder.AppendLine($" Time = {entry.Time} (0x{entry.Time:X})"); + builder.AppendLine($" Attributes = {entry.Attributes} (0x{entry.Attributes:X})"); + builder.AppendLine($" Name = {entry.Name ?? "[NULL]"}"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/N3DS.cs b/BurnOutSharp.Wrappers/N3DS.cs index 634e26a9..e2559bdb 100644 --- a/BurnOutSharp.Wrappers/N3DS.cs +++ b/BurnOutSharp.Wrappers/N3DS.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -279,465 +280,476 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("3DS Cart Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintNCSDHeader(); - PrintCardInfoHeader(); - PrintDevelopmentCardInfoHeader(); - PrintPartitions(); - PrintExtendedHeaders(); - PrintExeFSHeaders(); - PrintRomFSHeaders(); + builder.AppendLine("3DS Cart Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintNCSDHeader(builder); + PrintCardInfoHeader(builder); + PrintDevelopmentCardInfoHeader(builder); + PrintPartitions(builder); + PrintExtendedHeaders(builder); + PrintExeFSHeaders(builder); + PrintRomFSHeaders(builder); + + return builder; } /// /// Print NCSD header information /// - private void PrintNCSDHeader() + /// StringBuilder to append information to + private void PrintNCSDHeader(StringBuilder builder) { - Console.WriteLine(" NCSD Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(RSA2048Signature).Replace('-', ' ')}"); - Console.WriteLine($" Magic number: {MagicNumber} (0x{MagicNumber:X})"); - Console.WriteLine($" Image size in media units: {ImageSizeInMediaUnits} (0x{ImageSizeInMediaUnits:X})"); - Console.WriteLine($" Media ID: {BitConverter.ToString(MediaId).Replace('-', ' ')}"); - Console.WriteLine($" Partitions filesystem type: {PartitionsFSType} (0x{PartitionsFSType:X})"); - Console.WriteLine($" Partitions crypt type: {BitConverter.ToString(PartitionsCryptType).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" NCSD Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(RSA2048Signature).Replace('-', ' ')}"); + builder.AppendLine($" Magic number: {MagicNumber} (0x{MagicNumber:X})"); + builder.AppendLine($" Image size in media units: {ImageSizeInMediaUnits} (0x{ImageSizeInMediaUnits:X})"); + builder.AppendLine($" Media ID: {BitConverter.ToString(MediaId).Replace('-', ' ')}"); + builder.AppendLine($" Partitions filesystem type: {PartitionsFSType} (0x{PartitionsFSType:X})"); + builder.AppendLine($" Partitions crypt type: {BitConverter.ToString(PartitionsCryptType).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine($" Partition table:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Partition table:"); + builder.AppendLine(" -------------------------"); for (int i = 0; i < PartitionsTable.Length; i++) { var partitionTableEntry = PartitionsTable[i]; - Console.WriteLine($" Partition table entry {i}"); - Console.WriteLine($" Offset: {partitionTableEntry.Offset} (0x{partitionTableEntry.Offset:X})"); - Console.WriteLine($" Length: {partitionTableEntry.Length} (0x{partitionTableEntry.Length:X})"); + builder.AppendLine($" Partition table entry {i}"); + builder.AppendLine($" Offset: {partitionTableEntry.Offset} (0x{partitionTableEntry.Offset:X})"); + builder.AppendLine($" Length: {partitionTableEntry.Length} (0x{partitionTableEntry.Length:X})"); } - Console.WriteLine(); + builder.AppendLine(); // If we have a cart image if (PartitionsFSType == Models.N3DS.FilesystemType.Normal || PartitionsFSType == Models.N3DS.FilesystemType.None) { - Console.WriteLine($" Exheader SHA-256 hash: {BitConverter.ToString(ExheaderHash).Replace('-', ' ')}"); - Console.WriteLine($" Additional header size: {AdditionalHeaderSize} (0x{AdditionalHeaderSize:X})"); - Console.WriteLine($" Sector zero offset: {SectorZeroOffset} (0x{SectorZeroOffset:X})"); - Console.WriteLine($" Partition flags: {BitConverter.ToString(PartitionFlags).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine($" Exheader SHA-256 hash: {BitConverter.ToString(ExheaderHash).Replace('-', ' ')}"); + builder.AppendLine($" Additional header size: {AdditionalHeaderSize} (0x{AdditionalHeaderSize:X})"); + builder.AppendLine($" Sector zero offset: {SectorZeroOffset} (0x{SectorZeroOffset:X})"); + builder.AppendLine($" Partition flags: {BitConverter.ToString(PartitionFlags).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine($" Partition ID table:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Partition ID table:"); + builder.AppendLine(" -------------------------"); for (int i = 0; i < PartitionIdTable.Length; i++) { - Console.WriteLine($" Partition {i} ID: {PartitionIdTable[i]} (0x{PartitionIdTable[i]:X})"); + builder.AppendLine($" Partition {i} ID: {PartitionIdTable[i]} (0x{PartitionIdTable[i]:X})"); } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine($" Reserved 1: {BitConverter.ToString(Reserved1).Replace('-', ' ')}"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Firmware update byte 1: {FirmUpdateByte1} (0x{FirmUpdateByte1:X})"); - Console.WriteLine($" Firmware update byte 2: {FirmUpdateByte2} (0x{FirmUpdateByte2:X})"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Firmware update byte 1: {FirmUpdateByte1} (0x{FirmUpdateByte1:X})"); + builder.AppendLine($" Firmware update byte 2: {FirmUpdateByte2} (0x{FirmUpdateByte2:X})"); } // If we have a firmware image else if (PartitionsFSType == Models.N3DS.FilesystemType.FIRM) { - Console.WriteLine($" Unknown: {BitConverter.ToString(Unknown).Replace('-', ' ')}"); - Console.WriteLine($" Encrypted MBR: {BitConverter.ToString(EncryptedMBR).Replace('-', ' ')}"); + builder.AppendLine($" Unknown: {BitConverter.ToString(Unknown).Replace('-', ' ')}"); + builder.AppendLine($" Encrypted MBR: {BitConverter.ToString(EncryptedMBR).Replace('-', ' ')}"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print card info header information /// - private void PrintCardInfoHeader() + /// StringBuilder to append information to + private void PrintCardInfoHeader(StringBuilder builder) { - Console.WriteLine(" Card Info Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Writable address in media units: {CIH_WritableAddressMediaUnits} (0x{CIH_WritableAddressMediaUnits:X})"); - Console.WriteLine($" Card info bitmask: {CIH_CardInfoBitmask} (0x{CIH_CardInfoBitmask:X})"); - Console.WriteLine($" Reserved 1: {BitConverter.ToString(CIH_Reserved1).Replace('-', ' ')}"); - Console.WriteLine($" Filled size of cartridge: {CIH_FilledSize} (0x{CIH_FilledSize:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(CIH_Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Title version: {CIH_TitleVersion} (0x{CIH_TitleVersion:X})"); - Console.WriteLine($" Card revision: {CIH_CardRevision} (0x{CIH_CardRevision:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(CIH_Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" Title ID of CVer in included update partition: {BitConverter.ToString(CIH_CVerTitleID).Replace('-', ' ')}"); - Console.WriteLine($" Version number of CVer in included update partition: {CIH_CVerVersionNumber} (0x{CIH_CVerVersionNumber:X})"); - Console.WriteLine($" Reserved 4: {BitConverter.ToString(CIH_Reserved4).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" Card Info Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Writable address in media units: {CIH_WritableAddressMediaUnits} (0x{CIH_WritableAddressMediaUnits:X})"); + builder.AppendLine($" Card info bitmask: {CIH_CardInfoBitmask} (0x{CIH_CardInfoBitmask:X})"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(CIH_Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Filled size of cartridge: {CIH_FilledSize} (0x{CIH_FilledSize:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(CIH_Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Title version: {CIH_TitleVersion} (0x{CIH_TitleVersion:X})"); + builder.AppendLine($" Card revision: {CIH_CardRevision} (0x{CIH_CardRevision:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(CIH_Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" Title ID of CVer in included update partition: {BitConverter.ToString(CIH_CVerTitleID).Replace('-', ' ')}"); + builder.AppendLine($" Version number of CVer in included update partition: {CIH_CVerVersionNumber} (0x{CIH_CVerVersionNumber:X})"); + builder.AppendLine($" Reserved 4: {BitConverter.ToString(CIH_Reserved4).Replace('-', ' ')}"); + builder.AppendLine(); } /// /// Print development card info header information /// - private void PrintDevelopmentCardInfoHeader() + /// StringBuilder to append information to + private void PrintDevelopmentCardInfoHeader(StringBuilder builder) { - Console.WriteLine(" Development Card Info Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Development Card Info Header Information:"); + builder.AppendLine(" -------------------------"); if (_cart.DevelopmentCardInfoHeader == null) { - Console.WriteLine(" No development card info header"); + builder.AppendLine(" No development card info header"); } else { - Console.WriteLine(); - Console.WriteLine(" Initial Data:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Card seed keyY: {BitConverter.ToString(DCIH_ID_CardSeedKeyY).Replace('-', ' ')}"); - Console.WriteLine($" Encrypted card seed: {BitConverter.ToString(DCIH_ID_EncryptedCardSeed).Replace('-', ' ')}"); - 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(); + builder.AppendLine(); + builder.AppendLine(" Initial Data:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Card seed keyY: {BitConverter.ToString(DCIH_ID_CardSeedKeyY).Replace('-', ' ')}"); + builder.AppendLine($" Encrypted card seed: {BitConverter.ToString(DCIH_ID_EncryptedCardSeed).Replace('-', ' ')}"); + builder.AppendLine($" Card seed AES-MAC: {BitConverter.ToString(DCIH_ID_CardSeedAESMAC).Replace('-', ' ')}"); + builder.AppendLine($" Card seed nonce: {BitConverter.ToString(DCIH_ID_CardSeedNonce).Replace('-', ' ')}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(DCIH_ID_Reserved).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine(" Backup Header:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic ID: {DCIH_ID_BackupHeader.MagicID} (0x{DCIH_ID_BackupHeader.MagicID:X})"); - Console.WriteLine($" Content size in media units: {DCIH_ID_BackupHeader.ContentSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ContentSizeInMediaUnits:X})"); - Console.WriteLine($" Partition ID: {DCIH_ID_BackupHeader.PartitionId} (0x{DCIH_ID_BackupHeader.PartitionId:X})"); - Console.WriteLine($" Maker code: {DCIH_ID_BackupHeader.MakerCode} (0x{DCIH_ID_BackupHeader.MakerCode:X})"); - Console.WriteLine($" Version: {DCIH_ID_BackupHeader.Version} (0x{DCIH_ID_BackupHeader.Version:X})"); - Console.WriteLine($" Verification hash: {DCIH_ID_BackupHeader.VerificationHash} (0x{DCIH_ID_BackupHeader.VerificationHash:X})"); - 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} (0x{DCIH_ID_BackupHeader.ProductCode:X})"); - 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} (0x{DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Flags: {DCIH_ID_BackupHeader.Flags} (0x{DCIH_ID_BackupHeader.Flags:X})"); - Console.WriteLine($" Plain region offset, in media units: {DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Plain region size, in media units: {DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Logo region offset, in media units: {DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Logo region size, in media units: {DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS offset, in media units: {DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits:X})"); - Console.WriteLine($" ExeFS size, in media units: {DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS hash region size, in media units: {DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" RomFS offset, in media units: {DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits:X})"); - Console.WriteLine($" RomFS size, in media units: {DCIH_ID_BackupHeader.RomFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSSizeInMediaUnits:X})"); - Console.WriteLine($" RomFS hash region size, in media units: {DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits:X})"); - 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('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" Backup Header:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic ID: {DCIH_ID_BackupHeader.MagicID} (0x{DCIH_ID_BackupHeader.MagicID:X})"); + builder.AppendLine($" Content size in media units: {DCIH_ID_BackupHeader.ContentSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ContentSizeInMediaUnits:X})"); + builder.AppendLine($" Partition ID: {DCIH_ID_BackupHeader.PartitionId} (0x{DCIH_ID_BackupHeader.PartitionId:X})"); + builder.AppendLine($" Maker code: {DCIH_ID_BackupHeader.MakerCode} (0x{DCIH_ID_BackupHeader.MakerCode:X})"); + builder.AppendLine($" Version: {DCIH_ID_BackupHeader.Version} (0x{DCIH_ID_BackupHeader.Version:X})"); + builder.AppendLine($" Verification hash: {DCIH_ID_BackupHeader.VerificationHash} (0x{DCIH_ID_BackupHeader.VerificationHash:X})"); + builder.AppendLine($" Program ID: {BitConverter.ToString(DCIH_ID_BackupHeader.ProgramId).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Logo region SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.LogoRegionHash).Replace('-', ' ')}"); + builder.AppendLine($" Product code: {DCIH_ID_BackupHeader.ProductCode} (0x{DCIH_ID_BackupHeader.ProductCode:X})"); + builder.AppendLine($" Extended header SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.ExtendedHeaderHash).Replace('-', ' ')}"); + builder.AppendLine($" Extended header size in bytes: {DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes} (0x{DCIH_ID_BackupHeader.ExtendedHeaderSizeInBytes:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Flags: {DCIH_ID_BackupHeader.Flags} (0x{DCIH_ID_BackupHeader.Flags:X})"); + builder.AppendLine($" Plain region offset, in media units: {DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Plain region size, in media units: {DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.PlainRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Logo region offset, in media units: {DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Logo region size, in media units: {DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.LogoRegionSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS offset, in media units: {DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSOffsetInMediaUnits:X})"); + builder.AppendLine($" ExeFS size, in media units: {DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS hash region size, in media units: {DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.ExeFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" RomFS offset, in media units: {DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSOffsetInMediaUnits:X})"); + builder.AppendLine($" RomFS size, in media units: {DCIH_ID_BackupHeader.RomFSSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSSizeInMediaUnits:X})"); + builder.AppendLine($" RomFS hash region size, in media units: {DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits} (0x{DCIH_ID_BackupHeader.RomFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 4: {BitConverter.ToString(DCIH_ID_BackupHeader.Reserved4).Replace('-', ' ')}"); + builder.AppendLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.ExeFSSuperblockHash).Replace('-', ' ')}"); + builder.AppendLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(DCIH_ID_BackupHeader.RomFSSuperblockHash).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine($" Card device reserved 1: {BitConverter.ToString(DCIH_CardDeviceReserved1).Replace('-', ' ')}"); - Console.WriteLine($" Title key: {BitConverter.ToString(DCIH_TitleKey).Replace('-', ' ')}"); - Console.WriteLine($" Card device reserved 2: {BitConverter.ToString(DCIH_CardDeviceReserved2).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine($" Card device reserved 1: {BitConverter.ToString(DCIH_CardDeviceReserved1).Replace('-', ' ')}"); + builder.AppendLine($" Title key: {BitConverter.ToString(DCIH_TitleKey).Replace('-', ' ')}"); + builder.AppendLine($" Card device reserved 2: {BitConverter.ToString(DCIH_CardDeviceReserved2).Replace('-', ' ')}"); + builder.AppendLine(); - Console.WriteLine(" Test Data:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {BitConverter.ToString(DCIH_TD_Signature).Replace('-', ' ')}"); - Console.WriteLine($" Ascending byte sequence: {BitConverter.ToString(DCIH_TD_AscendingByteSequence).Replace('-', ' ')}"); - Console.WriteLine($" Descending byte sequence: {BitConverter.ToString(DCIH_TD_DescendingByteSequence).Replace('-', ' ')}"); - Console.WriteLine($" Filled with 00: {BitConverter.ToString(DCIH_TD_Filled00).Replace('-', ' ')}"); - Console.WriteLine($" Filled with FF: {BitConverter.ToString(DCIH_TD_FilledFF).Replace('-', ' ')}"); - Console.WriteLine($" Filled with 0F: {BitConverter.ToString(DCIH_TD_Filled0F).Replace('-', ' ')}"); - Console.WriteLine($" Filled with F0: {BitConverter.ToString(DCIH_TD_FilledF0).Replace('-', ' ')}"); - Console.WriteLine($" Filled with 55: {BitConverter.ToString(DCIH_TD_Filled55).Replace('-', ' ')}"); - Console.WriteLine($" Filled with AA: {BitConverter.ToString(DCIH_TD_FilledAA).Replace('-', ' ')}"); - Console.WriteLine($" Final byte: {DCIH_TD_FinalByte}"); + builder.AppendLine(" Test Data:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {BitConverter.ToString(DCIH_TD_Signature).Replace('-', ' ')}"); + builder.AppendLine($" Ascending byte sequence: {BitConverter.ToString(DCIH_TD_AscendingByteSequence).Replace('-', ' ')}"); + builder.AppendLine($" Descending byte sequence: {BitConverter.ToString(DCIH_TD_DescendingByteSequence).Replace('-', ' ')}"); + builder.AppendLine($" Filled with 00: {BitConverter.ToString(DCIH_TD_Filled00).Replace('-', ' ')}"); + builder.AppendLine($" Filled with FF: {BitConverter.ToString(DCIH_TD_FilledFF).Replace('-', ' ')}"); + builder.AppendLine($" Filled with 0F: {BitConverter.ToString(DCIH_TD_Filled0F).Replace('-', ' ')}"); + builder.AppendLine($" Filled with F0: {BitConverter.ToString(DCIH_TD_FilledF0).Replace('-', ' ')}"); + builder.AppendLine($" Filled with 55: {BitConverter.ToString(DCIH_TD_Filled55).Replace('-', ' ')}"); + builder.AppendLine($" Filled with AA: {BitConverter.ToString(DCIH_TD_FilledAA).Replace('-', ' ')}"); + builder.AppendLine($" Final byte: {DCIH_TD_FinalByte}"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print NCCH partition header information /// - private void PrintPartitions() + /// StringBuilder to append information to + private void PrintPartitions(StringBuilder builder) { - Console.WriteLine(" NCCH Partition Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" NCCH Partition Header Information:"); + builder.AppendLine(" -------------------------"); if (Partitions == null || Partitions.Length == 0) { - Console.WriteLine(" No NCCH partition headers"); + builder.AppendLine(" No NCCH partition headers"); } else { for (int i = 0; i < Partitions.Length; i++) { var partitionHeader = Partitions[i]; - Console.WriteLine($" NCCH Partition Header {i}"); + builder.AppendLine($" NCCH Partition Header {i}"); if (partitionHeader.MagicID == string.Empty) { - Console.WriteLine($" Empty partition, no data can be parsed"); + builder.AppendLine($" 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"); + builder.AppendLine($" 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} (0x{partitionHeader.MagicID:X})"); - Console.WriteLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits} (0x{partitionHeader.ContentSizeInMediaUnits:X})"); - Console.WriteLine($" Partition ID: {partitionHeader.PartitionId} (0x{partitionHeader.PartitionId:X})"); - Console.WriteLine($" Maker code: {partitionHeader.MakerCode} (0x{partitionHeader.MakerCode:X})"); - Console.WriteLine($" Version: {partitionHeader.Version} (0x{partitionHeader.Version:X})"); - Console.WriteLine($" Verification hash: {partitionHeader.VerificationHash} (0x{partitionHeader.VerificationHash:X})"); - 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} (0x{partitionHeader.ProductCode:X})"); - Console.WriteLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}"); - Console.WriteLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}"); - Console.WriteLine(" Flags:"); - Console.WriteLine($" Reserved 0: {partitionHeader.Flags.Reserved0} (0x{partitionHeader.Flags.Reserved0:X})"); - Console.WriteLine($" Reserved 1: {partitionHeader.Flags.Reserved1} (0x{partitionHeader.Flags.Reserved1:X})"); - Console.WriteLine($" Reserved 2: {partitionHeader.Flags.Reserved2} (0x{partitionHeader.Flags.Reserved2:X})"); - Console.WriteLine($" Crypto method: {partitionHeader.Flags.CryptoMethod} (0x{partitionHeader.Flags.CryptoMethod:X})"); - Console.WriteLine($" Content platform: {partitionHeader.Flags.ContentPlatform} (0x{partitionHeader.Flags.ContentPlatform:X})"); - Console.WriteLine($" Content type: {partitionHeader.Flags.MediaPlatformIndex} (0x{partitionHeader.Flags.MediaPlatformIndex:X})"); - Console.WriteLine($" Content unit size: {partitionHeader.Flags.ContentUnitSize} (0x{partitionHeader.Flags.ContentUnitSize:X})"); - Console.WriteLine($" Bitmasks: {partitionHeader.Flags.BitMasks} (0x{partitionHeader.Flags.BitMasks:X})"); - Console.WriteLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits} (0x{partitionHeader.PlainRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits} (0x{partitionHeader.PlainRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits} (0x{partitionHeader.LogoRegionOffsetInMediaUnits:X})"); - Console.WriteLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits} (0x{partitionHeader.LogoRegionSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits} (0x{partitionHeader.ExeFSOffsetInMediaUnits:X})"); - Console.WriteLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits} (0x{partitionHeader.ExeFSSizeInMediaUnits:X})"); - Console.WriteLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits} (0x{partitionHeader.ExeFSHashRegionSizeInMediaUnits:X})"); - Console.WriteLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}"); - Console.WriteLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits} (0x{partitionHeader.RomFSOffsetInMediaUnits:X})"); - Console.WriteLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits} (0x{partitionHeader.RomFSSizeInMediaUnits:X})"); - Console.WriteLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits} (0x{partitionHeader.RomFSHashRegionSizeInMediaUnits:X})"); - 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('-', ' ')}"); + builder.AppendLine($" RSA-2048 SHA-256 signature: {BitConverter.ToString(partitionHeader.RSA2048Signature).Replace('-', ' ')}"); + builder.AppendLine($" Magic ID: {partitionHeader.MagicID} (0x{partitionHeader.MagicID:X})"); + builder.AppendLine($" Content size in media units: {partitionHeader.ContentSizeInMediaUnits} (0x{partitionHeader.ContentSizeInMediaUnits:X})"); + builder.AppendLine($" Partition ID: {partitionHeader.PartitionId} (0x{partitionHeader.PartitionId:X})"); + builder.AppendLine($" Maker code: {partitionHeader.MakerCode} (0x{partitionHeader.MakerCode:X})"); + builder.AppendLine($" Version: {partitionHeader.Version} (0x{partitionHeader.Version:X})"); + builder.AppendLine($" Verification hash: {partitionHeader.VerificationHash} (0x{partitionHeader.VerificationHash:X})"); + builder.AppendLine($" Program ID: {BitConverter.ToString(partitionHeader.ProgramId).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(partitionHeader.Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Logo region SHA-256 hash: {BitConverter.ToString(partitionHeader.LogoRegionHash).Replace('-', ' ')}"); + builder.AppendLine($" Product code: {partitionHeader.ProductCode} (0x{partitionHeader.ProductCode:X})"); + builder.AppendLine($" Extended header SHA-256 hash: {BitConverter.ToString(partitionHeader.ExtendedHeaderHash).Replace('-', ' ')}"); + builder.AppendLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(partitionHeader.Reserved2).Replace('-', ' ')}"); + builder.AppendLine(" Flags:"); + builder.AppendLine($" Reserved 0: {partitionHeader.Flags.Reserved0} (0x{partitionHeader.Flags.Reserved0:X})"); + builder.AppendLine($" Reserved 1: {partitionHeader.Flags.Reserved1} (0x{partitionHeader.Flags.Reserved1:X})"); + builder.AppendLine($" Reserved 2: {partitionHeader.Flags.Reserved2} (0x{partitionHeader.Flags.Reserved2:X})"); + builder.AppendLine($" Crypto method: {partitionHeader.Flags.CryptoMethod} (0x{partitionHeader.Flags.CryptoMethod:X})"); + builder.AppendLine($" Content platform: {partitionHeader.Flags.ContentPlatform} (0x{partitionHeader.Flags.ContentPlatform:X})"); + builder.AppendLine($" Content type: {partitionHeader.Flags.MediaPlatformIndex} (0x{partitionHeader.Flags.MediaPlatformIndex:X})"); + builder.AppendLine($" Content unit size: {partitionHeader.Flags.ContentUnitSize} (0x{partitionHeader.Flags.ContentUnitSize:X})"); + builder.AppendLine($" Bitmasks: {partitionHeader.Flags.BitMasks} (0x{partitionHeader.Flags.BitMasks:X})"); + builder.AppendLine($" Plain region offset, in media units: {partitionHeader.PlainRegionOffsetInMediaUnits} (0x{partitionHeader.PlainRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Plain region size, in media units: {partitionHeader.PlainRegionSizeInMediaUnits} (0x{partitionHeader.PlainRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Logo region offset, in media units: {partitionHeader.LogoRegionOffsetInMediaUnits} (0x{partitionHeader.LogoRegionOffsetInMediaUnits:X})"); + builder.AppendLine($" Logo region size, in media units: {partitionHeader.LogoRegionSizeInMediaUnits} (0x{partitionHeader.LogoRegionSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS offset, in media units: {partitionHeader.ExeFSOffsetInMediaUnits} (0x{partitionHeader.ExeFSOffsetInMediaUnits:X})"); + builder.AppendLine($" ExeFS size, in media units: {partitionHeader.ExeFSSizeInMediaUnits} (0x{partitionHeader.ExeFSSizeInMediaUnits:X})"); + builder.AppendLine($" ExeFS hash region size, in media units: {partitionHeader.ExeFSHashRegionSizeInMediaUnits} (0x{partitionHeader.ExeFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 3: {BitConverter.ToString(partitionHeader.Reserved3).Replace('-', ' ')}"); + builder.AppendLine($" RomFS offset, in media units: {partitionHeader.RomFSOffsetInMediaUnits} (0x{partitionHeader.RomFSOffsetInMediaUnits:X})"); + builder.AppendLine($" RomFS size, in media units: {partitionHeader.RomFSSizeInMediaUnits} (0x{partitionHeader.RomFSSizeInMediaUnits:X})"); + builder.AppendLine($" RomFS hash region size, in media units: {partitionHeader.RomFSHashRegionSizeInMediaUnits} (0x{partitionHeader.RomFSHashRegionSizeInMediaUnits:X})"); + builder.AppendLine($" Reserved 4: {BitConverter.ToString(partitionHeader.Reserved4).Replace('-', ' ')}"); + builder.AppendLine($" ExeFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.ExeFSSuperblockHash).Replace('-', ' ')}"); + builder.AppendLine($" RomFS superblock SHA-256 hash: {BitConverter.ToString(partitionHeader.RomFSSuperblockHash).Replace('-', ' ')}"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print NCCH extended header information /// - private void PrintExtendedHeaders() + /// StringBuilder to append information to + private void PrintExtendedHeaders(StringBuilder builder) { - Console.WriteLine(" NCCH Extended Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" NCCH Extended Header Information:"); + builder.AppendLine(" -------------------------"); if (ExtendedHeaders == null || ExtendedHeaders.Length == 0) { - Console.WriteLine(" No NCCH extended headers"); + builder.AppendLine(" No NCCH extended headers"); } else { for (int i = 0; i < ExtendedHeaders.Length; i++) { var extendedHeader = ExtendedHeaders[i]; - Console.WriteLine($" NCCH Extended Header {i}"); + builder.AppendLine($" NCCH Extended Header {i}"); if (extendedHeader == null) { - Console.WriteLine($" Unrecognized partition data, no data can be parsed"); + builder.AppendLine($" Unrecognized partition data, no data can be parsed"); } else { - Console.WriteLine($" System control info:"); - Console.WriteLine($" Application title: {extendedHeader.SCI.ApplicationTitle}"); - Console.WriteLine($" Reserved 1: {BitConverter.ToString(extendedHeader.SCI.Reserved1).Replace('-', ' ')}"); - Console.WriteLine($" Flag: {extendedHeader.SCI.Flag} (0x{extendedHeader.SCI.Flag:X})"); - Console.WriteLine($" Remaster version: {extendedHeader.SCI.RemasterVersion} (0x{extendedHeader.SCI.RemasterVersion:X})"); + builder.AppendLine($" System control info:"); + builder.AppendLine($" Application title: {extendedHeader.SCI.ApplicationTitle}"); + builder.AppendLine($" Reserved 1: {BitConverter.ToString(extendedHeader.SCI.Reserved1).Replace('-', ' ')}"); + builder.AppendLine($" Flag: {extendedHeader.SCI.Flag} (0x{extendedHeader.SCI.Flag:X})"); + builder.AppendLine($" Remaster version: {extendedHeader.SCI.RemasterVersion} (0x{extendedHeader.SCI.RemasterVersion:X})"); - Console.WriteLine($" Text code set info:"); - Console.WriteLine($" Address: {extendedHeader.SCI.TextCodeSetInfo.Address} (0x{extendedHeader.SCI.TextCodeSetInfo.Address:X})"); - Console.WriteLine($" Physical region size (in page-multiples): {extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages:X})"); - Console.WriteLine($" Size (in bytes): {extendedHeader.SCI.TextCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.TextCodeSetInfo.SizeInBytes:X})"); + builder.AppendLine($" Text code set info:"); + builder.AppendLine($" Address: {extendedHeader.SCI.TextCodeSetInfo.Address} (0x{extendedHeader.SCI.TextCodeSetInfo.Address:X})"); + builder.AppendLine($" Physical region size (in page-multiples): {extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.TextCodeSetInfo.PhysicalRegionSizeInPages:X})"); + builder.AppendLine($" Size (in bytes): {extendedHeader.SCI.TextCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.TextCodeSetInfo.SizeInBytes:X})"); - Console.WriteLine($" Stack size: {extendedHeader.SCI.StackSize} (0x{extendedHeader.SCI.StackSize:X})"); + builder.AppendLine($" Stack size: {extendedHeader.SCI.StackSize} (0x{extendedHeader.SCI.StackSize:X})"); - Console.WriteLine($" Read-only code set info:"); - Console.WriteLine($" Address: {extendedHeader.SCI.ReadOnlyCodeSetInfo.Address} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.Address:X})"); - Console.WriteLine($" Physical region size (in page-multiples): {extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages:X})"); - Console.WriteLine($" Size (in bytes): {extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes:X})"); + builder.AppendLine($" Read-only code set info:"); + builder.AppendLine($" Address: {extendedHeader.SCI.ReadOnlyCodeSetInfo.Address} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.Address:X})"); + builder.AppendLine($" Physical region size (in page-multiples): {extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.PhysicalRegionSizeInPages:X})"); + builder.AppendLine($" Size (in bytes): {extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.ReadOnlyCodeSetInfo.SizeInBytes:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(extendedHeader.SCI.Reserved2).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Reserved 2: {BitConverter.ToString(extendedHeader.SCI.Reserved2).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Data code set info:"); - Console.WriteLine($" Address: {extendedHeader.SCI.DataCodeSetInfo.Address} (0x{extendedHeader.SCI.DataCodeSetInfo.Address:X})"); - Console.WriteLine($" Physical region size (in page-multiples): {extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages:X})"); - Console.WriteLine($" Size (in bytes): {extendedHeader.SCI.DataCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.DataCodeSetInfo.SizeInBytes:X})"); + builder.AppendLine($" Data code set info:"); + builder.AppendLine($" Address: {extendedHeader.SCI.DataCodeSetInfo.Address} (0x{extendedHeader.SCI.DataCodeSetInfo.Address:X})"); + builder.AppendLine($" Physical region size (in page-multiples): {extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages} (0x{extendedHeader.SCI.DataCodeSetInfo.PhysicalRegionSizeInPages:X})"); + builder.AppendLine($" Size (in bytes): {extendedHeader.SCI.DataCodeSetInfo.SizeInBytes} (0x{extendedHeader.SCI.DataCodeSetInfo.SizeInBytes:X})"); - Console.WriteLine($" BSS size: {extendedHeader.SCI.BSSSize} (0x{extendedHeader.SCI.BSSSize:X})"); - Console.WriteLine($" Dependency module list: {string.Join(", ", extendedHeader.SCI.DependencyModuleList)}"); + builder.AppendLine($" BSS size: {extendedHeader.SCI.BSSSize} (0x{extendedHeader.SCI.BSSSize:X})"); + builder.AppendLine($" Dependency module list: {string.Join(", ", extendedHeader.SCI.DependencyModuleList)}"); - Console.WriteLine($" System info:"); - Console.WriteLine($" SaveData size: {extendedHeader.SCI.SystemInfo.SaveDataSize} (0x{extendedHeader.SCI.SystemInfo.SaveDataSize:X})"); - Console.WriteLine($" Jump ID: {extendedHeader.SCI.SystemInfo.JumpID} (0x{extendedHeader.SCI.SystemInfo.JumpID:X})"); - Console.WriteLine($" Reserved: {BitConverter.ToString(extendedHeader.SCI.SystemInfo.Reserved).Replace('-', newChar: ' ')}"); + builder.AppendLine($" System info:"); + builder.AppendLine($" SaveData size: {extendedHeader.SCI.SystemInfo.SaveDataSize} (0x{extendedHeader.SCI.SystemInfo.SaveDataSize:X})"); + builder.AppendLine($" Jump ID: {extendedHeader.SCI.SystemInfo.JumpID} (0x{extendedHeader.SCI.SystemInfo.JumpID:X})"); + builder.AppendLine($" Reserved: {BitConverter.ToString(extendedHeader.SCI.SystemInfo.Reserved).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Access control info:"); - Console.WriteLine($" ARM11 local system capabilities:"); - Console.WriteLine($" Program ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID:X})"); - Console.WriteLine($" Core version: {extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion:X})"); - Console.WriteLine($" Flag 1: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1:X})"); - Console.WriteLine($" Flag 2: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2:X})"); - Console.WriteLine($" Flag 0: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0:X})"); - Console.WriteLine($" Priority: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority:X})"); - Console.WriteLine($" Resource limit descriptors: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors)}"); + builder.AppendLine($" Access control info:"); + builder.AppendLine($" ARM11 local system capabilities:"); + builder.AppendLine($" Program ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ProgramID:X})"); + builder.AppendLine($" Core version: {extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.CoreVersion:X})"); + builder.AppendLine($" Flag 1: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag1:X})"); + builder.AppendLine($" Flag 2: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag2:X})"); + builder.AppendLine($" Flag 0: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Flag0:X})"); + builder.AppendLine($" Priority: {extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.Priority:X})"); + builder.AppendLine($" Resource limit descriptors: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors)}"); - Console.WriteLine($" Storage info:"); - Console.WriteLine($" Extdata ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); - Console.WriteLine($" System savedata IDs: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Storage accessible unique IDs: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', newChar: ' ')}"); - Console.WriteLine($" File system access info: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Other attributes: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); + builder.AppendLine($" Storage info:"); + builder.AppendLine($" Extdata ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); + builder.AppendLine($" System savedata IDs: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Storage accessible unique IDs: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', newChar: ' ')}"); + builder.AppendLine($" File system access info: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Other attributes: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); - Console.WriteLine($" Service access control: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl)}"); - Console.WriteLine($" Extended service access control: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl)}"); - Console.WriteLine($" Reserved: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Resource limit cateogry: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + builder.AppendLine($" Service access control: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl)}"); + builder.AppendLine($" Extended service access control: {string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl)}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); - Console.WriteLine($" ARM11 kernel capabilities:"); - Console.WriteLine($" Descriptors: {string.Join(", ", extendedHeader.ACI.ARM11KernelCapabilities.Descriptors)}"); - Console.WriteLine($" Reserved: {BitConverter.ToString(extendedHeader.ACI.ARM11KernelCapabilities.Reserved).Replace('-', newChar: ' ')}"); + builder.AppendLine($" ARM11 kernel capabilities:"); + builder.AppendLine($" Descriptors: {string.Join(", ", extendedHeader.ACI.ARM11KernelCapabilities.Descriptors)}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(extendedHeader.ACI.ARM11KernelCapabilities.Reserved).Replace('-', newChar: ' ')}"); - Console.WriteLine($" ARM9 access control:"); - Console.WriteLine($" Descriptors: {BitConverter.ToString(extendedHeader.ACI.ARM9AccessControl.Descriptors).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Descriptor version: {extendedHeader.ACI.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACI.ARM9AccessControl.DescriptorVersion:X})"); + builder.AppendLine($" ARM9 access control:"); + builder.AppendLine($" Descriptors: {BitConverter.ToString(extendedHeader.ACI.ARM9AccessControl.Descriptors).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Descriptor version: {extendedHeader.ACI.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACI.ARM9AccessControl.DescriptorVersion:X})"); - Console.WriteLine($" AccessDec signature (RSA-2048-SHA256): {BitConverter.ToString(extendedHeader.AccessDescSignature).Replace('-', ' ')}"); - Console.WriteLine($" NCCH HDR RSA-2048 public key: {BitConverter.ToString(extendedHeader.NCCHHDRPublicKey).Replace('-', ' ')}"); + builder.AppendLine($" AccessDec signature (RSA-2048-SHA256): {BitConverter.ToString(extendedHeader.AccessDescSignature).Replace('-', ' ')}"); + builder.AppendLine($" NCCH HDR RSA-2048 public key: {BitConverter.ToString(extendedHeader.NCCHHDRPublicKey).Replace('-', ' ')}"); - Console.WriteLine($" Access control info (for limitations of first ACI):"); - Console.WriteLine($" ARM11 local system capabilities:"); - Console.WriteLine($" Program ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID:X})"); - Console.WriteLine($" Core version: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion:X})"); - Console.WriteLine($" Flag 1: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1:X})"); - Console.WriteLine($" Flag 2: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2:X})"); - Console.WriteLine($" Flag 0: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0:X})"); - Console.WriteLine($" Priority: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority:X})"); - Console.WriteLine($" Resource limit descriptors: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors)}"); + builder.AppendLine($" Access control info (for limitations of first ACI):"); + builder.AppendLine($" ARM11 local system capabilities:"); + builder.AppendLine($" Program ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ProgramID:X})"); + builder.AppendLine($" Core version: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.CoreVersion:X})"); + builder.AppendLine($" Flag 1: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag1:X})"); + builder.AppendLine($" Flag 2: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag2:X})"); + builder.AppendLine($" Flag 0: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Flag0:X})"); + builder.AppendLine($" Priority: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Priority:X})"); + builder.AppendLine($" Resource limit descriptors: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors)}"); - Console.WriteLine($" Storage info:"); - Console.WriteLine($" Extdata ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); - Console.WriteLine($" System savedata IDs: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Storage accessible unique IDs: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', newChar: ' ')}"); - Console.WriteLine($" File system access info: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Other attributes: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); + builder.AppendLine($" Storage info:"); + builder.AppendLine($" Extdata ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); + builder.AppendLine($" System savedata IDs: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Storage accessible unique IDs: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', newChar: ' ')}"); + builder.AppendLine($" File system access info: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Other attributes: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); - Console.WriteLine($" Service access control: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl)}"); - Console.WriteLine($" Extended service access control: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl)}"); - Console.WriteLine($" Reserved: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Resource limit cateogry: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + builder.AppendLine($" Service access control: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl)}"); + builder.AppendLine($" Extended service access control: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl)}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); - Console.WriteLine($" ARM11 kernel capabilities:"); - Console.WriteLine($" Descriptors: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors)}"); - Console.WriteLine($" Reserved: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved).Replace('-', newChar: ' ')}"); + builder.AppendLine($" ARM11 kernel capabilities:"); + builder.AppendLine($" Descriptors: {string.Join(", ", extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors)}"); + builder.AppendLine($" Reserved: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved).Replace('-', newChar: ' ')}"); - Console.WriteLine($" ARM9 access control:"); - Console.WriteLine($" Descriptors: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors).Replace('-', newChar: ' ')}"); - Console.WriteLine($" Descriptor version: {extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion:X})"); + builder.AppendLine($" ARM9 access control:"); + builder.AppendLine($" Descriptors: {BitConverter.ToString(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors).Replace('-', newChar: ' ')}"); + builder.AppendLine($" Descriptor version: {extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion:X})"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print ExeFS header information /// - private void PrintExeFSHeaders() + /// StringBuilder to append information to + private void PrintExeFSHeaders(StringBuilder builder) { - Console.WriteLine(" ExeFS Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" ExeFS Header Information:"); + builder.AppendLine(" -------------------------"); if (ExeFSHeaders == null || ExeFSHeaders.Length == 0) { - Console.WriteLine(" No ExeFS headers"); + builder.AppendLine(" No ExeFS headers"); } else { for (int i = 0; i < ExeFSHeaders.Length; i++) { var exeFSHeader = ExeFSHeaders[i]; - Console.WriteLine($" ExeFS Header {i}"); + builder.AppendLine($" ExeFS Header {i}"); if (exeFSHeader == null) { - Console.WriteLine($" Unrecognized partition data, no data can be parsed"); + builder.AppendLine($" Unrecognized partition data, no data can be parsed"); } else { - Console.WriteLine($" File headers:"); + builder.AppendLine($" File headers:"); for (int j = 0; j < exeFSHeader.FileHeaders.Length; j++) { var fileHeader = exeFSHeader.FileHeaders[j]; - Console.WriteLine(value: $" File Header {j}"); - Console.WriteLine(value: $" File name: {fileHeader.FileName}"); - Console.WriteLine(value: $" File offset: {fileHeader.FileOffset} (0x{fileHeader.FileOffset:X})"); - Console.WriteLine(value: $" File size: {fileHeader.FileSize} (0x{fileHeader.FileSize:X})"); + builder.AppendLine(value: $" File Header {j}"); + builder.AppendLine(value: $" File name: {fileHeader.FileName}"); + builder.AppendLine(value: $" File offset: {fileHeader.FileOffset} (0x{fileHeader.FileOffset:X})"); + builder.AppendLine(value: $" File size: {fileHeader.FileSize} (0x{fileHeader.FileSize:X})"); } - Console.WriteLine(value: $" Reserved: {BitConverter.ToString(exeFSHeader.Reserved).Replace('-', ' ')}"); + builder.AppendLine(value: $" Reserved: {BitConverter.ToString(exeFSHeader.Reserved).Replace('-', ' ')}"); - Console.WriteLine($" File hashes:"); + builder.AppendLine($" File hashes:"); for (int j = 0; j < exeFSHeader.FileHashes.Length; j++) { var fileHash = exeFSHeader.FileHashes[j]; - Console.WriteLine(value: $" File Hash {j}"); - Console.WriteLine(value: $" SHA-256: {BitConverter.ToString(fileHash).Replace('-', ' ')}"); + builder.AppendLine(value: $" File Hash {j}"); + builder.AppendLine(value: $" SHA-256: {BitConverter.ToString(fileHash).Replace('-', ' ')}"); } } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print RomFS header information /// - private void PrintRomFSHeaders() + /// StringBuilder to append information to + private void PrintRomFSHeaders(StringBuilder builder) { - Console.WriteLine(" RomFS Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" RomFS Header Information:"); + builder.AppendLine(" -------------------------"); if (RomFSHeaders == null || RomFSHeaders.Length == 0) { - Console.WriteLine(" No RomFS headers"); + builder.AppendLine(" No RomFS headers"); } else { for (int i = 0; i < RomFSHeaders.Length; i++) { var romFSHeader = RomFSHeaders[i]; - Console.WriteLine($" RomFS Header {i}"); + builder.AppendLine($" RomFS Header {i}"); if (romFSHeader == null) { - Console.WriteLine($" Unrecognized RomFS data, no data can be parsed"); + builder.AppendLine($" Unrecognized RomFS data, no data can be parsed"); } else { - Console.WriteLine(value: $" Magic string: {romFSHeader.MagicString}"); - Console.WriteLine(value: $" Magic number: {romFSHeader.MagicNumber} (0x{romFSHeader.MagicNumber:X})"); - Console.WriteLine(value: $" Master hash size: {romFSHeader.MasterHashSize} (0x{romFSHeader.MasterHashSize:X})"); - Console.WriteLine(value: $" Level 1 logical offset: {romFSHeader.Level1LogicalOffset} (0x{romFSHeader.Level1LogicalOffset:X})"); - Console.WriteLine(value: $" Level 1 hashdata size: {romFSHeader.Level1HashdataSize} (0x{romFSHeader.Level1HashdataSize:X})"); - Console.WriteLine(value: $" Level 1 block size: {romFSHeader.Level1BlockSizeLog2} (0x{romFSHeader.Level1BlockSizeLog2:X})"); - Console.WriteLine(value: $" Reserved 1: {BitConverter.ToString(romFSHeader.Reserved1).Replace('-', ' ')}"); - Console.WriteLine(value: $" Level 2 logical offset: {romFSHeader.Level2LogicalOffset} (0x{romFSHeader.Level2LogicalOffset:X})"); - Console.WriteLine(value: $" Level 2 hashdata size: {romFSHeader.Level2HashdataSize} (0x{romFSHeader.Level2HashdataSize:X})"); - Console.WriteLine(value: $" Level 2 block size: {romFSHeader.Level2BlockSizeLog2} (0x{romFSHeader.Level2BlockSizeLog2:X})"); - Console.WriteLine(value: $" Reserved 2: {BitConverter.ToString(romFSHeader.Reserved2).Replace('-', ' ')}"); - Console.WriteLine(value: $" Level 3 logical offset: {romFSHeader.Level3LogicalOffset} (0x{romFSHeader.Level3LogicalOffset:X})"); - Console.WriteLine(value: $" Level 3 hashdata size: {romFSHeader.Level3HashdataSize} (0x{romFSHeader.Level3HashdataSize:X})"); - Console.WriteLine(value: $" Level 3 block size: {romFSHeader.Level3BlockSizeLog2} (0x{romFSHeader.Level3BlockSizeLog2:X})"); - Console.WriteLine(value: $" Reserved 3: {BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' ')}"); - Console.WriteLine(value: $" Reserved 4: {BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' ')}"); - Console.WriteLine(value: $" Optional info size: {romFSHeader.OptionalInfoSize} (0x{romFSHeader.OptionalInfoSize:X})"); + builder.AppendLine(value: $" Magic string: {romFSHeader.MagicString}"); + builder.AppendLine(value: $" Magic number: {romFSHeader.MagicNumber} (0x{romFSHeader.MagicNumber:X})"); + builder.AppendLine(value: $" Master hash size: {romFSHeader.MasterHashSize} (0x{romFSHeader.MasterHashSize:X})"); + builder.AppendLine(value: $" Level 1 logical offset: {romFSHeader.Level1LogicalOffset} (0x{romFSHeader.Level1LogicalOffset:X})"); + builder.AppendLine(value: $" Level 1 hashdata size: {romFSHeader.Level1HashdataSize} (0x{romFSHeader.Level1HashdataSize:X})"); + builder.AppendLine(value: $" Level 1 block size: {romFSHeader.Level1BlockSizeLog2} (0x{romFSHeader.Level1BlockSizeLog2:X})"); + builder.AppendLine(value: $" Reserved 1: {BitConverter.ToString(romFSHeader.Reserved1).Replace('-', ' ')}"); + builder.AppendLine(value: $" Level 2 logical offset: {romFSHeader.Level2LogicalOffset} (0x{romFSHeader.Level2LogicalOffset:X})"); + builder.AppendLine(value: $" Level 2 hashdata size: {romFSHeader.Level2HashdataSize} (0x{romFSHeader.Level2HashdataSize:X})"); + builder.AppendLine(value: $" Level 2 block size: {romFSHeader.Level2BlockSizeLog2} (0x{romFSHeader.Level2BlockSizeLog2:X})"); + builder.AppendLine(value: $" Reserved 2: {BitConverter.ToString(romFSHeader.Reserved2).Replace('-', ' ')}"); + builder.AppendLine(value: $" Level 3 logical offset: {romFSHeader.Level3LogicalOffset} (0x{romFSHeader.Level3LogicalOffset:X})"); + builder.AppendLine(value: $" Level 3 hashdata size: {romFSHeader.Level3HashdataSize} (0x{romFSHeader.Level3HashdataSize:X})"); + builder.AppendLine(value: $" Level 3 block size: {romFSHeader.Level3BlockSizeLog2} (0x{romFSHeader.Level3BlockSizeLog2:X})"); + builder.AppendLine(value: $" Reserved 3: {BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' ')}"); + builder.AppendLine(value: $" Reserved 4: {BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' ')}"); + builder.AppendLine(value: $" Optional info size: {romFSHeader.OptionalInfoSize} (0x{romFSHeader.OptionalInfoSize:X})"); } } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/NCF.cs b/BurnOutSharp.Wrappers/NCF.cs index 02658a5b..7287b0f0 100644 --- a/BurnOutSharp.Wrappers/NCF.cs +++ b/BurnOutSharp.Wrappers/NCF.cs @@ -1,5 +1,5 @@ -using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -257,306 +257,323 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("NCF Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("NCF Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Header - PrintHeader(); + PrintHeader(builder); // Directory and Directory Maps - PrintDirectoryHeader(); - PrintDirectoryEntries(); + PrintDirectoryHeader(builder); + PrintDirectoryEntries(builder); // TODO: Should we print out the entire string table? - PrintDirectoryInfo1Entries(); - PrintDirectoryInfo2Entries(); - PrintDirectoryCopyEntries(); - PrintDirectoryLocalEntries(); - PrintUnknownHeader(); - PrintUnknownEntries(); + PrintDirectoryInfo1Entries(builder); + PrintDirectoryInfo2Entries(builder); + PrintDirectoryCopyEntries(builder); + PrintDirectoryLocalEntries(builder); + PrintUnknownHeader(builder); + PrintUnknownEntries(builder); // Checksums and Checksum Maps - PrintChecksumHeader(); - PrintChecksumMapHeader(); - PrintChecksumMapEntries(); - PrintChecksumEntries(); + PrintChecksumHeader(builder); + PrintChecksumMapHeader(builder); + PrintChecksumMapEntries(builder); + PrintChecksumEntries(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); - Console.WriteLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); - Console.WriteLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); - Console.WriteLine($" Cache ID: {CacheID} (0x{CacheID:X})"); - Console.WriteLine($" Last version played: {LastVersionPlayed} (0x{LastVersionPlayed:X})"); - Console.WriteLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); - Console.WriteLine($" Dummy 2: {Dummy2} (0x{Dummy2:X})"); - Console.WriteLine($" File size: {FileSize} (0x{FileSize:X})"); - Console.WriteLine($" Block size: {BlockSize} (0x{BlockSize:X})"); - Console.WriteLine($" Block count: {BlockCount} (0x{BlockCount:X})"); - Console.WriteLine($" Dummy 3: {Dummy3} (0x{Dummy3:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); + builder.AppendLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); + builder.AppendLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); + builder.AppendLine($" Cache ID: {CacheID} (0x{CacheID:X})"); + builder.AppendLine($" Last version played: {LastVersionPlayed} (0x{LastVersionPlayed:X})"); + builder.AppendLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); + builder.AppendLine($" Dummy 2: {Dummy2} (0x{Dummy2:X})"); + builder.AppendLine($" File size: {FileSize} (0x{FileSize:X})"); + builder.AppendLine($" Block size: {BlockSize} (0x{BlockSize:X})"); + builder.AppendLine($" Block count: {BlockCount} (0x{BlockCount:X})"); + builder.AppendLine($" Dummy 3: {Dummy3} (0x{Dummy3:X})"); + builder.AppendLine(); } /// /// Print directory header information /// - private void PrintDirectoryHeader() + /// StringBuilder to append information to + private void PrintDirectoryHeader(StringBuilder builder) { - Console.WriteLine(" Directory Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {DH_Dummy0} (0x{DH_Dummy0:X})"); - Console.WriteLine($" Cache ID: {DH_CacheID} (0x{DH_CacheID:X})"); - Console.WriteLine($" Last version played: {DH_LastVersionPlayed} (0x{DH_LastVersionPlayed:X})"); - Console.WriteLine($" Item count: {DH_ItemCount} (0x{DH_ItemCount:X})"); - Console.WriteLine($" File count: {DH_FileCount} (0x{DH_FileCount:X})"); - Console.WriteLine($" Checksum data length: {DH_ChecksumDataLength} (0x{DH_ChecksumDataLength:X})"); - Console.WriteLine($" Directory size: {DH_DirectorySize} (0x{DH_DirectorySize:X})"); - Console.WriteLine($" Name size: {DH_NameSize} (0x{DH_NameSize:X})"); - Console.WriteLine($" Info 1 count: {DH_Info1Count} (0x{DH_Info1Count:X})"); - Console.WriteLine($" Copy count: {DH_CopyCount} (0x{DH_CopyCount:X})"); - Console.WriteLine($" Local count: {DH_LocalCount} (0x{DH_LocalCount:X})"); - Console.WriteLine($" Dummy 1: {DH_Dummy1} (0x{DH_Dummy1:X})"); - Console.WriteLine($" Dummy 2: {DH_Dummy2} (0x{DH_Dummy2:X})"); - Console.WriteLine($" Checksum: {DH_Checksum} (0x{DH_Checksum:X})"); - Console.WriteLine(); + builder.AppendLine(" Directory Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {DH_Dummy0} (0x{DH_Dummy0:X})"); + builder.AppendLine($" Cache ID: {DH_CacheID} (0x{DH_CacheID:X})"); + builder.AppendLine($" Last version played: {DH_LastVersionPlayed} (0x{DH_LastVersionPlayed:X})"); + builder.AppendLine($" Item count: {DH_ItemCount} (0x{DH_ItemCount:X})"); + builder.AppendLine($" File count: {DH_FileCount} (0x{DH_FileCount:X})"); + builder.AppendLine($" Checksum data length: {DH_ChecksumDataLength} (0x{DH_ChecksumDataLength:X})"); + builder.AppendLine($" Directory size: {DH_DirectorySize} (0x{DH_DirectorySize:X})"); + builder.AppendLine($" Name size: {DH_NameSize} (0x{DH_NameSize:X})"); + builder.AppendLine($" Info 1 count: {DH_Info1Count} (0x{DH_Info1Count:X})"); + builder.AppendLine($" Copy count: {DH_CopyCount} (0x{DH_CopyCount:X})"); + builder.AppendLine($" Local count: {DH_LocalCount} (0x{DH_LocalCount:X})"); + builder.AppendLine($" Dummy 1: {DH_Dummy1} (0x{DH_Dummy1:X})"); + builder.AppendLine($" Dummy 2: {DH_Dummy2} (0x{DH_Dummy2:X})"); + builder.AppendLine($" Checksum: {DH_Checksum} (0x{DH_Checksum:X})"); + builder.AppendLine(); } /// /// Print directory entries information /// - private void PrintDirectoryEntries() + /// StringBuilder to append information to + private void PrintDirectoryEntries(StringBuilder builder) { - Console.WriteLine(" Directory Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryEntries == null || DirectoryEntries.Length == 0) { - Console.WriteLine(" No directory entries"); + builder.AppendLine(" No directory entries"); } else { for (int i = 0; i < DirectoryEntries.Length; i++) { var directoryEntry = DirectoryEntries[i]; - Console.WriteLine($" Directory Entry {i}"); - Console.WriteLine($" Name offset: {directoryEntry.NameOffset} (0x{directoryEntry.NameOffset:X})"); - Console.WriteLine($" Name: {directoryEntry.Name}"); - Console.WriteLine($" Item size: {directoryEntry.ItemSize} (0x{directoryEntry.ItemSize:X})"); - Console.WriteLine($" Checksum index: {directoryEntry.ChecksumIndex} (0x{directoryEntry.ChecksumIndex:X})"); - Console.WriteLine($" Directory flags: {directoryEntry.DirectoryFlags} (0x{directoryEntry.DirectoryFlags:X})"); - Console.WriteLine($" Parent index: {directoryEntry.ParentIndex} (0x{directoryEntry.ParentIndex:X})"); - Console.WriteLine($" Next index: {directoryEntry.NextIndex} (0x{directoryEntry.NextIndex:X})"); - Console.WriteLine($" First index: {directoryEntry.FirstIndex} (0x{directoryEntry.FirstIndex:X})"); + builder.AppendLine($" Directory Entry {i}"); + builder.AppendLine($" Name offset: {directoryEntry.NameOffset} (0x{directoryEntry.NameOffset:X})"); + builder.AppendLine($" Name: {directoryEntry.Name}"); + builder.AppendLine($" Item size: {directoryEntry.ItemSize} (0x{directoryEntry.ItemSize:X})"); + builder.AppendLine($" Checksum index: {directoryEntry.ChecksumIndex} (0x{directoryEntry.ChecksumIndex:X})"); + builder.AppendLine($" Directory flags: {directoryEntry.DirectoryFlags} (0x{directoryEntry.DirectoryFlags:X})"); + builder.AppendLine($" Parent index: {directoryEntry.ParentIndex} (0x{directoryEntry.ParentIndex:X})"); + builder.AppendLine($" Next index: {directoryEntry.NextIndex} (0x{directoryEntry.NextIndex:X})"); + builder.AppendLine($" First index: {directoryEntry.FirstIndex} (0x{directoryEntry.FirstIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory info 1 entries information /// - private void PrintDirectoryInfo1Entries() + /// StringBuilder to append information to + private void PrintDirectoryInfo1Entries(StringBuilder builder) { - Console.WriteLine(" Directory Info 1 Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Info 1 Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryInfo1Entries == null || DirectoryInfo1Entries.Length == 0) { - Console.WriteLine(" No directory info 1 entries"); + builder.AppendLine(" No directory info 1 entries"); } else { for (int i = 0; i < DirectoryInfo1Entries.Length; i++) { var directoryInfoEntry = DirectoryInfo1Entries[i]; - Console.WriteLine($" Directory Info 1 Entry {i}"); - Console.WriteLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); + builder.AppendLine($" Directory Info 1 Entry {i}"); + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory info 2 entries information /// - private void PrintDirectoryInfo2Entries() + /// StringBuilder to append information to + private void PrintDirectoryInfo2Entries(StringBuilder builder) { - Console.WriteLine(" Directory Info 2 Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Info 2 Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryInfo2Entries == null || DirectoryInfo2Entries.Length == 0) { - Console.WriteLine(" No directory info 2 entries"); + builder.AppendLine(" No directory info 2 entries"); } else { for (int i = 0; i < DirectoryInfo2Entries.Length; i++) { var directoryInfoEntry = DirectoryInfo2Entries[i]; - Console.WriteLine($" Directory Info 2 Entry {i}"); - Console.WriteLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); + builder.AppendLine($" Directory Info 2 Entry {i}"); + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory copy entries information /// - private void PrintDirectoryCopyEntries() + /// StringBuilder to append information to + private void PrintDirectoryCopyEntries(StringBuilder builder) { - Console.WriteLine(" Directory Copy Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Directory Copy Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (DirectoryCopyEntries == null || DirectoryCopyEntries.Length == 0) { - Console.WriteLine(" No directory copy entries"); + builder.AppendLine(" No directory copy entries"); } else { for (int i = 0; i < DirectoryCopyEntries.Length; i++) { var directoryCopyEntry = DirectoryCopyEntries[i]; - Console.WriteLine($" Directory Copy Entry {i}"); - Console.WriteLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); + builder.AppendLine($" Directory Copy Entry {i}"); + builder.AppendLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory local entries information /// - private void PrintDirectoryLocalEntries() + /// StringBuilder to append information to + private void PrintDirectoryLocalEntries(StringBuilder builder) { - Console.WriteLine(" Directory Local Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Directory Local Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (DirectoryLocalEntries == null || DirectoryLocalEntries.Length == 0) { - Console.WriteLine(" No directory local entries"); + builder.AppendLine(" No directory local entries"); } else { for (int i = 0; i < DirectoryLocalEntries.Length; i++) { var directoryLocalEntry = DirectoryLocalEntries[i]; - Console.WriteLine($" Directory Local Entry {i}"); - Console.WriteLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); + builder.AppendLine($" Directory Local Entry {i}"); + builder.AppendLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print unknown header information /// - private void PrintUnknownHeader() + /// StringBuilder to append information to + private void PrintUnknownHeader(StringBuilder builder) { - Console.WriteLine(" Unknown Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {UH_Dummy0} (0x{UH_Dummy0:X})"); - Console.WriteLine($" Dummy 1: {UH_Dummy1} (0x{UH_Dummy1:X})"); - Console.WriteLine(); + builder.AppendLine(" Unknown Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {UH_Dummy0} (0x{UH_Dummy0:X})"); + builder.AppendLine($" Dummy 1: {UH_Dummy1} (0x{UH_Dummy1:X})"); + builder.AppendLine(); } /// /// Print unknown entries information /// - private void PrintUnknownEntries() + /// StringBuilder to append information to + private void PrintUnknownEntries(StringBuilder builder) { - Console.WriteLine(" Unknown Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Unknown Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (UnknownEntries == null || UnknownEntries.Length == 0) { - Console.WriteLine(" No unknown entries"); + builder.AppendLine(" No unknown entries"); } else { for (int i = 0; i < UnknownEntries.Length; i++) { var unknownEntry = UnknownEntries[i]; - Console.WriteLine($" Unknown Entry {i}"); - Console.WriteLine($" Dummy 0: {unknownEntry.Dummy0} (0x{unknownEntry.Dummy0:X})"); + builder.AppendLine($" Unknown Entry {i}"); + builder.AppendLine($" Dummy 0: {unknownEntry.Dummy0} (0x{unknownEntry.Dummy0:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print checksum header information /// - private void PrintChecksumHeader() + /// StringBuilder to append information to + private void PrintChecksumHeader(StringBuilder builder) { - Console.WriteLine(" Checksum Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {CH_Dummy0} (0x{CH_Dummy0:X})"); - Console.WriteLine($" Checksum size: {CH_ChecksumSize} (0x{CH_ChecksumSize:X})"); - Console.WriteLine(); + builder.AppendLine(" Checksum Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {CH_Dummy0} (0x{CH_Dummy0:X})"); + builder.AppendLine($" Checksum size: {CH_ChecksumSize} (0x{CH_ChecksumSize:X})"); + builder.AppendLine(); } /// /// Print checksum map header information /// - private void PrintChecksumMapHeader() + /// StringBuilder to append information to + private void PrintChecksumMapHeader(StringBuilder builder) { - Console.WriteLine(" Checksum Map Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Dummy 0: {CMH_Dummy0} (0x{CMH_Dummy0:X})"); - Console.WriteLine($" Dummy 1: {CMH_Dummy1} (0x{CMH_Dummy1:X})"); - Console.WriteLine($" Item count: {CMH_ItemCount} (0x{CMH_ItemCount:X})"); - Console.WriteLine($" Checksum count: {CMH_ChecksumCount} (0x{CMH_ChecksumCount:X})"); - Console.WriteLine(); + builder.AppendLine(" Checksum Map Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Dummy 0: {CMH_Dummy0} (0x{CMH_Dummy0:X})"); + builder.AppendLine($" Dummy 1: {CMH_Dummy1} (0x{CMH_Dummy1:X})"); + builder.AppendLine($" Item count: {CMH_ItemCount} (0x{CMH_ItemCount:X})"); + builder.AppendLine($" Checksum count: {CMH_ChecksumCount} (0x{CMH_ChecksumCount:X})"); + builder.AppendLine(); } /// /// Print checksum map entries information /// - private void PrintChecksumMapEntries() + /// StringBuilder to append information to + private void PrintChecksumMapEntries(StringBuilder builder) { - Console.WriteLine(" Checksum Map Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Checksum Map Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (ChecksumMapEntries == null || ChecksumMapEntries.Length == 0) { - Console.WriteLine(" No checksum map entries"); + builder.AppendLine(" No checksum map entries"); } else { for (int i = 0; i < ChecksumMapEntries.Length; i++) { var checksumMapEntry = ChecksumMapEntries[i]; - Console.WriteLine($" Checksum Map Entry {i}"); - Console.WriteLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); - Console.WriteLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); + builder.AppendLine($" Checksum Map Entry {i}"); + builder.AppendLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); + builder.AppendLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print checksum entries information /// - private void PrintChecksumEntries() + /// StringBuilder to append information to + private void PrintChecksumEntries(StringBuilder builder) { - Console.WriteLine(" Checksum Entries Information:"); - Console.WriteLine(value: " -------------------------"); + builder.AppendLine(" Checksum Entries Information:"); + builder.AppendLine(value: " -------------------------"); if (ChecksumEntries == null || ChecksumEntries.Length == 0) { - Console.WriteLine(" No checksum entries"); + builder.AppendLine(" No checksum entries"); } else { for (int i = 0; i < ChecksumEntries.Length; i++) { var checksumEntry = ChecksumEntries[i]; - Console.WriteLine($" Checksum Entry {i}"); - Console.WriteLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); + builder.AppendLine($" Checksum Entry {i}"); + builder.AppendLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/NewExecutable.cs b/BurnOutSharp.Wrappers/NewExecutable.cs index 507e1d46..e51ebd8a 100644 --- a/BurnOutSharp.Wrappers/NewExecutable.cs +++ b/BurnOutSharp.Wrappers/NewExecutable.cs @@ -275,146 +275,155 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("New Executable Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("New Executable Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Stub - PrintStubHeader(); - PrintStubExtendedHeader(); + PrintStubHeader(builder); + PrintStubExtendedHeader(builder); // Header - PrintHeader(); + PrintHeader(builder); // Tables - PrintSegmentTable(); - PrintResourceTable(); - PrintResidentNameTable(); - PrintModuleReferenceTable(); - PrintImportedNameTable(); - PrintEntryTable(); - PrintNonresidentNameTable(); + PrintSegmentTable(builder); + PrintResourceTable(builder); + PrintResidentNameTable(builder); + PrintModuleReferenceTable(builder); + PrintImportedNameTable(builder); + PrintEntryTable(builder); + PrintNonresidentNameTable(builder); + + return builder; } /// /// Print stub header information /// - private void PrintStubHeader() + /// StringBuilder to append information to + private void PrintStubHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {Stub_Magic}"); - Console.WriteLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); - Console.WriteLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); - Console.WriteLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); - Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); - Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); - Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); - Console.WriteLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); - Console.WriteLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); - Console.WriteLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); - Console.WriteLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); - Console.WriteLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); - Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); - Console.WriteLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic number: {Stub_Magic}"); + builder.AppendLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); + builder.AppendLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); + builder.AppendLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); + builder.AppendLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); + builder.AppendLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); + builder.AppendLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); + builder.AppendLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); + builder.AppendLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); + builder.AppendLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); + builder.AppendLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); + builder.AppendLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); + builder.AppendLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); + builder.AppendLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); + builder.AppendLine(); } /// /// Print stub extended header information /// - private void PrintStubExtendedHeader() + /// StringBuilder to append information to + private void PrintStubExtendedHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Extended Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); - Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); - Console.WriteLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); - Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Extended Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + builder.AppendLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); + builder.AppendLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + builder.AppendLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); + builder.AppendLine(); } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {Magic}"); - Console.WriteLine($" Linker version: {LinkerVersion} (0x{LinkerVersion:X})"); - Console.WriteLine($" Linker revision: {LinkerRevision} (0x{LinkerRevision:X})"); - Console.WriteLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); - Console.WriteLine($" Entry table size: {EntryTableSize} (0x{EntryTableSize:X})"); - Console.WriteLine($" CRC checksum: {CrcChecksum} (0x{CrcChecksum:X})"); - Console.WriteLine($" Flag word: {FlagWord} (0x{FlagWord:X})"); - Console.WriteLine($" Automatic data segment number: {AutomaticDataSegmentNumber} (0x{AutomaticDataSegmentNumber:X})"); - Console.WriteLine($" Initial heap allocation: {InitialHeapAlloc} (0x{InitialHeapAlloc:X})"); - Console.WriteLine($" Initial stack allocation: {InitialStackAlloc} (0x{InitialStackAlloc:X})"); - Console.WriteLine($" Initial CS:IP setting: {InitialCSIPSetting} (0x{InitialCSIPSetting:X})"); - Console.WriteLine($" Initial SS:SP setting: {InitialSSSPSetting} (0x{InitialSSSPSetting:X})"); - Console.WriteLine($" File segment count: {FileSegmentCount} (0x{FileSegmentCount:X})"); - Console.WriteLine($" Module reference table size: {ModuleReferenceTableSize} (0x{ModuleReferenceTableSize:X})"); - Console.WriteLine($" Non-resident name table size: {NonResidentNameTableSize} (0x{NonResidentNameTableSize:X})"); - Console.WriteLine($" Segment table offset: {SegmentTableOffset} (0x{SegmentTableOffset:X})"); - Console.WriteLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); - Console.WriteLine($" Resident name table offset: {ResidentNameTableOffset} (0x{ResidentNameTableOffset:X})"); - Console.WriteLine($" Module reference table offset: {ModuleReferenceTableOffset} (0x{ModuleReferenceTableOffset:X})"); - Console.WriteLine($" Imported names table offset: {ImportedNamesTableOffset} (0x{ImportedNamesTableOffset:X})"); - Console.WriteLine($" Non-resident name table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); - Console.WriteLine($" Moveable entries count: {MovableEntriesCount} (0x{MovableEntriesCount:X})"); - Console.WriteLine($" Segment alignment shift count: {SegmentAlignmentShiftCount} (0x{SegmentAlignmentShiftCount:X})"); - Console.WriteLine($" Resource entries count: {ResourceEntriesCount} (0x{ResourceEntriesCount:X})"); - Console.WriteLine($" Target operating system: {TargetOperatingSystem} (0x{TargetOperatingSystem:X})"); - Console.WriteLine($" Additional flags: {AdditionalFlags} (0x{AdditionalFlags:X})"); - Console.WriteLine($" Return thunk offset: {ReturnThunkOffset} (0x{ReturnThunkOffset:X})"); - Console.WriteLine($" Segment reference thunk offset: {SegmentReferenceThunkOffset} (0x{SegmentReferenceThunkOffset:X})"); - Console.WriteLine($" Minimum code swap area size: {MinCodeSwapAreaSize} (0x{MinCodeSwapAreaSize:X})"); - Console.WriteLine($" Windows SDK revision: {WindowsSDKRevision} (0x{WindowsSDKRevision:X})"); - Console.WriteLine($" Windows SDK version: {WindowsSDKVersion} (0x{WindowsSDKVersion:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic number: {Magic}"); + builder.AppendLine($" Linker version: {LinkerVersion} (0x{LinkerVersion:X})"); + builder.AppendLine($" Linker revision: {LinkerRevision} (0x{LinkerRevision:X})"); + builder.AppendLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); + builder.AppendLine($" Entry table size: {EntryTableSize} (0x{EntryTableSize:X})"); + builder.AppendLine($" CRC checksum: {CrcChecksum} (0x{CrcChecksum:X})"); + builder.AppendLine($" Flag word: {FlagWord} (0x{FlagWord:X})"); + builder.AppendLine($" Automatic data segment number: {AutomaticDataSegmentNumber} (0x{AutomaticDataSegmentNumber:X})"); + builder.AppendLine($" Initial heap allocation: {InitialHeapAlloc} (0x{InitialHeapAlloc:X})"); + builder.AppendLine($" Initial stack allocation: {InitialStackAlloc} (0x{InitialStackAlloc:X})"); + builder.AppendLine($" Initial CS:IP setting: {InitialCSIPSetting} (0x{InitialCSIPSetting:X})"); + builder.AppendLine($" Initial SS:SP setting: {InitialSSSPSetting} (0x{InitialSSSPSetting:X})"); + builder.AppendLine($" File segment count: {FileSegmentCount} (0x{FileSegmentCount:X})"); + builder.AppendLine($" Module reference table size: {ModuleReferenceTableSize} (0x{ModuleReferenceTableSize:X})"); + builder.AppendLine($" Non-resident name table size: {NonResidentNameTableSize} (0x{NonResidentNameTableSize:X})"); + builder.AppendLine($" Segment table offset: {SegmentTableOffset} (0x{SegmentTableOffset:X})"); + builder.AppendLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); + builder.AppendLine($" Resident name table offset: {ResidentNameTableOffset} (0x{ResidentNameTableOffset:X})"); + builder.AppendLine($" Module reference table offset: {ModuleReferenceTableOffset} (0x{ModuleReferenceTableOffset:X})"); + builder.AppendLine($" Imported names table offset: {ImportedNamesTableOffset} (0x{ImportedNamesTableOffset:X})"); + builder.AppendLine($" Non-resident name table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); + builder.AppendLine($" Moveable entries count: {MovableEntriesCount} (0x{MovableEntriesCount:X})"); + builder.AppendLine($" Segment alignment shift count: {SegmentAlignmentShiftCount} (0x{SegmentAlignmentShiftCount:X})"); + builder.AppendLine($" Resource entries count: {ResourceEntriesCount} (0x{ResourceEntriesCount:X})"); + builder.AppendLine($" Target operating system: {TargetOperatingSystem} (0x{TargetOperatingSystem:X})"); + builder.AppendLine($" Additional flags: {AdditionalFlags} (0x{AdditionalFlags:X})"); + builder.AppendLine($" Return thunk offset: {ReturnThunkOffset} (0x{ReturnThunkOffset:X})"); + builder.AppendLine($" Segment reference thunk offset: {SegmentReferenceThunkOffset} (0x{SegmentReferenceThunkOffset:X})"); + builder.AppendLine($" Minimum code swap area size: {MinCodeSwapAreaSize} (0x{MinCodeSwapAreaSize:X})"); + builder.AppendLine($" Windows SDK revision: {WindowsSDKRevision} (0x{WindowsSDKRevision:X})"); + builder.AppendLine($" Windows SDK version: {WindowsSDKVersion} (0x{WindowsSDKVersion:X})"); + builder.AppendLine(); } /// /// Print segment table information /// - private void PrintSegmentTable() + /// StringBuilder to append information to + private void PrintSegmentTable(StringBuilder builder) { - Console.WriteLine(" Segment Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Segment Table Information:"); + builder.AppendLine(" -------------------------"); if (FileSegmentCount == 0 || SegmentTable.Length == 0) { - Console.WriteLine(" No segment table items"); + builder.AppendLine(" No segment table items"); } else { for (int i = 0; i < SegmentTable.Length; i++) { var entry = SegmentTable[i]; - Console.WriteLine($" Segment Table Entry {i}"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Flag word: {entry.FlagWord} (0x{entry.FlagWord:X})"); - Console.WriteLine($" Minimum allocation size: {entry.MinimumAllocationSize} (0x{entry.MinimumAllocationSize:X})"); + builder.AppendLine($" Segment Table Entry {i}"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Flag word: {entry.FlagWord} (0x{entry.FlagWord:X})"); + builder.AppendLine($" Minimum allocation size: {entry.MinimumAllocationSize} (0x{entry.MinimumAllocationSize:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print resource table information /// - private void PrintResourceTable() + /// StringBuilder to append information to + private void PrintResourceTable(StringBuilder builder) { - Console.WriteLine(" Resource Table Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Alignment shift count: {ResourceTable.AlignmentShiftCount} (0x{ResourceTable.AlignmentShiftCount:X})"); + builder.AppendLine(" Resource Table Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Alignment shift count: {ResourceTable.AlignmentShiftCount} (0x{ResourceTable.AlignmentShiftCount:X})"); if (ResourceEntriesCount == 0 || ResourceTable.ResourceTypes.Length == 0) { - Console.WriteLine(" No resource table items"); + builder.AppendLine(" No resource table items"); } else { @@ -422,14 +431,14 @@ namespace BurnOutSharp.Wrappers { // TODO: If not integer type, print out name var entry = ResourceTable.ResourceTypes[i]; - Console.WriteLine($" Resource Table Entry {i}"); - Console.WriteLine($" Type ID: {entry.TypeID} (0x{entry.TypeID:X}) (Is Integer Type: {entry.IsIntegerType()})"); - Console.WriteLine($" Resource count: {entry.ResourceCount} (0x{entry.ResourceCount:X})"); - Console.WriteLine($" Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); - Console.WriteLine($" Resources = "); + builder.AppendLine($" Resource Table Entry {i}"); + builder.AppendLine($" Type ID: {entry.TypeID} (0x{entry.TypeID:X}) (Is Integer Type: {entry.IsIntegerType()})"); + builder.AppendLine($" Resource count: {entry.ResourceCount} (0x{entry.ResourceCount:X})"); + builder.AppendLine($" Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); + builder.AppendLine($" Resources = "); if (entry.ResourceCount == 0 || entry.Resources.Length == 0) { - Console.WriteLine(" No resource items"); + builder.AppendLine(" No resource items"); } else { @@ -437,12 +446,12 @@ namespace BurnOutSharp.Wrappers { // TODO: If not integer type, print out name var resource = entry.Resources[j]; - Console.WriteLine($" Resource Entry {i}"); - Console.WriteLine($" Offset: {resource.Offset} (0x{resource.Offset:X})"); - Console.WriteLine($" Length: {resource.Length} (0x{resource.Length:X})"); - Console.WriteLine($" Flag word: {resource.FlagWord} (0x{resource.FlagWord:X})"); - Console.WriteLine($" Resource ID: {resource.ResourceID} (0x{resource.ResourceID:X}) (Is Integer Type: {resource.IsIntegerType()})"); - Console.WriteLine($" Reserved: {resource.Reserved} (0x{resource.Reserved:X})"); + builder.AppendLine($" Resource Entry {i}"); + builder.AppendLine($" Offset: {resource.Offset} (0x{resource.Offset:X})"); + builder.AppendLine($" Length: {resource.Length} (0x{resource.Length:X})"); + builder.AppendLine($" Flag word: {resource.FlagWord} (0x{resource.FlagWord:X})"); + builder.AppendLine($" Resource ID: {resource.ResourceID} (0x{resource.ResourceID:X}) (Is Integer Type: {resource.IsIntegerType()})"); + builder.AppendLine($" Reserved: {resource.Reserved} (0x{resource.Reserved:X})"); } } } @@ -450,55 +459,57 @@ namespace BurnOutSharp.Wrappers if (ResourceTable.TypeAndNameStrings.Count == 0) { - Console.WriteLine(" No resource table type/name strings"); + builder.AppendLine(" No resource table type/name strings"); } else { foreach (var typeAndNameString in ResourceTable.TypeAndNameStrings) { - Console.WriteLine($" Resource Type/Name Offset {typeAndNameString.Key}"); - Console.WriteLine($" Length: {typeAndNameString.Value.Length} (0x{typeAndNameString.Value.Length:X})"); - Console.WriteLine($" Text: {(typeAndNameString.Value.Text != null ? Encoding.ASCII.GetString(typeAndNameString.Value.Text).TrimEnd('\0') : "[EMPTY]")}"); + builder.AppendLine($" Resource Type/Name Offset {typeAndNameString.Key}"); + builder.AppendLine($" Length: {typeAndNameString.Value.Length} (0x{typeAndNameString.Value.Length:X})"); + builder.AppendLine($" Text: {(typeAndNameString.Value.Text != null ? Encoding.ASCII.GetString(typeAndNameString.Value.Text).TrimEnd('\0') : "[EMPTY]")}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print resident-name table information /// - private void PrintResidentNameTable() + /// StringBuilder to append information to + private void PrintResidentNameTable(StringBuilder builder) { - Console.WriteLine(" Resident-Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Resident-Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ResidentNameTableOffset == 0 || ResidentNameTable.Length == 0) { - Console.WriteLine(" No resident-name table items"); + builder.AppendLine(" No resident-name table items"); } else { for (int i = 0; i < ResidentNameTable.Length; i++) { var entry = ResidentNameTable[i]; - Console.WriteLine($" Resident-Name Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString).TrimEnd('\0') : "[EMPTY]")}"); - Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + builder.AppendLine($" Resident-Name Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString).TrimEnd('\0') : "[EMPTY]")}"); + builder.AppendLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print module-reference table information /// - private void PrintModuleReferenceTable() + /// StringBuilder to append information to + private void PrintModuleReferenceTable(StringBuilder builder) { - Console.WriteLine(" Module-Reference Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Module-Reference Table Information:"); + builder.AppendLine(" -------------------------"); if (ModuleReferenceTableSize == 0 || ModuleReferenceTable.Length == 0) { - Console.WriteLine(" No module-reference table items"); + builder.AppendLine(" No module-reference table items"); } else { @@ -506,96 +517,99 @@ namespace BurnOutSharp.Wrappers { // TODO: Read the imported names table and print value here var entry = ModuleReferenceTable[i]; - Console.WriteLine($" Module-Reference Table Entry {i}"); - Console.WriteLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + Stub_NewExeHeaderAddr + ImportedNamesTableOffset})"); + builder.AppendLine($" Module-Reference Table Entry {i}"); + builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + Stub_NewExeHeaderAddr + ImportedNamesTableOffset})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print imported-name table information /// - private void PrintImportedNameTable() + /// StringBuilder to append information to + private void PrintImportedNameTable(StringBuilder builder) { - Console.WriteLine(" Imported-Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Imported-Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ImportedNamesTableOffset == 0 || ImportedNameTable.Count == 0) { - Console.WriteLine(" No imported-name table items"); + builder.AppendLine(" No imported-name table items"); } else { foreach (var entry in ImportedNameTable) { - Console.WriteLine($" Imported-Name Table at Offset {entry.Key}"); - Console.WriteLine($" Length: {entry.Value.Length} (0x{entry.Value.Length:X})"); - Console.WriteLine($" Name string: {(entry.Value.NameString != null ? Encoding.ASCII.GetString(entry.Value.NameString) : "[EMPTY]")}"); + builder.AppendLine($" Imported-Name Table at Offset {entry.Key}"); + builder.AppendLine($" Length: {entry.Value.Length} (0x{entry.Value.Length:X})"); + builder.AppendLine($" Name string: {(entry.Value.NameString != null ? Encoding.ASCII.GetString(entry.Value.NameString) : "[EMPTY]")}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print entry table information /// - private void PrintEntryTable() + /// StringBuilder to append information to + private void PrintEntryTable(StringBuilder builder) { - Console.WriteLine(" Entry Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Entry Table Information:"); + builder.AppendLine(" -------------------------"); if (EntryTableSize == 0 || EntryTable.Length == 0) { - Console.WriteLine(" No entry table items"); + builder.AppendLine(" No entry table items"); } else { for (int i = 0; i < EntryTable.Length; i++) { var entry = EntryTable[i]; - Console.WriteLine($" Entry Table Entry {i}"); - Console.WriteLine($" Entry count: {entry.EntryCount} (0x{entry.EntryCount:X})"); - Console.WriteLine($" Segment indicator: {entry.SegmentIndicator} (0x{entry.SegmentIndicator:X}) ({entry.GetEntryType()})"); + builder.AppendLine($" Entry Table Entry {i}"); + builder.AppendLine($" Entry count: {entry.EntryCount} (0x{entry.EntryCount:X})"); + builder.AppendLine($" Segment indicator: {entry.SegmentIndicator} (0x{entry.SegmentIndicator:X}) ({entry.GetEntryType()})"); switch (entry.GetEntryType()) { case BurnOutSharp.Models.NewExecutable.SegmentEntryType.FixedSegment: - Console.WriteLine($" Flag word: {entry.FixedFlagWord} (0x{entry.FixedFlagWord:X})"); - Console.WriteLine($" Offset: {entry.FixedOffset} (0x{entry.FixedOffset:X})"); + builder.AppendLine($" Flag word: {entry.FixedFlagWord} (0x{entry.FixedFlagWord:X})"); + builder.AppendLine($" Offset: {entry.FixedOffset} (0x{entry.FixedOffset:X})"); break; case BurnOutSharp.Models.NewExecutable.SegmentEntryType.MoveableSegment: - Console.WriteLine($" Flag word: {entry.MoveableFlagWord} (0x{entry.MoveableFlagWord:X})"); - Console.WriteLine($" Reserved: {entry.MoveableReserved} (0x{entry.MoveableReserved:X})"); - Console.WriteLine($" Segment number: {entry.MoveableSegmentNumber} (0x{entry.MoveableSegmentNumber:X})"); - Console.WriteLine($" Offset: {entry.MoveableOffset} (0x{entry.MoveableOffset:X})"); + builder.AppendLine($" Flag word: {entry.MoveableFlagWord} (0x{entry.MoveableFlagWord:X})"); + builder.AppendLine($" Reserved: {entry.MoveableReserved} (0x{entry.MoveableReserved:X})"); + builder.AppendLine($" Segment number: {entry.MoveableSegmentNumber} (0x{entry.MoveableSegmentNumber:X})"); + builder.AppendLine($" Offset: {entry.MoveableOffset} (0x{entry.MoveableOffset:X})"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print nonresident-name table information /// - private void PrintNonresidentNameTable() + /// StringBuilder to append information to + private void PrintNonresidentNameTable(StringBuilder builder) { - Console.WriteLine(" Nonresident-Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Nonresident-Name Table Information:"); + builder.AppendLine(" -------------------------"); if (NonResidentNameTableSize == 0 || NonResidentNameTable.Length == 0) { - Console.WriteLine(" No nonresident-name table items"); + builder.AppendLine(" No nonresident-name table items"); } else { for (int i = 0; i < NonResidentNameTable.Length; i++) { var entry = NonResidentNameTable[i]; - Console.WriteLine($" Nonresident-Name Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString) : "[EMPTY]")}"); - Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + builder.AppendLine($" Nonresident-Name Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString) : "[EMPTY]")}"); + builder.AppendLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/Nitro.cs b/BurnOutSharp.Wrappers/Nitro.cs index c00f93c4..dabb27a4 100644 --- a/BurnOutSharp.Wrappers/Nitro.cs +++ b/BurnOutSharp.Wrappers/Nitro.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -299,7 +300,7 @@ namespace BurnOutSharp.Wrappers #endregion - #region Name Table + #region File Allocation Table /// public Models.Nitro.FileAllocationTableEntry[] FileAllocationTable => _cart.FileAllocationTable; @@ -374,240 +375,251 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("NDS Cart Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintCommonHeader(); - PrintExtendedDSiHeader(); - PrintSecureArea(); - PrintNameTable(); - PrintFileAllocationTable(); + builder.AppendLine("NDS Cart Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintCommonHeader(builder); + PrintExtendedDSiHeader(builder); + PrintSecureArea(builder); + PrintNameTable(builder); + PrintFileAllocationTable(builder); + + return builder; } /// /// Print common header information /// - private void PrintCommonHeader() + /// StringBuilder to append information to + private void PrintCommonHeader(StringBuilder builder) { - Console.WriteLine(" Common Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Game title: {GameTitle ?? "[NULL]"}"); - Console.WriteLine($" Game code: {GameCode} (0x{GameCode:X})"); - Console.WriteLine($" Maker code: {MakerCode ?? "[NULL]"}"); - Console.WriteLine($" Unit code: {UnitCode} (0x{UnitCode:X})"); - Console.WriteLine($" Encryption seed select: {EncryptionSeedSelect} (0x{EncryptionSeedSelect:X})"); - Console.WriteLine($" Device capacity: {DeviceCapacity} (0x{DeviceCapacity:X})"); - Console.WriteLine($" Reserved 1: {BitConverter.ToString(Reserved1).Replace('-', ' ')}"); - Console.WriteLine($" Game revision: {GameRevision} (0x{GameRevision:X})"); - Console.WriteLine($" Rom version: {RomVersion} (0x{RomVersion:X})"); - Console.WriteLine($" ARM9 rom offset: {ARM9RomOffset} (0x{ARM9RomOffset:X})"); - Console.WriteLine($" ARM9 entry address: {ARM9EntryAddress} (0x{ARM9EntryAddress:X})"); - Console.WriteLine($" ARM9 load address: {ARM9LoadAddress} (0x{ARM9LoadAddress:X})"); - Console.WriteLine($" ARM9 size: {ARM9Size} (0x{ARM9Size:X})"); - Console.WriteLine($" ARM7 rom offset: {ARM7RomOffset} (0x{ARM7RomOffset:X})"); - Console.WriteLine($" ARM7 entry address: {ARM7EntryAddress} (0x{ARM7EntryAddress:X})"); - Console.WriteLine($" ARM7 load address: {ARM7LoadAddress} (0x{ARM7LoadAddress:X})"); - Console.WriteLine($" ARM7 size: {ARM7Size} (0x{ARM7Size:X})"); - Console.WriteLine($" File name table offset: {FileNameTableOffset} (0x{FileNameTableOffset:X})"); - Console.WriteLine($" File name table length: {FileNameTableLength} (0x{FileNameTableLength:X})"); - Console.WriteLine($" File allocation table offset: {FileAllocationTableOffset} (0x{FileAllocationTableOffset:X})"); - Console.WriteLine($" File allocation table length: {FileAllocationTableLength} (0x{FileAllocationTableLength:X})"); - Console.WriteLine($" ARM9 overlay offset: {ARM9OverlayOffset} (0x{ARM9OverlayOffset:X})"); - Console.WriteLine($" ARM9 overlay length: {ARM9OverlayLength} (0x{ARM9OverlayLength:X})"); - Console.WriteLine($" ARM7 overlay offset: {ARM7OverlayOffset} (0x{ARM7OverlayOffset:X})"); - Console.WriteLine($" ARM7 overlay length: {ARM7OverlayLength} (0x{ARM7OverlayLength:X})"); - Console.WriteLine($" Normal card control register settings: {NormalCardControlRegisterSettings} (0x{NormalCardControlRegisterSettings:X})"); - Console.WriteLine($" Secure card control register settings: {SecureCardControlRegisterSettings} (0x{SecureCardControlRegisterSettings:X})"); - Console.WriteLine($" Icon banner offset: {IconBannerOffset} (0x{IconBannerOffset:X})"); - Console.WriteLine($" Secure area CRC: {SecureAreaCRC} (0x{SecureAreaCRC:X})"); - Console.WriteLine($" Secure transfer timeout: {SecureTransferTimeout} (0x{SecureTransferTimeout:X})"); - Console.WriteLine($" ARM9 autoload: {ARM9Autoload} (0x{ARM9Autoload:X})"); - Console.WriteLine($" ARM7 autoload: {ARM7Autoload} (0x{ARM7Autoload:X})"); - Console.WriteLine($" Secure disable: {SecureDisable} (0x{SecureDisable:X})"); - Console.WriteLine($" NTR region rom size: {NTRRegionRomSize} (0x{NTRRegionRomSize:X})"); - Console.WriteLine($" Header size: {HeaderSize} (0x{HeaderSize:X})"); - Console.WriteLine($" Reserved 2: {BitConverter.ToString(Reserved2).Replace('-', ' ')}"); - Console.WriteLine($" Nintendo logo: {BitConverter.ToString(NintendoLogo).Replace('-', ' ')}"); - Console.WriteLine($" Nintendo logo CRC: {NintendoLogoCRC} (0x{NintendoLogoCRC:X})"); - Console.WriteLine($" Header CRC: {HeaderCRC} (0x{HeaderCRC:X})"); - Console.WriteLine($" Debugger reserved: {BitConverter.ToString(DebuggerReserved).Replace('-', ' ')}"); - Console.WriteLine(); + 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: {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: {BitConverter.ToString(Reserved2).Replace('-', ' ')}"); + builder.AppendLine($" Nintendo logo: {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: {BitConverter.ToString(DebuggerReserved).Replace('-', ' ')}"); + builder.AppendLine(); } /// /// Print extended DSi header information /// - private void PrintExtendedDSiHeader() + /// StringBuilder to append information to + private void PrintExtendedDSiHeader(StringBuilder builder) { - Console.WriteLine(" Extended DSi Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Extended DSi Header Information:"); + builder.AppendLine(" -------------------------"); if (_cart.ExtendedDSiHeader == null) { - Console.WriteLine(" No extended DSi header"); + builder.AppendLine(" No extended DSi header"); } else { - Console.WriteLine($" Global MBK1..MBK5 settings: {string.Join(", ", GlobalMBK15Settings)}"); - Console.WriteLine($" Local MBK6..MBK8 settings for ARM9: {string.Join(", ", LocalMBK68SettingsARM9)}"); - Console.WriteLine($" Local MBK6..MBK8 settings for ARM7: {string.Join(", ", LocalMBK68SettingsARM7)}"); - Console.WriteLine($" Global MBK9 setting: {GlobalMBK9Setting} (0x{GlobalMBK9Setting:X})"); - Console.WriteLine($" Region flags: {RegionFlags} (0x{RegionFlags:X})"); - Console.WriteLine($" Access control: {AccessControl} (0x{AccessControl:X})"); - Console.WriteLine($" ARM7 SCFG EXT mask: {ARM7SCFGEXTMask} (0x{ARM7SCFGEXTMask:X})"); - Console.WriteLine($" Reserved/flags?: {ReservedFlags} (0x{ReservedFlags:X})"); - Console.WriteLine($" ARM9i rom offset: {ARM9iRomOffset} (0x{ARM9iRomOffset:X})"); - Console.WriteLine($" Reserved 3: {Reserved3} (0x{Reserved3:X})"); - Console.WriteLine($" ARM9i load address: {ARM9iLoadAddress} (0x{ARM9iLoadAddress:X})"); - Console.WriteLine($" ARM9i size: {ARM9iSize} (0x{ARM9iSize:X})"); - Console.WriteLine($" ARM7i rom offset: {ARM7iRomOffset} (0x{ARM7iRomOffset:X})"); - Console.WriteLine($" Reserved 4: {Reserved4} (0x{Reserved4:X})"); - Console.WriteLine($" ARM7i load address: {ARM7iLoadAddress} (0x{ARM7iLoadAddress:X})"); - Console.WriteLine($" ARM7i size: {ARM7iSize} (0x{ARM7iSize:X})"); - Console.WriteLine($" Digest NTR region offset: {DigestNTRRegionOffset} (0x{DigestNTRRegionOffset:X})"); - Console.WriteLine($" Digest NTR region length: {DigestNTRRegionLength} (0x{DigestNTRRegionLength:X})"); - Console.WriteLine($" Digest TWL region offset: {DigestTWLRegionOffset} (0x{DigestTWLRegionOffset:X})"); - Console.WriteLine($" Digest TWL region length: {DigestTWLRegionLength} (0x{DigestTWLRegionLength:X})"); - Console.WriteLine($" Digest sector hashtable region offset: {DigestSectorHashtableRegionOffset} (0x{DigestSectorHashtableRegionOffset:X})"); - Console.WriteLine($" Digest sector hashtable region length: {DigestSectorHashtableRegionLength} (0x{DigestSectorHashtableRegionLength:X})"); - Console.WriteLine($" Digest block hashtable region offset: {DigestBlockHashtableRegionOffset} (0x{DigestBlockHashtableRegionOffset:X})"); - Console.WriteLine($" Digest block hashtable region length: {DigestBlockHashtableRegionLength} (0x{DigestBlockHashtableRegionLength:X})"); - Console.WriteLine($" Digest sector size: {DigestSectorSize} (0x{DigestSectorSize:X})"); - Console.WriteLine($" Digest block sector count: {DigestBlockSectorCount} (0x{DigestBlockSectorCount:X})"); - Console.WriteLine($" Icon banner size: {IconBannerSize} (0x{IconBannerSize:X})"); - Console.WriteLine($" Unknown 1: {Unknown1} (0x{Unknown1:X})"); - Console.WriteLine($" Modcrypt area 1 offset: {ModcryptArea1Offset} (0x{ModcryptArea1Offset:X})"); - Console.WriteLine($" Modcrypt area 1 size: {ModcryptArea1Size} (0x{ModcryptArea1Size:X})"); - Console.WriteLine($" Modcrypt area 2 offset: {ModcryptArea2Offset} (0x{ModcryptArea2Offset:X})"); - Console.WriteLine($" Modcrypt area 2 size: {ModcryptArea2Size} (0x{ModcryptArea2Size:X})"); - Console.WriteLine($" Title ID: {BitConverter.ToString(TitleID).Replace('-', ' ')}"); - Console.WriteLine($" DSiWare 'public.sav' size: {DSiWarePublicSavSize} (0x{DSiWarePublicSavSize:X})"); - Console.WriteLine($" DSiWare 'private.sav' size: {DSiWarePrivateSavSize} (0x{DSiWarePrivateSavSize:X})"); - Console.WriteLine($" Reserved (zero): {BitConverter.ToString(ReservedZero).Replace('-', ' ')}"); - Console.WriteLine($" Unknown 2: {BitConverter.ToString(Unknown2).Replace('-', ' ')}"); - Console.WriteLine($" ARM9 (with encrypted secure area) SHA1 HMAC hash: {BitConverter.ToString(ARM9WithSecureAreaSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" ARM7 SHA1 HMAC hash: {BitConverter.ToString(ARM7SHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" Digest master SHA1 HMAC hash: {BitConverter.ToString(DigestMasterSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" Banner SHA1 HMAC hash: {BitConverter.ToString(BannerSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" ARM9i (decrypted) SHA1 HMAC hash: {BitConverter.ToString(ARM9iDecryptedSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" ARM7i (decrypted) SHA1 HMAC hash: {BitConverter.ToString(ARM7iDecryptedSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" Reserved 5: {BitConverter.ToString(Reserved5).Replace('-', ' ')}"); - Console.WriteLine($" ARM9 (without secure area) SHA1 HMAC hash: {BitConverter.ToString(ARM9NoSecureAreaSHA1HMACHash).Replace('-', ' ')}"); - Console.WriteLine($" Reserved 6: {BitConverter.ToString(Reserved6).Replace('-', ' ')}"); - Console.WriteLine($" Reserved and unchecked region: {BitConverter.ToString(ReservedAndUnchecked).Replace('-', ' ')}"); - Console.WriteLine($" RSA signature: {BitConverter.ToString(RSASignature).Replace('-', ' ')}"); + builder.AppendLine($" Global MBK1..MBK5 settings: {string.Join(", ", GlobalMBK15Settings)}"); + builder.AppendLine($" Local MBK6..MBK8 settings for ARM9: {string.Join(", ", LocalMBK68SettingsARM9)}"); + builder.AppendLine($" Local MBK6..MBK8 settings for ARM7: {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: {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): {BitConverter.ToString(ReservedZero).Replace('-', ' ')}"); + builder.AppendLine($" Unknown 2: {BitConverter.ToString(Unknown2).Replace('-', ' ')}"); + builder.AppendLine($" ARM9 (with encrypted secure area) SHA1 HMAC hash: {BitConverter.ToString(ARM9WithSecureAreaSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" ARM7 SHA1 HMAC hash: {BitConverter.ToString(ARM7SHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" Digest master SHA1 HMAC hash: {BitConverter.ToString(DigestMasterSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" Banner SHA1 HMAC hash: {BitConverter.ToString(BannerSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" ARM9i (decrypted) SHA1 HMAC hash: {BitConverter.ToString(ARM9iDecryptedSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" ARM7i (decrypted) SHA1 HMAC hash: {BitConverter.ToString(ARM7iDecryptedSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 5: {BitConverter.ToString(Reserved5).Replace('-', ' ')}"); + builder.AppendLine($" ARM9 (without secure area) SHA1 HMAC hash: {BitConverter.ToString(ARM9NoSecureAreaSHA1HMACHash).Replace('-', ' ')}"); + builder.AppendLine($" Reserved 6: {BitConverter.ToString(Reserved6).Replace('-', ' ')}"); + builder.AppendLine($" Reserved and unchecked region: {BitConverter.ToString(ReservedAndUnchecked).Replace('-', ' ')}"); + builder.AppendLine($" RSA signature: {BitConverter.ToString(RSASignature).Replace('-', ' ')}"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print secure area information /// - private void PrintSecureArea() + /// StringBuilder to append information to + private void PrintSecureArea(StringBuilder builder) { - Console.WriteLine(" Secure Area Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" {BitConverter.ToString(SecureArea).Replace('-', ' ')}"); - Console.WriteLine(); + builder.AppendLine(" Secure Area Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" {BitConverter.ToString(SecureArea).Replace('-', ' ')}"); + builder.AppendLine(); } /// /// Print name table information /// - private void PrintNameTable() + /// StringBuilder to append information to + private void PrintNameTable(StringBuilder builder) { - Console.WriteLine(" Name Table Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine(); + builder.AppendLine(" Name Table Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine(); - PrintFolderAllocationTable(); - PrintNameList(); + PrintFolderAllocationTable(builder); + PrintNameList(builder); } /// /// Print folder allocation table information /// - private void PrintFolderAllocationTable() + /// StringBuilder to append information to + private void PrintFolderAllocationTable(StringBuilder builder) { - Console.WriteLine($" Folder Allocation Table:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Folder Allocation Table:"); + builder.AppendLine(" -------------------------"); if (FolderAllocationTable == null || FolderAllocationTable.Length == 0) { - Console.WriteLine(" No folder allocation table entries"); + builder.AppendLine(" No folder allocation table entries"); } else { for (int i = 0; i < FolderAllocationTable.Length; i++) { var entry = FolderAllocationTable[i]; - Console.WriteLine($" Folder Allocation Table Entry {i}"); - Console.WriteLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); - Console.WriteLine($" First file index: {entry.FirstFileIndex} (0x{entry.FirstFileIndex:X})"); + builder.AppendLine($" Folder Allocation Table Entry {i}"); + 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) { - Console.WriteLine($" Parent folder index: {entry.ParentFolderIndex} (0x{entry.ParentFolderIndex:X})"); - Console.WriteLine($" Unknown: {entry.Unknown} (0x{entry.Unknown:X})"); + 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); - Console.WriteLine($" Total entries: {totalEntries} (0x{totalEntries:X})"); + builder.AppendLine($" Total entries: {totalEntries} (0x{totalEntries:X})"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print folder allocation table information /// - private void PrintNameList() + /// StringBuilder to append information to + private void PrintNameList(StringBuilder builder) { - Console.WriteLine($" Name List:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Name List:"); + builder.AppendLine(" -------------------------"); if (NameList == null || NameList.Length == 0) { - Console.WriteLine(" No name list entries"); + builder.AppendLine(" No name list entries"); } else { for (int i = 0; i < NameList.Length; i++) { var entry = NameList[i]; - Console.WriteLine($" Name List Entry {i}"); - Console.WriteLine($" Folder: {entry.Folder} (0x{entry.Folder:X})"); - Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + builder.AppendLine($" Name List Entry {i}"); + builder.AppendLine($" Folder: {entry.Folder} (0x{entry.Folder:X})"); + builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); if (entry.Folder) - Console.WriteLine($" Index: {entry.Index} (0x{entry.Index:X})"); + builder.AppendLine($" Index: {entry.Index} (0x{entry.Index:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print file allocation table information /// - private void PrintFileAllocationTable() + /// StringBuilder to append information to + private void PrintFileAllocationTable(StringBuilder builder) { - Console.WriteLine($" File Allocation Table:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" File Allocation Table:"); + builder.AppendLine(" -------------------------"); if (FileAllocationTable == null || FileAllocationTable.Length == 0) { - Console.WriteLine(" No file allocation table entries"); + builder.AppendLine(" No file allocation table entries"); } else { for (int i = 0; i < FileAllocationTable.Length; i++) { var entry = FileAllocationTable[i]; - Console.WriteLine($" File Allocation Table Entry {i}"); - Console.WriteLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); - Console.WriteLine($" End offset: {entry.EndOffset} (0x{entry.EndOffset:X})"); + builder.AppendLine($" File Allocation Table Entry {i}"); + builder.AppendLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); + builder.AppendLine($" End offset: {entry.EndOffset} (0x{entry.EndOffset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/PAK.cs b/BurnOutSharp.Wrappers/PAK.cs index bfc0e059..01f29d94 100644 --- a/BurnOutSharp.Wrappers/PAK.cs +++ b/BurnOutSharp.Wrappers/PAK.cs @@ -1,5 +1,5 @@ -using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -101,52 +101,58 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("PAK Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintDirectoryItems(); + builder.AppendLine("PAK Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintDirectoryItems(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Directory offset: {DirectoryOffset} (0x{DirectoryOffset:X})"); - Console.WriteLine($" Directory length: {DirectoryLength} (0x{DirectoryLength:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Directory offset: {DirectoryOffset} (0x{DirectoryOffset:X})"); + builder.AppendLine($" Directory length: {DirectoryLength} (0x{DirectoryLength:X})"); + builder.AppendLine(); } /// /// Print directory items information /// - private void PrintDirectoryItems() + /// StringBuilder to append information to + private void PrintDirectoryItems(StringBuilder builder) { - Console.WriteLine(" Directory Items Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Items Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryItems == null || DirectoryItems.Length == 0) { - Console.WriteLine(" No directory items"); + builder.AppendLine(" No directory items"); } else { for (int i = 0; i < DirectoryItems.Length; i++) { var directoryItem = DirectoryItems[i]; - Console.WriteLine($" Directory Item {i}"); - Console.WriteLine($" Item name: {directoryItem.ItemName}"); - Console.WriteLine($" Item offset: {directoryItem.ItemOffset} (0x{directoryItem.ItemOffset:X})"); - Console.WriteLine($" Item length: {directoryItem.ItemLength} (0x{directoryItem.ItemLength:X})"); + builder.AppendLine($" Directory Item {i}"); + builder.AppendLine($" Item name: {directoryItem.ItemName}"); + builder.AppendLine($" Item offset: {directoryItem.ItemOffset} (0x{directoryItem.ItemOffset:X})"); + builder.AppendLine($" Item length: {directoryItem.ItemLength} (0x{directoryItem.ItemLength:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs index 6b61fc41..fe105fc5 100644 --- a/BurnOutSharp.Wrappers/PortableExecutable.cs +++ b/BurnOutSharp.Wrappers/PortableExecutable.cs @@ -1080,317 +1080,312 @@ namespace BurnOutSharp.Wrappers #region Printing - /// - /// Print all sections, including their start and end addresses - /// - public void PrintAllSections() - { - foreach (var section in SectionTable) - { - // TODO: Handle long section names with leading `/` - string sectionName = Encoding.UTF8.GetString(section.Name); - uint sectionAddr = section.PointerToRawData; - uint sectionEnd = sectionAddr + section.VirtualSize; - Console.WriteLine($"{sectionName}: {sectionAddr} -> {sectionEnd} ({sectionAddr:X} -> {sectionEnd:X})"); - } - } - /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("Portable Executable Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("Portable Executable Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Stub - PrintStubHeader(); - PrintStubExtendedHeader(); + PrintStubHeader(builder); + PrintStubExtendedHeader(builder); // Header - PrintCOFFFileHeader(); - PrintOptionalHeader(); + PrintCOFFFileHeader(builder); + PrintOptionalHeader(builder); // Tables - PrintSectionTable(); - PrintCOFFSymbolTable(); - PrintAttributeCertificateTable(); - PrintDelayLoadDirectoryTable(); + PrintSectionTable(builder); + PrintCOFFSymbolTable(builder); + PrintAttributeCertificateTable(builder); + PrintDelayLoadDirectoryTable(builder); // Named Sections - PrintBaseRelocationTable(); - PrintDebugTable(); - PrintExportTable(); - PrintImportTable(); - PrintResourceDirectoryTable(); + PrintBaseRelocationTable(builder); + PrintDebugTable(builder); + PrintExportTable(builder); + PrintImportTable(builder); + PrintResourceDirectoryTable(builder); + + return builder; } /// /// Print stub header information /// - private void PrintStubHeader() + /// StringBuilder to append information to + private void PrintStubHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {Stub_Magic}"); - Console.WriteLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); - Console.WriteLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); - Console.WriteLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); - Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); - Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); - Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); - Console.WriteLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); - Console.WriteLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); - Console.WriteLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); - Console.WriteLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); - Console.WriteLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); - Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); - Console.WriteLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Magic number: {Stub_Magic}"); + builder.AppendLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); + builder.AppendLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); + builder.AppendLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); + builder.AppendLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); + builder.AppendLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); + builder.AppendLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); + builder.AppendLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); + builder.AppendLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); + builder.AppendLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); + builder.AppendLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); + builder.AppendLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); + builder.AppendLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); + builder.AppendLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); + builder.AppendLine(); } /// /// Print stub extended header information /// - private void PrintStubExtendedHeader() + /// StringBuilder to append information to + private void PrintStubExtendedHeader(StringBuilder builder) { - Console.WriteLine(" MS-DOS Stub Extended Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); - Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); - Console.WriteLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); - Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); - Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); - Console.WriteLine(); + builder.AppendLine(" MS-DOS Stub Extended Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + builder.AppendLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); + builder.AppendLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); + builder.AppendLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + builder.AppendLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); + builder.AppendLine(); } /// /// Print COFF file header information /// - private void PrintCOFFFileHeader() + /// StringBuilder to append information to + private void PrintCOFFFileHeader(StringBuilder builder) { - Console.WriteLine(" COFF File Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Machine: {Machine} (0x{Machine:X})"); - Console.WriteLine($" Number of sections: {NumberOfSections} (0x{NumberOfSections:X})"); - Console.WriteLine($" Time/Date stamp: {TimeDateStamp} (0x{TimeDateStamp:X})"); - Console.WriteLine($" Pointer to symbol table: {PointerToSymbolTable} (0x{PointerToSymbolTable:X})"); - Console.WriteLine($" Number of symbols: {NumberOfSymbols} (0x{NumberOfSymbols:X})"); - Console.WriteLine($" Size of optional header: {SizeOfOptionalHeader} (0x{SizeOfOptionalHeader:X})"); - Console.WriteLine($" Characteristics: {Characteristics} (0x{Characteristics:X})"); - Console.WriteLine(); + builder.AppendLine(" COFF File Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Machine: {Machine} (0x{Machine:X})"); + builder.AppendLine($" Number of sections: {NumberOfSections} (0x{NumberOfSections:X})"); + builder.AppendLine($" Time/Date stamp: {TimeDateStamp} (0x{TimeDateStamp:X})"); + builder.AppendLine($" Pointer to symbol table: {PointerToSymbolTable} (0x{PointerToSymbolTable:X})"); + builder.AppendLine($" Number of symbols: {NumberOfSymbols} (0x{NumberOfSymbols:X})"); + builder.AppendLine($" Size of optional header: {SizeOfOptionalHeader} (0x{SizeOfOptionalHeader:X})"); + builder.AppendLine($" Characteristics: {Characteristics} (0x{Characteristics:X})"); + builder.AppendLine(); } /// /// Print optional header information /// - private void PrintOptionalHeader() + /// StringBuilder to append information to + private void PrintOptionalHeader(StringBuilder builder) { - Console.WriteLine(" Optional Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Optional Header Information:"); + builder.AppendLine(" -------------------------"); if (SizeOfOptionalHeader == 0) { - Console.WriteLine(" No optional header present"); + builder.AppendLine(" No optional header present"); } else { - Console.WriteLine($" Magic: {OH_Magic} (0x{OH_Magic:X})"); - Console.WriteLine($" Major linker version: {OH_MajorLinkerVersion} (0x{OH_MajorLinkerVersion:X})"); - Console.WriteLine($" Minor linker version: {OH_MinorLinkerVersion} (0x{OH_MinorLinkerVersion:X})"); - Console.WriteLine($" Size of code section: {OH_SizeOfCode} (0x{OH_SizeOfCode:X})"); - Console.WriteLine($" Size of initialized data: {OH_SizeOfInitializedData} (0x{OH_SizeOfInitializedData:X})"); - Console.WriteLine($" Size of uninitialized data: {OH_SizeOfUninitializedData} (0x{OH_SizeOfUninitializedData:X})"); - Console.WriteLine($" Address of entry point: {OH_AddressOfEntryPoint} (0x{OH_AddressOfEntryPoint:X})"); - Console.WriteLine($" Base of code: {OH_BaseOfCode} (0x{OH_BaseOfCode:X})"); + builder.AppendLine($" Magic: {OH_Magic} (0x{OH_Magic:X})"); + builder.AppendLine($" Major linker version: {OH_MajorLinkerVersion} (0x{OH_MajorLinkerVersion:X})"); + builder.AppendLine($" Minor linker version: {OH_MinorLinkerVersion} (0x{OH_MinorLinkerVersion:X})"); + builder.AppendLine($" Size of code section: {OH_SizeOfCode} (0x{OH_SizeOfCode:X})"); + builder.AppendLine($" Size of initialized data: {OH_SizeOfInitializedData} (0x{OH_SizeOfInitializedData:X})"); + builder.AppendLine($" Size of uninitialized data: {OH_SizeOfUninitializedData} (0x{OH_SizeOfUninitializedData:X})"); + builder.AppendLine($" Address of entry point: {OH_AddressOfEntryPoint} (0x{OH_AddressOfEntryPoint:X})"); + builder.AppendLine($" Base of code: {OH_BaseOfCode} (0x{OH_BaseOfCode:X})"); if (OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Base of data: {OH_BaseOfData} (0x{OH_BaseOfData:X})"); + builder.AppendLine($" Base of data: {OH_BaseOfData} (0x{OH_BaseOfData:X})"); - Console.WriteLine($" Image base: {OH_ImageBase} (0x{OH_ImageBase:X})"); - Console.WriteLine($" Section alignment: {OH_SectionAlignment} (0x{OH_SectionAlignment:X})"); - Console.WriteLine($" File alignment: {OH_FileAlignment} (0x{OH_FileAlignment:X})"); - Console.WriteLine($" Major operating system version: {OH_MajorOperatingSystemVersion} (0x{OH_MajorOperatingSystemVersion:X})"); - Console.WriteLine($" Minor operating system version: {OH_MinorOperatingSystemVersion} (0x{OH_MinorOperatingSystemVersion:X})"); - Console.WriteLine($" Major image version: {OH_MajorImageVersion} (0x{OH_MajorImageVersion:X})"); - Console.WriteLine($" Minor image version: {OH_MinorImageVersion} (0x{OH_MinorImageVersion:X})"); - Console.WriteLine($" Major subsystem version: {OH_MajorSubsystemVersion} (0x{OH_MajorSubsystemVersion:X})"); - Console.WriteLine($" Minor subsystem version: {OH_MinorSubsystemVersion} (0x{OH_MinorSubsystemVersion:X})"); - Console.WriteLine($" Win32 version value: {OH_Win32VersionValue} (0x{OH_Win32VersionValue:X})"); - Console.WriteLine($" Size of image: {OH_SizeOfImage} (0x{OH_SizeOfImage:X})"); - Console.WriteLine($" Size of headers: {OH_SizeOfHeaders} (0x{OH_SizeOfHeaders:X})"); - Console.WriteLine($" Checksum: {OH_CheckSum} (0x{OH_CheckSum:X})"); - Console.WriteLine($" Subsystem: {OH_Subsystem} (0x{OH_Subsystem:X})"); - Console.WriteLine($" DLL characteristics: {OH_DllCharacteristics} (0x{OH_DllCharacteristics:X})"); - Console.WriteLine($" Size of stack reserve: {OH_SizeOfStackReserve} (0x{OH_SizeOfStackReserve:X})"); - Console.WriteLine($" Size of stack commit: {OH_SizeOfStackCommit} (0x{OH_SizeOfStackCommit:X})"); - Console.WriteLine($" Size of heap reserve: {OH_SizeOfHeapReserve} (0x{OH_SizeOfHeapReserve:X})"); - Console.WriteLine($" Size of heap commit: {OH_SizeOfHeapCommit} (0x{OH_SizeOfHeapCommit:X})"); - Console.WriteLine($" Loader flags: {OH_LoaderFlags} (0x{OH_LoaderFlags:X})"); - Console.WriteLine($" Number of data-directory entries: {OH_NumberOfRvaAndSizes} (0x{OH_NumberOfRvaAndSizes:X})"); + builder.AppendLine($" Image base: {OH_ImageBase} (0x{OH_ImageBase:X})"); + builder.AppendLine($" Section alignment: {OH_SectionAlignment} (0x{OH_SectionAlignment:X})"); + builder.AppendLine($" File alignment: {OH_FileAlignment} (0x{OH_FileAlignment:X})"); + builder.AppendLine($" Major operating system version: {OH_MajorOperatingSystemVersion} (0x{OH_MajorOperatingSystemVersion:X})"); + builder.AppendLine($" Minor operating system version: {OH_MinorOperatingSystemVersion} (0x{OH_MinorOperatingSystemVersion:X})"); + builder.AppendLine($" Major image version: {OH_MajorImageVersion} (0x{OH_MajorImageVersion:X})"); + builder.AppendLine($" Minor image version: {OH_MinorImageVersion} (0x{OH_MinorImageVersion:X})"); + builder.AppendLine($" Major subsystem version: {OH_MajorSubsystemVersion} (0x{OH_MajorSubsystemVersion:X})"); + builder.AppendLine($" Minor subsystem version: {OH_MinorSubsystemVersion} (0x{OH_MinorSubsystemVersion:X})"); + builder.AppendLine($" Win32 version value: {OH_Win32VersionValue} (0x{OH_Win32VersionValue:X})"); + builder.AppendLine($" Size of image: {OH_SizeOfImage} (0x{OH_SizeOfImage:X})"); + builder.AppendLine($" Size of headers: {OH_SizeOfHeaders} (0x{OH_SizeOfHeaders:X})"); + builder.AppendLine($" Checksum: {OH_CheckSum} (0x{OH_CheckSum:X})"); + builder.AppendLine($" Subsystem: {OH_Subsystem} (0x{OH_Subsystem:X})"); + builder.AppendLine($" DLL characteristics: {OH_DllCharacteristics} (0x{OH_DllCharacteristics:X})"); + builder.AppendLine($" Size of stack reserve: {OH_SizeOfStackReserve} (0x{OH_SizeOfStackReserve:X})"); + builder.AppendLine($" Size of stack commit: {OH_SizeOfStackCommit} (0x{OH_SizeOfStackCommit:X})"); + builder.AppendLine($" Size of heap reserve: {OH_SizeOfHeapReserve} (0x{OH_SizeOfHeapReserve:X})"); + builder.AppendLine($" Size of heap commit: {OH_SizeOfHeapCommit} (0x{OH_SizeOfHeapCommit:X})"); + builder.AppendLine($" Loader flags: {OH_LoaderFlags} (0x{OH_LoaderFlags:X})"); + builder.AppendLine($" Number of data-directory entries: {OH_NumberOfRvaAndSizes} (0x{OH_NumberOfRvaAndSizes:X})"); if (OH_ExportTable != null) { - Console.WriteLine(" Export Table (1)"); - Console.WriteLine($" Virtual address: {OH_ExportTable.VirtualAddress} (0x{OH_ExportTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ExportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ExportTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ExportTable.Size} (0x{OH_ExportTable.Size:X})"); + builder.AppendLine(" Export Table (1)"); + builder.AppendLine($" Virtual address: {OH_ExportTable.VirtualAddress} (0x{OH_ExportTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ExportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ExportTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ExportTable.Size} (0x{OH_ExportTable.Size:X})"); } if (OH_ImportTable != null) { - Console.WriteLine(" Import Table (2)"); - Console.WriteLine($" Virtual address: {OH_ImportTable.VirtualAddress} (0x{OH_ImportTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ImportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ImportTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ImportTable.Size} (0x{OH_ImportTable.Size:X})"); + builder.AppendLine(" Import Table (2)"); + builder.AppendLine($" Virtual address: {OH_ImportTable.VirtualAddress} (0x{OH_ImportTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ImportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ImportTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ImportTable.Size} (0x{OH_ImportTable.Size:X})"); } if (OH_ResourceTable != null) { - Console.WriteLine(" Resource Table (3)"); - Console.WriteLine($" Virtual address: {OH_ResourceTable.VirtualAddress} (0x{OH_ResourceTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ResourceTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ResourceTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ResourceTable.Size} (0x{OH_ResourceTable.Size:X})"); + builder.AppendLine(" Resource Table (3)"); + builder.AppendLine($" Virtual address: {OH_ResourceTable.VirtualAddress} (0x{OH_ResourceTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ResourceTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ResourceTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ResourceTable.Size} (0x{OH_ResourceTable.Size:X})"); } if (OH_ExceptionTable != null) { - Console.WriteLine(" Exception Table (4)"); - Console.WriteLine($" Virtual address: {OH_ExceptionTable.VirtualAddress} (0x{OH_ExceptionTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ExceptionTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ExceptionTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ExceptionTable.Size} (0x{OH_ExceptionTable.Size:X})"); + builder.AppendLine(" Exception Table (4)"); + builder.AppendLine($" Virtual address: {OH_ExceptionTable.VirtualAddress} (0x{OH_ExceptionTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ExceptionTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ExceptionTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ExceptionTable.Size} (0x{OH_ExceptionTable.Size:X})"); } if (OH_CertificateTable != null) { - Console.WriteLine(" Certificate Table (5)"); - Console.WriteLine($" Virtual address: {OH_CertificateTable.VirtualAddress} (0x{OH_CertificateTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_CertificateTable.Size} (0x{OH_CertificateTable.Size:X})"); + builder.AppendLine(" Certificate Table (5)"); + builder.AppendLine($" Virtual address: {OH_CertificateTable.VirtualAddress} (0x{OH_CertificateTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_CertificateTable.Size} (0x{OH_CertificateTable.Size:X})"); } if (OH_BaseRelocationTable != null) { - Console.WriteLine(" Base Relocation Table (6)"); - Console.WriteLine($" Virtual address: {OH_BaseRelocationTable.VirtualAddress} (0x{OH_BaseRelocationTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_BaseRelocationTable.Size} (0x{OH_BaseRelocationTable.Size:X})"); + builder.AppendLine(" Base Relocation Table (6)"); + builder.AppendLine($" Virtual address: {OH_BaseRelocationTable.VirtualAddress} (0x{OH_BaseRelocationTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_BaseRelocationTable.Size} (0x{OH_BaseRelocationTable.Size:X})"); } if (OH_Debug != null) { - Console.WriteLine(" Debug Table (7)"); - Console.WriteLine($" Virtual address: {OH_Debug.VirtualAddress} (0x{OH_Debug.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_Debug.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_Debug.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_Debug.Size} (0x{OH_Debug.Size:X})"); + builder.AppendLine(" Debug Table (7)"); + builder.AppendLine($" Virtual address: {OH_Debug.VirtualAddress} (0x{OH_Debug.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_Debug.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_Debug.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_Debug.Size} (0x{OH_Debug.Size:X})"); } if (OH_NumberOfRvaAndSizes >= 8) { - Console.WriteLine(" Architecture Table (8)"); - Console.WriteLine($" Virtual address: 0 (0x00000000)"); - Console.WriteLine($" Physical address: 0 (0x00000000)"); - Console.WriteLine($" Size: 0 (0x00000000)"); + builder.AppendLine(" Architecture Table (8)"); + builder.AppendLine($" Virtual address: 0 (0x00000000)"); + builder.AppendLine($" Physical address: 0 (0x00000000)"); + builder.AppendLine($" Size: 0 (0x00000000)"); } if (OH_GlobalPtr != null) { - Console.WriteLine(" Global Pointer Register (9)"); - Console.WriteLine($" Virtual address: {OH_GlobalPtr.VirtualAddress} (0x{OH_GlobalPtr.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_GlobalPtr.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_GlobalPtr.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_GlobalPtr.Size} (0x{OH_GlobalPtr.Size:X})"); + builder.AppendLine(" Global Pointer Register (9)"); + builder.AppendLine($" Virtual address: {OH_GlobalPtr.VirtualAddress} (0x{OH_GlobalPtr.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_GlobalPtr.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_GlobalPtr.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_GlobalPtr.Size} (0x{OH_GlobalPtr.Size:X})"); } if (OH_ThreadLocalStorageTable != null) { - Console.WriteLine(" Thread Local Storage (TLS) Table (10)"); - Console.WriteLine($" Virtual address: {OH_ThreadLocalStorageTable.VirtualAddress} (0x{OH_ThreadLocalStorageTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ThreadLocalStorageTable.Size} (0x{OH_ThreadLocalStorageTable.Size:X})"); + builder.AppendLine(" Thread Local Storage (TLS) Table (10)"); + builder.AppendLine($" Virtual address: {OH_ThreadLocalStorageTable.VirtualAddress} (0x{OH_ThreadLocalStorageTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ThreadLocalStorageTable.Size} (0x{OH_ThreadLocalStorageTable.Size:X})"); } if (OH_LoadConfigTable != null) { - Console.WriteLine(" Load Config Table (11)"); - Console.WriteLine($" Virtual address: {OH_LoadConfigTable.VirtualAddress} (0x{OH_LoadConfigTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_LoadConfigTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_LoadConfigTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_LoadConfigTable.Size} (0x{OH_LoadConfigTable.Size:X})"); + builder.AppendLine(" Load Config Table (11)"); + builder.AppendLine($" Virtual address: {OH_LoadConfigTable.VirtualAddress} (0x{OH_LoadConfigTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_LoadConfigTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_LoadConfigTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_LoadConfigTable.Size} (0x{OH_LoadConfigTable.Size:X})"); } if (OH_BoundImport != null) { - Console.WriteLine(" Bound Import Table (12)"); - Console.WriteLine($" Virtual address: {OH_BoundImport.VirtualAddress} (0x{OH_BoundImport.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_BoundImport.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_BoundImport.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_BoundImport.Size} (0x{OH_BoundImport.Size:X})"); + builder.AppendLine(" Bound Import Table (12)"); + builder.AppendLine($" Virtual address: {OH_BoundImport.VirtualAddress} (0x{OH_BoundImport.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_BoundImport.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_BoundImport.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_BoundImport.Size} (0x{OH_BoundImport.Size:X})"); } if (OH_ImportAddressTable != null) { - Console.WriteLine(" Import Address Table (13)"); - Console.WriteLine($" Virtual address: {OH_ImportAddressTable.VirtualAddress} (0x{OH_ImportAddressTable.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_ImportAddressTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ImportAddressTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_ImportAddressTable.Size} (0x{OH_ImportAddressTable.Size:X})"); + builder.AppendLine(" Import Address Table (13)"); + builder.AppendLine($" Virtual address: {OH_ImportAddressTable.VirtualAddress} (0x{OH_ImportAddressTable.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_ImportAddressTable.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_ImportAddressTable.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_ImportAddressTable.Size} (0x{OH_ImportAddressTable.Size:X})"); } if (OH_DelayImportDescriptor != null) { - Console.WriteLine(" Delay Import Descriptior (14)"); - Console.WriteLine($" Virtual address: {OH_DelayImportDescriptor.VirtualAddress} (0x{OH_DelayImportDescriptor.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_DelayImportDescriptor.Size} (0x{OH_DelayImportDescriptor.Size:X})"); + builder.AppendLine(" Delay Import Descriptior (14)"); + builder.AppendLine($" Virtual address: {OH_DelayImportDescriptor.VirtualAddress} (0x{OH_DelayImportDescriptor.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_DelayImportDescriptor.Size} (0x{OH_DelayImportDescriptor.Size:X})"); } if (OH_CLRRuntimeHeader != null) { - Console.WriteLine(" CLR Runtime Header (15)"); - Console.WriteLine($" Virtual address: {OH_CLRRuntimeHeader.VirtualAddress} (0x{OH_CLRRuntimeHeader.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {OH_CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size: {OH_CLRRuntimeHeader.Size} (0x{OH_CLRRuntimeHeader.Size:X})"); + builder.AppendLine(" CLR Runtime Header (15)"); + builder.AppendLine($" Virtual address: {OH_CLRRuntimeHeader.VirtualAddress} (0x{OH_CLRRuntimeHeader.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {OH_CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{OH_CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size: {OH_CLRRuntimeHeader.Size} (0x{OH_CLRRuntimeHeader.Size:X})"); } if (OH_NumberOfRvaAndSizes >= 16) { - Console.WriteLine(" Reserved (16)"); - Console.WriteLine($" Virtual address: 0 (0x00000000)"); - Console.WriteLine($" Physical address: 0 (0x00000000)"); - Console.WriteLine($" Size: 0 (0x00000000)"); + builder.AppendLine(" Reserved (16)"); + builder.AppendLine($" Virtual address: 0 (0x00000000)"); + builder.AppendLine($" Physical address: 0 (0x00000000)"); + builder.AppendLine($" Size: 0 (0x00000000)"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print section table information /// - private void PrintSectionTable() + /// StringBuilder to append information to + private void PrintSectionTable(StringBuilder builder) { - Console.WriteLine(" Section Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Section Table Information:"); + builder.AppendLine(" -------------------------"); if (NumberOfSections == 0 || SectionTable.Length == 0) { - Console.WriteLine(" No section table items"); + builder.AppendLine(" No section table items"); } else { for (int i = 0; i < SectionTable.Length; i++) { var entry = SectionTable[i]; - Console.WriteLine($" Section Table Entry {i}"); - Console.WriteLine($" Name: {Encoding.UTF8.GetString(entry.Name).TrimEnd('\0')}"); - Console.WriteLine($" Virtual size: {entry.VirtualSize} (0x{entry.VirtualSize:X})"); - Console.WriteLine($" Virtual address: {entry.VirtualAddress} (0x{entry.VirtualAddress:X})"); - Console.WriteLine($" Physical address: {entry.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{entry.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Size of raw data: {entry.SizeOfRawData} (0x{entry.SizeOfRawData:X})"); - Console.WriteLine($" Pointer to raw data: {entry.PointerToRawData} (0x{entry.PointerToRawData:X})"); - Console.WriteLine($" Pointer to relocations: {entry.PointerToRelocations} (0x{entry.PointerToRelocations:X})"); - Console.WriteLine($" Pointer to linenumbers: {entry.PointerToLinenumbers} (0x{entry.PointerToLinenumbers:X})"); - Console.WriteLine($" Number of relocations: {entry.NumberOfRelocations} (0x{entry.NumberOfRelocations:X})"); - Console.WriteLine($" Number of linenumbers: {entry.NumberOfLinenumbers} (0x{entry.NumberOfLinenumbers:X})"); - Console.WriteLine($" Characteristics: {entry.Characteristics} (0x{entry.Characteristics:X})"); + builder.AppendLine($" Section Table Entry {i}"); + builder.AppendLine($" Name: {Encoding.UTF8.GetString(entry.Name).TrimEnd('\0')}"); + builder.AppendLine($" Virtual size: {entry.VirtualSize} (0x{entry.VirtualSize:X})"); + builder.AppendLine($" Virtual address: {entry.VirtualAddress} (0x{entry.VirtualAddress:X})"); + builder.AppendLine($" Physical address: {entry.VirtualAddress.ConvertVirtualAddress(SectionTable)} (0x{entry.VirtualAddress.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Size of raw data: {entry.SizeOfRawData} (0x{entry.SizeOfRawData:X})"); + builder.AppendLine($" Pointer to raw data: {entry.PointerToRawData} (0x{entry.PointerToRawData:X})"); + builder.AppendLine($" Pointer to relocations: {entry.PointerToRelocations} (0x{entry.PointerToRelocations:X})"); + builder.AppendLine($" Pointer to linenumbers: {entry.PointerToLinenumbers} (0x{entry.PointerToLinenumbers:X})"); + builder.AppendLine($" Number of relocations: {entry.NumberOfRelocations} (0x{entry.NumberOfRelocations:X})"); + builder.AppendLine($" Number of linenumbers: {entry.NumberOfLinenumbers} (0x{entry.NumberOfLinenumbers:X})"); + builder.AppendLine($" Characteristics: {entry.Characteristics} (0x{entry.Characteristics:X})"); // TODO: Add COFFRelocations // TODO: Add COFFLineNumbers } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print COFF symbol table information /// - private void PrintCOFFSymbolTable() + /// StringBuilder to append information to + private void PrintCOFFSymbolTable(StringBuilder builder) { - Console.WriteLine(" COFF Symbol Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" COFF Symbol Table Information:"); + builder.AppendLine(" -------------------------"); if (PointerToSymbolTable == 0 || NumberOfSymbols == 0 || COFFSymbolTable == null || COFFSymbolTable.Length == 0) { - Console.WriteLine(" No COFF symbol table items"); + builder.AppendLine(" No COFF symbol table items"); } else { @@ -1400,23 +1395,23 @@ namespace BurnOutSharp.Wrappers for (int i = 0; i < COFFSymbolTable.Length; i++) { var entry = COFFSymbolTable[i]; - Console.WriteLine($" COFF Symbol Table Entry {i} (Subtype {currentSymbolType})"); + builder.AppendLine($" COFF Symbol Table Entry {i} (Subtype {currentSymbolType})"); if (currentSymbolType == 0) { if (entry.ShortName != null) { - Console.WriteLine($" Short name: {Encoding.UTF8.GetString(entry.ShortName).TrimEnd('\0')}"); + builder.AppendLine($" Short name: {Encoding.UTF8.GetString(entry.ShortName).TrimEnd('\0')}"); } else { - Console.WriteLine($" Zeroes: {entry.Zeroes} (0x{entry.Zeroes:X})"); - Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + builder.AppendLine($" Zeroes: {entry.Zeroes} (0x{entry.Zeroes:X})"); + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); } - Console.WriteLine($" Value: {entry.Value} (0x{entry.Value:X})"); - Console.WriteLine($" Section number: {entry.SectionNumber} (0x{entry.SectionNumber:X})"); - Console.WriteLine($" Symbol type: {entry.SymbolType} (0x{entry.SymbolType:X})"); - Console.WriteLine($" Storage class: {entry.StorageClass} (0x{entry.StorageClass:X})"); - Console.WriteLine($" Number of aux symbols: {entry.NumberOfAuxSymbols} (0x{entry.NumberOfAuxSymbols:X})"); + builder.AppendLine($" Value: {entry.Value} (0x{entry.Value:X})"); + builder.AppendLine($" Section number: {entry.SectionNumber} (0x{entry.SectionNumber:X})"); + builder.AppendLine($" Symbol type: {entry.SymbolType} (0x{entry.SymbolType:X})"); + builder.AppendLine($" Storage class: {entry.StorageClass} (0x{entry.StorageClass:X})"); + builder.AppendLine($" Number of aux symbols: {entry.NumberOfAuxSymbols} (0x{entry.NumberOfAuxSymbols:X})"); auxSymbolsRemaining = entry.NumberOfAuxSymbols; if (auxSymbolsRemaining == 0) @@ -1458,51 +1453,51 @@ namespace BurnOutSharp.Wrappers } else if (currentSymbolType == 1) { - Console.WriteLine($" Tag index: {entry.AuxFormat1TagIndex} (0x{entry.AuxFormat1TagIndex:X})"); - Console.WriteLine($" Total size: {entry.AuxFormat1TotalSize} (0x{entry.AuxFormat1TotalSize:X})"); - Console.WriteLine($" Pointer to linenumber: {entry.AuxFormat1PointerToLinenumber} (0x{entry.AuxFormat1PointerToLinenumber:X})"); - Console.WriteLine($" Pointer to next function: {entry.AuxFormat1PointerToNextFunction} (0x{entry.AuxFormat1PointerToNextFunction:X})"); - Console.WriteLine($" Unused: {entry.AuxFormat1Unused} (0x{entry.AuxFormat1Unused:X})"); + builder.AppendLine($" Tag index: {entry.AuxFormat1TagIndex} (0x{entry.AuxFormat1TagIndex:X})"); + builder.AppendLine($" Total size: {entry.AuxFormat1TotalSize} (0x{entry.AuxFormat1TotalSize:X})"); + builder.AppendLine($" Pointer to linenumber: {entry.AuxFormat1PointerToLinenumber} (0x{entry.AuxFormat1PointerToLinenumber:X})"); + builder.AppendLine($" Pointer to next function: {entry.AuxFormat1PointerToNextFunction} (0x{entry.AuxFormat1PointerToNextFunction:X})"); + builder.AppendLine($" Unused: {entry.AuxFormat1Unused} (0x{entry.AuxFormat1Unused:X})"); auxSymbolsRemaining--; } else if (currentSymbolType == 2) { - Console.WriteLine($" Unused: {entry.AuxFormat2Unused1} (0x{entry.AuxFormat2Unused1:X})"); - Console.WriteLine($" Linenumber: {entry.AuxFormat2Linenumber} (0x{entry.AuxFormat2Linenumber:X})"); - Console.WriteLine($" Unused: {entry.AuxFormat2Unused2} (0x{entry.AuxFormat2Unused2:X})"); - Console.WriteLine($" Pointer to next function: {entry.AuxFormat2PointerToNextFunction} (0x{entry.AuxFormat2PointerToNextFunction:X})"); - Console.WriteLine($" Unused: {entry.AuxFormat2Unused3} (0x{entry.AuxFormat2Unused3:X})"); + builder.AppendLine($" Unused: {entry.AuxFormat2Unused1} (0x{entry.AuxFormat2Unused1:X})"); + builder.AppendLine($" Linenumber: {entry.AuxFormat2Linenumber} (0x{entry.AuxFormat2Linenumber:X})"); + builder.AppendLine($" Unused: {entry.AuxFormat2Unused2} (0x{entry.AuxFormat2Unused2:X})"); + builder.AppendLine($" Pointer to next function: {entry.AuxFormat2PointerToNextFunction} (0x{entry.AuxFormat2PointerToNextFunction:X})"); + builder.AppendLine($" Unused: {entry.AuxFormat2Unused3} (0x{entry.AuxFormat2Unused3:X})"); auxSymbolsRemaining--; } else if (currentSymbolType == 3) { - Console.WriteLine($" Tag index: {entry.AuxFormat3TagIndex} (0x{entry.AuxFormat3TagIndex:X})"); - Console.WriteLine($" Characteristics: {entry.AuxFormat3Characteristics} (0x{entry.AuxFormat3Characteristics:X})"); - Console.WriteLine($" Unused: {BitConverter.ToString(entry.AuxFormat3Unused).Replace("-", string.Empty)}"); + builder.AppendLine($" Tag index: {entry.AuxFormat3TagIndex} (0x{entry.AuxFormat3TagIndex:X})"); + builder.AppendLine($" Characteristics: {entry.AuxFormat3Characteristics} (0x{entry.AuxFormat3Characteristics:X})"); + builder.AppendLine($" Unused: {BitConverter.ToString(entry.AuxFormat3Unused).Replace("-", string.Empty)}"); auxSymbolsRemaining--; } else if (currentSymbolType == 4) { - Console.WriteLine($" File name: {Encoding.ASCII.GetString(entry.AuxFormat4FileName).TrimEnd('\0')}"); + builder.AppendLine($" File name: {Encoding.ASCII.GetString(entry.AuxFormat4FileName).TrimEnd('\0')}"); auxSymbolsRemaining--; } else if (currentSymbolType == 5) { - Console.WriteLine($" Length: {entry.AuxFormat5Length} (0x{entry.AuxFormat5Length:X})"); - Console.WriteLine($" Number of relocations: {entry.AuxFormat5NumberOfRelocations} (0x{entry.AuxFormat5NumberOfRelocations:X})"); - Console.WriteLine($" Number of linenumbers: {entry.AuxFormat5NumberOfLinenumbers} (0x{entry.AuxFormat5NumberOfLinenumbers:X})"); - Console.WriteLine($" Checksum: {entry.AuxFormat5CheckSum} (0x{entry.AuxFormat5CheckSum:X})"); - Console.WriteLine($" Number: {entry.AuxFormat5Number} (0x{entry.AuxFormat5Number:X})"); - Console.WriteLine($" Selection: {entry.AuxFormat5Selection} (0x{entry.AuxFormat5Selection:X})"); - Console.WriteLine($" Unused: {BitConverter.ToString(entry.AuxFormat5Unused).Replace("-", string.Empty)}"); + builder.AppendLine($" Length: {entry.AuxFormat5Length} (0x{entry.AuxFormat5Length:X})"); + builder.AppendLine($" Number of relocations: {entry.AuxFormat5NumberOfRelocations} (0x{entry.AuxFormat5NumberOfRelocations:X})"); + builder.AppendLine($" Number of linenumbers: {entry.AuxFormat5NumberOfLinenumbers} (0x{entry.AuxFormat5NumberOfLinenumbers:X})"); + builder.AppendLine($" Checksum: {entry.AuxFormat5CheckSum} (0x{entry.AuxFormat5CheckSum:X})"); + builder.AppendLine($" Number: {entry.AuxFormat5Number} (0x{entry.AuxFormat5Number:X})"); + builder.AppendLine($" Selection: {entry.AuxFormat5Selection} (0x{entry.AuxFormat5Selection:X})"); + builder.AppendLine($" Unused: {BitConverter.ToString(entry.AuxFormat5Unused).Replace("-", string.Empty)}"); auxSymbolsRemaining--; } else if (currentSymbolType == 6) { - Console.WriteLine($" Aux type: {entry.AuxFormat6AuxType} (0x{entry.AuxFormat6AuxType:X})"); - Console.WriteLine($" Reserved: {entry.AuxFormat6Reserved1} (0x{entry.AuxFormat6Reserved1:X})"); - Console.WriteLine($" Symbol table index: {entry.AuxFormat6SymbolTableIndex} (0x{entry.AuxFormat6SymbolTableIndex:X})"); - Console.WriteLine($" Reserved: {BitConverter.ToString(entry.AuxFormat6Reserved2).Replace("-", string.Empty)}"); + builder.AppendLine($" Aux type: {entry.AuxFormat6AuxType} (0x{entry.AuxFormat6AuxType:X})"); + builder.AppendLine($" Reserved: {entry.AuxFormat6Reserved1} (0x{entry.AuxFormat6Reserved1:X})"); + builder.AppendLine($" Symbol table index: {entry.AuxFormat6SymbolTableIndex} (0x{entry.AuxFormat6SymbolTableIndex:X})"); + builder.AppendLine($" Reserved: {BitConverter.ToString(entry.AuxFormat6Reserved2).Replace("-", string.Empty)}"); auxSymbolsRemaining--; } @@ -1511,174 +1506,178 @@ namespace BurnOutSharp.Wrappers currentSymbolType = 0; } - Console.WriteLine(); - Console.WriteLine(" COFF String Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine(" COFF String Table Information:"); + builder.AppendLine(" -------------------------"); if (COFFStringTable == null || COFFStringTable.Strings == null || COFFStringTable.Strings.Length == 0) { - Console.WriteLine(" No COFF string table items"); + builder.AppendLine(" No COFF string table items"); } else { - Console.WriteLine($" Total size: {COFFStringTable.TotalSize} (0x{COFFStringTable.TotalSize:X})"); + builder.AppendLine($" Total size: {COFFStringTable.TotalSize} (0x{COFFStringTable.TotalSize:X})"); for (int i = 0; i < COFFStringTable.Strings.Length; i++) { string entry = COFFStringTable.Strings[i]; - Console.WriteLine($" COFF String Table Entry {i})"); - Console.WriteLine($" Value: {entry}"); + builder.AppendLine($" COFF String Table Entry {i})"); + builder.AppendLine($" Value: {entry}"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print attribute certificate table information /// - private void PrintAttributeCertificateTable() + /// StringBuilder to append information to + private void PrintAttributeCertificateTable(StringBuilder builder) { - Console.WriteLine(" Attribute Certificate Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Attribute Certificate Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_CertificateTable == null || OH_CertificateTable.VirtualAddress == 0 || AttributeCertificateTable.Length == 0) { - Console.WriteLine(" No attribute certificate table items"); + builder.AppendLine(" No attribute certificate table items"); } else { for (int i = 0; i < AttributeCertificateTable.Length; i++) { var entry = AttributeCertificateTable[i]; - Console.WriteLine($" Attribute Certificate Table Entry {i}"); - Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); - Console.WriteLine($" Revision: {entry.Revision} (0x{entry.Revision:X})"); - Console.WriteLine($" Certificate type: {entry.CertificateType} (0x{entry.CertificateType:X})"); - Console.WriteLine(); + builder.AppendLine($" Attribute Certificate Table Entry {i}"); + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); + builder.AppendLine($" Revision: {entry.Revision} (0x{entry.Revision:X})"); + builder.AppendLine($" Certificate type: {entry.CertificateType} (0x{entry.CertificateType:X})"); + builder.AppendLine(); if (entry.CertificateType == Models.PortableExecutable.WindowsCertificateType.WIN_CERT_TYPE_PKCS_SIGNED_DATA) { - Console.WriteLine(" Certificate Data [Formatted]"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Certificate Data [Formatted]"); + builder.AppendLine(" -------------------------"); var topLevelValues = AbstractSyntaxNotationOne.Parse(entry.Certificate, pointer: 0); if (topLevelValues == null) { - Console.WriteLine(" INVALID DATA FOUND"); - Console.WriteLine($" {BitConverter.ToString(entry.Certificate).Replace("-", string.Empty)}"); + builder.AppendLine(" INVALID DATA FOUND"); + builder.AppendLine($" {BitConverter.ToString(entry.Certificate).Replace("-", string.Empty)}"); } else { foreach (TypeLengthValue tlv in topLevelValues) { string tlvString = tlv.Format(paddingLevel: 4); - Console.WriteLine(tlvString); + builder.AppendLine(tlvString); } } } else { - Console.WriteLine($" Certificate Data [Binary]"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Certificate Data [Binary]"); + builder.AppendLine(" -------------------------"); try { - Console.WriteLine($" {BitConverter.ToString(entry.Certificate).Replace("-", string.Empty)}"); + builder.AppendLine($" {BitConverter.ToString(entry.Certificate).Replace("-", string.Empty)}"); } catch { - Console.WriteLine($" [DATA TOO LARGE TO FORMAT]"); + builder.AppendLine($" [DATA TOO LARGE TO FORMAT]"); } } - Console.WriteLine(); + builder.AppendLine(); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print delay-load directory table information /// - private void PrintDelayLoadDirectoryTable() + /// StringBuilder to append information to + private void PrintDelayLoadDirectoryTable(StringBuilder builder) { - Console.WriteLine(" Delay-Load Directory Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Delay-Load Directory Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_DelayImportDescriptor == null || OH_DelayImportDescriptor.VirtualAddress == 0 || DelayLoadDirectoryTable == null) { - Console.WriteLine(" No delay-load directory table items"); + builder.AppendLine(" No delay-load directory table items"); } else { - Console.WriteLine($" Attributes: {DelayLoadDirectoryTable.Attributes} (0x{DelayLoadDirectoryTable.Attributes:X})"); - Console.WriteLine($" Name RVA: {DelayLoadDirectoryTable.Name} (0x{DelayLoadDirectoryTable.Name:X})"); - Console.WriteLine($" Module handle: {DelayLoadDirectoryTable.ModuleHandle} (0x{DelayLoadDirectoryTable.ModuleHandle:X})"); - Console.WriteLine($" Delay import address table RVA: {DelayLoadDirectoryTable.DelayImportAddressTable} (0x{DelayLoadDirectoryTable.DelayImportAddressTable:X})"); - Console.WriteLine($" Delay import name table RVA: {DelayLoadDirectoryTable.DelayImportNameTable} (0x{DelayLoadDirectoryTable.DelayImportNameTable:X})"); - Console.WriteLine($" Bound delay import table RVA: {DelayLoadDirectoryTable.BoundDelayImportTable} (0x{DelayLoadDirectoryTable.BoundDelayImportTable:X})"); - Console.WriteLine($" Unload delay import table RVA: {DelayLoadDirectoryTable.UnloadDelayImportTable} (0x{DelayLoadDirectoryTable.UnloadDelayImportTable:X})"); - Console.WriteLine($" Timestamp: {DelayLoadDirectoryTable.TimeStamp} (0x{DelayLoadDirectoryTable.TimeStamp:X})"); + builder.AppendLine($" Attributes: {DelayLoadDirectoryTable.Attributes} (0x{DelayLoadDirectoryTable.Attributes:X})"); + builder.AppendLine($" Name RVA: {DelayLoadDirectoryTable.Name} (0x{DelayLoadDirectoryTable.Name:X})"); + builder.AppendLine($" Module handle: {DelayLoadDirectoryTable.ModuleHandle} (0x{DelayLoadDirectoryTable.ModuleHandle:X})"); + builder.AppendLine($" Delay import address table RVA: {DelayLoadDirectoryTable.DelayImportAddressTable} (0x{DelayLoadDirectoryTable.DelayImportAddressTable:X})"); + builder.AppendLine($" Delay import name table RVA: {DelayLoadDirectoryTable.DelayImportNameTable} (0x{DelayLoadDirectoryTable.DelayImportNameTable:X})"); + builder.AppendLine($" Bound delay import table RVA: {DelayLoadDirectoryTable.BoundDelayImportTable} (0x{DelayLoadDirectoryTable.BoundDelayImportTable:X})"); + builder.AppendLine($" Unload delay import table RVA: {DelayLoadDirectoryTable.UnloadDelayImportTable} (0x{DelayLoadDirectoryTable.UnloadDelayImportTable:X})"); + builder.AppendLine($" Timestamp: {DelayLoadDirectoryTable.TimeStamp} (0x{DelayLoadDirectoryTable.TimeStamp:X})"); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print base relocation table information /// - private void PrintBaseRelocationTable() + /// StringBuilder to append information to + private void PrintBaseRelocationTable(StringBuilder builder) { - Console.WriteLine(" Base Relocation Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Base Relocation Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_BaseRelocationTable == null || OH_BaseRelocationTable.VirtualAddress == 0 || BaseRelocationTable == null) { - Console.WriteLine(" No base relocation table items"); + builder.AppendLine(" No base relocation table items"); } else { for (int i = 0; i < BaseRelocationTable.Length; i++) { var baseRelocationTableEntry = BaseRelocationTable[i]; - Console.WriteLine($" Base Relocation Table Entry {i}"); - Console.WriteLine($" Page RVA: {baseRelocationTableEntry.PageRVA} (0x{baseRelocationTableEntry.PageRVA:X})"); - Console.WriteLine($" Page physical address: {baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable)} (0x{baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Block size: {baseRelocationTableEntry.BlockSize} (0x{baseRelocationTableEntry.BlockSize:X})"); + builder.AppendLine($" Base Relocation Table Entry {i}"); + builder.AppendLine($" Page RVA: {baseRelocationTableEntry.PageRVA} (0x{baseRelocationTableEntry.PageRVA:X})"); + builder.AppendLine($" Page physical address: {baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable)} (0x{baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Block size: {baseRelocationTableEntry.BlockSize} (0x{baseRelocationTableEntry.BlockSize:X})"); - Console.WriteLine($" Base Relocation Table {i} Type and Offset Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine($" Base Relocation Table {i} Type and Offset Information:"); + builder.AppendLine(" -------------------------"); if (baseRelocationTableEntry.TypeOffsetFieldEntries == null || baseRelocationTableEntry.TypeOffsetFieldEntries.Length == 0) { - Console.WriteLine(" No base relocation table type and offset entries"); + builder.AppendLine(" No base relocation table type and offset entries"); } else { for (int j = 0; j < baseRelocationTableEntry.TypeOffsetFieldEntries.Length; j++) { var typeOffsetFieldEntry = baseRelocationTableEntry.TypeOffsetFieldEntries[j]; - Console.WriteLine($" Type and Offset Entry {j}"); - Console.WriteLine($" Type: {typeOffsetFieldEntry.BaseRelocationType} (0x{typeOffsetFieldEntry.BaseRelocationType:X})"); - Console.WriteLine($" Offset: {typeOffsetFieldEntry.Offset} (0x{typeOffsetFieldEntry.Offset:X})"); + builder.AppendLine($" Type and Offset Entry {j}"); + builder.AppendLine($" Type: {typeOffsetFieldEntry.BaseRelocationType} (0x{typeOffsetFieldEntry.BaseRelocationType:X})"); + builder.AppendLine($" Offset: {typeOffsetFieldEntry.Offset} (0x{typeOffsetFieldEntry.Offset:X})"); } } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print debug table information /// - private void PrintDebugTable() + /// StringBuilder to append information to + private void PrintDebugTable(StringBuilder builder) { - Console.WriteLine(" Debug Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Debug Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_Debug == null || OH_Debug.VirtualAddress == 0 || DebugTable == null) { - Console.WriteLine(" No debug table items"); + builder.AppendLine(" No debug table items"); } else { @@ -1686,167 +1685,169 @@ namespace BurnOutSharp.Wrappers for (int i = 0; i < DebugTable.DebugDirectoryTable.Length; i++) { var debugDirectoryEntry = DebugTable.DebugDirectoryTable[i]; - Console.WriteLine($" Debug Directory Table Entry {i}"); - Console.WriteLine($" Characteristics: {debugDirectoryEntry.Characteristics} (0x{debugDirectoryEntry.Characteristics:X})"); - Console.WriteLine($" Time/Date stamp: {debugDirectoryEntry.TimeDateStamp} (0x{debugDirectoryEntry.TimeDateStamp:X})"); - Console.WriteLine($" Major version: {debugDirectoryEntry.MajorVersion} (0x{debugDirectoryEntry.MajorVersion:X})"); - Console.WriteLine($" Minor version: {debugDirectoryEntry.MinorVersion} (0x{debugDirectoryEntry.MinorVersion:X})"); - Console.WriteLine($" Debug type: {debugDirectoryEntry.DebugType} (0x{debugDirectoryEntry.DebugType:X})"); - Console.WriteLine($" Size of data: {debugDirectoryEntry.SizeOfData} (0x{debugDirectoryEntry.SizeOfData:X})"); - Console.WriteLine($" Address of raw data: {debugDirectoryEntry.AddressOfRawData} (0x{debugDirectoryEntry.AddressOfRawData:X})"); - Console.WriteLine($" Pointer to raw data: {debugDirectoryEntry.PointerToRawData} (0x{debugDirectoryEntry.PointerToRawData:X})"); + builder.AppendLine($" Debug Directory Table Entry {i}"); + builder.AppendLine($" Characteristics: {debugDirectoryEntry.Characteristics} (0x{debugDirectoryEntry.Characteristics:X})"); + builder.AppendLine($" Time/Date stamp: {debugDirectoryEntry.TimeDateStamp} (0x{debugDirectoryEntry.TimeDateStamp:X})"); + builder.AppendLine($" Major version: {debugDirectoryEntry.MajorVersion} (0x{debugDirectoryEntry.MajorVersion:X})"); + builder.AppendLine($" Minor version: {debugDirectoryEntry.MinorVersion} (0x{debugDirectoryEntry.MinorVersion:X})"); + builder.AppendLine($" Debug type: {debugDirectoryEntry.DebugType} (0x{debugDirectoryEntry.DebugType:X})"); + builder.AppendLine($" Size of data: {debugDirectoryEntry.SizeOfData} (0x{debugDirectoryEntry.SizeOfData:X})"); + builder.AppendLine($" Address of raw data: {debugDirectoryEntry.AddressOfRawData} (0x{debugDirectoryEntry.AddressOfRawData:X})"); + builder.AppendLine($" Pointer to raw data: {debugDirectoryEntry.PointerToRawData} (0x{debugDirectoryEntry.PointerToRawData:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print export table information /// - private void PrintExportTable() + /// StringBuilder to append information to + private void PrintExportTable(StringBuilder builder) { - Console.WriteLine(" Export Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Export Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_ExportTable == null || OH_ExportTable.VirtualAddress == 0 || ExportTable == null) { - Console.WriteLine(" No export table items"); + builder.AppendLine(" No export table items"); } else { - Console.WriteLine(); - Console.WriteLine(" Export Directory Table Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Export flags: {ExportTable.ExportDirectoryTable.ExportFlags} (0x{ExportTable.ExportDirectoryTable.ExportFlags:X})"); - Console.WriteLine($" Time/Date stamp: {ExportTable.ExportDirectoryTable.TimeDateStamp} (0x{ExportTable.ExportDirectoryTable.TimeDateStamp:X})"); - Console.WriteLine($" Major version: {ExportTable.ExportDirectoryTable.MajorVersion} (0x{ExportTable.ExportDirectoryTable.MajorVersion:X})"); - Console.WriteLine($" Minor version: {ExportTable.ExportDirectoryTable.MinorVersion} (0x{ExportTable.ExportDirectoryTable.MinorVersion:X})"); - Console.WriteLine($" Name RVA: {ExportTable.ExportDirectoryTable.NameRVA} (0x{ExportTable.ExportDirectoryTable.NameRVA:X})"); - Console.WriteLine($" Name: {ExportTable.ExportDirectoryTable.Name}"); - Console.WriteLine($" Ordinal base: {ExportTable.ExportDirectoryTable.OrdinalBase} (0x{ExportTable.ExportDirectoryTable.OrdinalBase:X})"); - Console.WriteLine($" Address table entries: {ExportTable.ExportDirectoryTable.AddressTableEntries} (0x{ExportTable.ExportDirectoryTable.AddressTableEntries:X})"); - Console.WriteLine($" Number of name pointers: {ExportTable.ExportDirectoryTable.NumberOfNamePointers} (0x{ExportTable.ExportDirectoryTable.NumberOfNamePointers:X})"); - Console.WriteLine($" Export address table RVA: {ExportTable.ExportDirectoryTable.ExportAddressTableRVA} (0x{ExportTable.ExportDirectoryTable.ExportAddressTableRVA:X})"); - Console.WriteLine($" Name pointer table RVA: {ExportTable.ExportDirectoryTable.NamePointerRVA} (0x{ExportTable.ExportDirectoryTable.NamePointerRVA:X})"); - Console.WriteLine($" Ordinal table RVA: {ExportTable.ExportDirectoryTable.OrdinalTableRVA} (0x{ExportTable.ExportDirectoryTable.OrdinalTableRVA:X})"); - Console.WriteLine(); + builder.AppendLine(); + builder.AppendLine(" Export Directory Table Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Export flags: {ExportTable.ExportDirectoryTable.ExportFlags} (0x{ExportTable.ExportDirectoryTable.ExportFlags:X})"); + builder.AppendLine($" Time/Date stamp: {ExportTable.ExportDirectoryTable.TimeDateStamp} (0x{ExportTable.ExportDirectoryTable.TimeDateStamp:X})"); + builder.AppendLine($" Major version: {ExportTable.ExportDirectoryTable.MajorVersion} (0x{ExportTable.ExportDirectoryTable.MajorVersion:X})"); + builder.AppendLine($" Minor version: {ExportTable.ExportDirectoryTable.MinorVersion} (0x{ExportTable.ExportDirectoryTable.MinorVersion:X})"); + builder.AppendLine($" Name RVA: {ExportTable.ExportDirectoryTable.NameRVA} (0x{ExportTable.ExportDirectoryTable.NameRVA:X})"); + builder.AppendLine($" Name: {ExportTable.ExportDirectoryTable.Name}"); + builder.AppendLine($" Ordinal base: {ExportTable.ExportDirectoryTable.OrdinalBase} (0x{ExportTable.ExportDirectoryTable.OrdinalBase:X})"); + builder.AppendLine($" Address table entries: {ExportTable.ExportDirectoryTable.AddressTableEntries} (0x{ExportTable.ExportDirectoryTable.AddressTableEntries:X})"); + builder.AppendLine($" Number of name pointers: {ExportTable.ExportDirectoryTable.NumberOfNamePointers} (0x{ExportTable.ExportDirectoryTable.NumberOfNamePointers:X})"); + builder.AppendLine($" Export address table RVA: {ExportTable.ExportDirectoryTable.ExportAddressTableRVA} (0x{ExportTable.ExportDirectoryTable.ExportAddressTableRVA:X})"); + builder.AppendLine($" Name pointer table RVA: {ExportTable.ExportDirectoryTable.NamePointerRVA} (0x{ExportTable.ExportDirectoryTable.NamePointerRVA:X})"); + builder.AppendLine($" Ordinal table RVA: {ExportTable.ExportDirectoryTable.OrdinalTableRVA} (0x{ExportTable.ExportDirectoryTable.OrdinalTableRVA:X})"); + builder.AppendLine(); - Console.WriteLine(" Export Address Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Export Address Table Information:"); + builder.AppendLine(" -------------------------"); if (ExportTable.ExportAddressTable == null || ExportTable.ExportAddressTable.Length == 0) { - Console.WriteLine(" No export address table items"); + builder.AppendLine(" No export address table items"); } else { for (int i = 0; i < ExportTable.ExportAddressTable.Length; i++) { var exportAddressTableEntry = ExportTable.ExportAddressTable[i]; - Console.WriteLine($" Export Address Table Entry {i}"); - Console.WriteLine($" Export RVA / Forwarder RVA: {exportAddressTableEntry.ExportRVA} (0x{exportAddressTableEntry.ExportRVA:X})"); + builder.AppendLine($" Export Address Table Entry {i}"); + builder.AppendLine($" Export RVA / Forwarder RVA: {exportAddressTableEntry.ExportRVA} (0x{exportAddressTableEntry.ExportRVA:X})"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Name Pointer Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Name Pointer Table Information:"); + builder.AppendLine(" -------------------------"); if (ExportTable.NamePointerTable?.Pointers == null || ExportTable.NamePointerTable.Pointers.Length == 0) { - Console.WriteLine(" No name pointer table items"); + builder.AppendLine(" No name pointer table items"); } else { for (int i = 0; i < ExportTable.NamePointerTable.Pointers.Length; i++) { var namePointerTableEntry = ExportTable.NamePointerTable.Pointers[i]; - Console.WriteLine($" Name Pointer Table Entry {i}"); - Console.WriteLine($" Pointer: {namePointerTableEntry} (0x{namePointerTableEntry:X})"); + builder.AppendLine($" Name Pointer Table Entry {i}"); + builder.AppendLine($" Pointer: {namePointerTableEntry} (0x{namePointerTableEntry:X})"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Ordinal Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Ordinal Table Information:"); + builder.AppendLine(" -------------------------"); if (ExportTable.OrdinalTable?.Indexes == null || ExportTable.OrdinalTable.Indexes.Length == 0) { - Console.WriteLine(" No ordinal table items"); + builder.AppendLine(" No ordinal table items"); } else { for (int i = 0; i < ExportTable.OrdinalTable.Indexes.Length; i++) { var ordinalTableEntry = ExportTable.OrdinalTable.Indexes[i]; - Console.WriteLine($" Ordinal Table Entry {i}"); - Console.WriteLine($" Index: {ordinalTableEntry} (0x{ordinalTableEntry:X})"); + builder.AppendLine($" Ordinal Table Entry {i}"); + builder.AppendLine($" Index: {ordinalTableEntry} (0x{ordinalTableEntry:X})"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Export Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Export Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ExportTable.ExportNameTable?.Strings == null || ExportTable.ExportNameTable.Strings.Length == 0) { - Console.WriteLine(" No export name table items"); + builder.AppendLine(" No export name table items"); } else { for (int i = 0; i < ExportTable.ExportNameTable.Strings.Length; i++) { var exportNameTableEntry = ExportTable.ExportNameTable.Strings[i]; - Console.WriteLine($" Export Name Table Entry {i}"); - Console.WriteLine($" String: {exportNameTableEntry}"); + builder.AppendLine($" Export Name Table Entry {i}"); + builder.AppendLine($" String: {exportNameTableEntry}"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print import table information /// - private void PrintImportTable() + /// StringBuilder to append information to + private void PrintImportTable(StringBuilder builder) { - Console.WriteLine(" Import Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Import Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_ImportTable == null || OH_ImportTable.VirtualAddress == 0 || ImportTable == null) { - Console.WriteLine(" No import table items"); + builder.AppendLine(" No import table items"); } else { - Console.WriteLine(); - Console.WriteLine(" Import Directory Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine(" Import Directory Table Information:"); + builder.AppendLine(" -------------------------"); if (ImportTable.ImportDirectoryTable == null || ImportTable.ImportDirectoryTable.Length == 0) { - Console.WriteLine(" No import directory table items"); + builder.AppendLine(" No import directory table items"); } else { for (int i = 0; i < ImportTable.ImportDirectoryTable.Length; i++) { var importDirectoryTableEntry = ImportTable.ImportDirectoryTable[i]; - Console.WriteLine($" Import Directory Table Entry {i}"); - Console.WriteLine($" Import lookup table RVA: {importDirectoryTableEntry.ImportLookupTableRVA} (0x{importDirectoryTableEntry.ImportLookupTableRVA:X})"); - Console.WriteLine($" Import lookup table Physical Address: {importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable):X})"); - Console.WriteLine($" Time/Date stamp: {importDirectoryTableEntry.TimeDateStamp} (0x{importDirectoryTableEntry.TimeDateStamp:X})"); - Console.WriteLine($" Forwarder chain: {importDirectoryTableEntry.ForwarderChain} (0x{importDirectoryTableEntry.ForwarderChain:X})"); - Console.WriteLine($" Name RVA: {importDirectoryTableEntry.NameRVA} (0x{importDirectoryTableEntry.NameRVA:X})"); - Console.WriteLine($" Name: {importDirectoryTableEntry.Name}"); - Console.WriteLine($" Import address table RVA: {importDirectoryTableEntry.ImportAddressTableRVA} (0x{importDirectoryTableEntry.ImportAddressTableRVA:X})"); - Console.WriteLine($" Import address table Physical Address: {importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Import Directory Table Entry {i}"); + builder.AppendLine($" Import lookup table RVA: {importDirectoryTableEntry.ImportLookupTableRVA} (0x{importDirectoryTableEntry.ImportLookupTableRVA:X})"); + builder.AppendLine($" Import lookup table Physical Address: {importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Time/Date stamp: {importDirectoryTableEntry.TimeDateStamp} (0x{importDirectoryTableEntry.TimeDateStamp:X})"); + builder.AppendLine($" Forwarder chain: {importDirectoryTableEntry.ForwarderChain} (0x{importDirectoryTableEntry.ForwarderChain:X})"); + builder.AppendLine($" Name RVA: {importDirectoryTableEntry.NameRVA} (0x{importDirectoryTableEntry.NameRVA:X})"); + builder.AppendLine($" Name: {importDirectoryTableEntry.Name}"); + builder.AppendLine($" Import address table RVA: {importDirectoryTableEntry.ImportAddressTableRVA} (0x{importDirectoryTableEntry.ImportAddressTableRVA:X})"); + builder.AppendLine($" Import address table Physical Address: {importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(SectionTable):X})"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Import Lookup Tables Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Import Lookup Tables Information:"); + builder.AppendLine(" -------------------------"); if (ImportTable.ImportLookupTables == null || ImportTable.ImportLookupTables.Count == 0) { - Console.WriteLine(" No import lookup tables"); + builder.AppendLine(" No import lookup tables"); } else { @@ -1855,40 +1856,40 @@ namespace BurnOutSharp.Wrappers int index = kvp.Key; var importLookupTable = kvp.Value; - Console.WriteLine(); - Console.WriteLine($" Import Lookup Table {index} Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine($" Import Lookup Table {index} Information:"); + builder.AppendLine(" -------------------------"); if (importLookupTable == null || importLookupTable.Length == 0) { - Console.WriteLine(" No import lookup table items"); + builder.AppendLine(" No import lookup table items"); } else { for (int i = 0; i < importLookupTable.Length; i++) { var importLookupTableEntry = importLookupTable[i]; - Console.WriteLine($" Import Lookup Table {index} Entry {i}"); - Console.WriteLine($" Ordinal/Name flag: {importLookupTableEntry.OrdinalNameFlag} (0x{importLookupTableEntry.OrdinalNameFlag:X})"); + builder.AppendLine($" Import Lookup Table {index} Entry {i}"); + builder.AppendLine($" Ordinal/Name flag: {importLookupTableEntry.OrdinalNameFlag} (0x{importLookupTableEntry.OrdinalNameFlag:X})"); if (importLookupTableEntry.OrdinalNameFlag) { - Console.WriteLine($" Ordinal number: {importLookupTableEntry.OrdinalNumber} (0x{importLookupTableEntry.OrdinalNumber:X})"); + builder.AppendLine($" Ordinal number: {importLookupTableEntry.OrdinalNumber} (0x{importLookupTableEntry.OrdinalNumber:X})"); } else { - Console.WriteLine($" Hint/Name table RVA: {importLookupTableEntry.HintNameTableRVA} (0x{importLookupTableEntry.HintNameTableRVA:X})"); - Console.WriteLine($" Hint/Name table Physical Address: {importLookupTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importLookupTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Hint/Name table RVA: {importLookupTableEntry.HintNameTableRVA} (0x{importLookupTableEntry.HintNameTableRVA:X})"); + builder.AppendLine($" Hint/Name table Physical Address: {importLookupTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importLookupTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable):X})"); } } } } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Import Address Tables Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Import Address Tables Information:"); + builder.AppendLine(" -------------------------"); if (ImportTable.ImportAddressTables == null || ImportTable.ImportAddressTables.Count == 0) { - Console.WriteLine(" No import address tables"); + builder.AppendLine(" No import address tables"); } else { @@ -1897,97 +1898,99 @@ namespace BurnOutSharp.Wrappers int index = kvp.Key; var importAddressTable = kvp.Value; - Console.WriteLine(); - Console.WriteLine($" Import Address Table {index} Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(); + builder.AppendLine($" Import Address Table {index} Information:"); + builder.AppendLine(" -------------------------"); if (importAddressTable == null || importAddressTable.Length == 0) { - Console.WriteLine(" No import address table items"); + builder.AppendLine(" No import address table items"); } else { for (int i = 0; i < importAddressTable.Length; i++) { var importAddressTableEntry = importAddressTable[i]; - Console.WriteLine($" Import Address Table {index} Entry {i}"); - Console.WriteLine($" Ordinal/Name flag: {importAddressTableEntry.OrdinalNameFlag} (0x{importAddressTableEntry.OrdinalNameFlag:X})"); + builder.AppendLine($" Import Address Table {index} Entry {i}"); + builder.AppendLine($" Ordinal/Name flag: {importAddressTableEntry.OrdinalNameFlag} (0x{importAddressTableEntry.OrdinalNameFlag:X})"); if (importAddressTableEntry.OrdinalNameFlag) { - Console.WriteLine($" Ordinal number: {importAddressTableEntry.OrdinalNumber} (0x{importAddressTableEntry.OrdinalNumber:X})"); + builder.AppendLine($" Ordinal number: {importAddressTableEntry.OrdinalNumber} (0x{importAddressTableEntry.OrdinalNumber:X})"); } else { - Console.WriteLine($" Hint/Name table RVA: {importAddressTableEntry.HintNameTableRVA} (0x{importAddressTableEntry.HintNameTableRVA:X})"); - Console.WriteLine($" Hint/Name table Physical Address: {importAddressTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importAddressTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable):X})"); + builder.AppendLine($" Hint/Name table RVA: {importAddressTableEntry.HintNameTableRVA} (0x{importAddressTableEntry.HintNameTableRVA:X})"); + builder.AppendLine($" Hint/Name table Physical Address: {importAddressTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable)} (0x{importAddressTableEntry.HintNameTableRVA.ConvertVirtualAddress(SectionTable):X})"); } } } } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine(" Hint/Name Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Hint/Name Table Information:"); + builder.AppendLine(" -------------------------"); if (ImportTable.HintNameTable == null || ImportTable.HintNameTable.Length == 0) { - Console.WriteLine(" No hint/name table items"); + builder.AppendLine(" No hint/name table items"); } else { for (int i = 0; i < ImportTable.HintNameTable.Length; i++) { var hintNameTableEntry = ImportTable.HintNameTable[i]; - Console.WriteLine($" Hint/Name Table Entry {i}"); - Console.WriteLine($" Hint: {hintNameTableEntry.Hint} (0x{hintNameTableEntry.Hint:X})"); - Console.WriteLine($" Name: {hintNameTableEntry.Name}"); + builder.AppendLine($" Hint/Name Table Entry {i}"); + builder.AppendLine($" Hint: {hintNameTableEntry.Hint} (0x{hintNameTableEntry.Hint:X})"); + builder.AppendLine($" Name: {hintNameTableEntry.Name}"); } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print resource directory table information /// - private void PrintResourceDirectoryTable() + /// StringBuilder to append information to + private void PrintResourceDirectoryTable(StringBuilder builder) { - Console.WriteLine(" Resource Directory Table Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Resource Directory Table Information:"); + builder.AppendLine(" -------------------------"); if (OH_ResourceTable == null || OH_ResourceTable.VirtualAddress == 0 || ResourceDirectoryTable == null) { - Console.WriteLine(" No resource directory table items"); + builder.AppendLine(" No resource directory table items"); } else { - PrintResourceDirectoryTable(ResourceDirectoryTable, level: 0, types: new List()); + PrintResourceDirectoryTable(ResourceDirectoryTable, level: 0, types: new List(), builder); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Pretty print the resource directory table information /// - private static void PrintResourceDirectoryTable(Models.PortableExecutable.ResourceDirectoryTable table, int level, List types) + /// StringBuilder to append information to + private static void PrintResourceDirectoryTable(Models.PortableExecutable.ResourceDirectoryTable table, int level, List types, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Table level: {level}"); - Console.WriteLine($"{padding}Characteristics: {table.Characteristics} (0x{table.Characteristics:X})"); - Console.WriteLine($"{padding}Time/Date stamp: {table.TimeDateStamp} (0x{table.TimeDateStamp:X})"); - Console.WriteLine($"{padding}Major version: {table.MajorVersion} (0x{table.MajorVersion:X})"); - Console.WriteLine($"{padding}Minor version: {table.MinorVersion} (0x{table.MinorVersion:X})"); - Console.WriteLine($"{padding}Number of name entries: {table.NumberOfNameEntries} (0x{table.NumberOfNameEntries:X})"); - Console.WriteLine($"{padding}Number of ID entries: {table.NumberOfIDEntries} (0x{table.NumberOfIDEntries:X})"); - Console.WriteLine(); + builder.AppendLine($"{padding}Table level: {level}"); + builder.AppendLine($"{padding}Characteristics: {table.Characteristics} (0x{table.Characteristics:X})"); + builder.AppendLine($"{padding}Time/Date stamp: {table.TimeDateStamp} (0x{table.TimeDateStamp:X})"); + builder.AppendLine($"{padding}Major version: {table.MajorVersion} (0x{table.MajorVersion:X})"); + builder.AppendLine($"{padding}Minor version: {table.MinorVersion} (0x{table.MinorVersion:X})"); + builder.AppendLine($"{padding}Number of name entries: {table.NumberOfNameEntries} (0x{table.NumberOfNameEntries:X})"); + builder.AppendLine($"{padding}Number of ID entries: {table.NumberOfIDEntries} (0x{table.NumberOfIDEntries:X})"); + builder.AppendLine(); - Console.WriteLine($"{padding}Entries"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Entries"); + builder.AppendLine($"{padding}-------------------------"); if (table.NumberOfNameEntries == 0 && table.NumberOfIDEntries == 0) { - Console.WriteLine($"{padding}No entries"); - Console.WriteLine(); + builder.AppendLine($"{padding}No entries"); + builder.AppendLine(); } else { @@ -2000,7 +2003,7 @@ namespace BurnOutSharp.Wrappers else newTypes.Add(entry.IntegerID); - PrintResourceDirectoryEntry(entry, level + 1, newTypes); + PrintResourceDirectoryEntry(entry, level + 1, newTypes, builder); } } } @@ -2008,42 +2011,44 @@ namespace BurnOutSharp.Wrappers /// /// Pretty print the resource directory entry information /// - private static void PrintResourceDirectoryEntry(Models.PortableExecutable.ResourceDirectoryEntry entry, int level, List types) + /// StringBuilder to append information to + private static void PrintResourceDirectoryEntry(Models.PortableExecutable.ResourceDirectoryEntry entry, int level, List types, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Item level: {level}"); + builder.AppendLine($"{padding}Item level: {level}"); if (entry.NameOffset != default) { - Console.WriteLine($"{padding}Name offset: {entry.NameOffset} (0x{entry.NameOffset:X})"); - Console.WriteLine($"{padding}Name ({entry.Name.Length}): {Encoding.UTF8.GetString(entry.Name.UnicodeString ?? new byte[0])}"); + builder.AppendLine($"{padding}Name offset: {entry.NameOffset} (0x{entry.NameOffset:X})"); + builder.AppendLine($"{padding}Name ({entry.Name.Length}): {Encoding.UTF8.GetString(entry.Name.UnicodeString ?? new byte[0])}"); } else { - Console.WriteLine($"{padding}Integer ID: {entry.IntegerID} (0x{entry.IntegerID:X})"); + builder.AppendLine($"{padding}Integer ID: {entry.IntegerID} (0x{entry.IntegerID:X})"); } if (entry.DataEntry != null) - PrintResourceDataEntry(entry.DataEntry, level: level + 1, types); + PrintResourceDataEntry(entry.DataEntry, level: level + 1, types, builder); else if (entry.Subdirectory != null) - PrintResourceDirectoryTable(entry.Subdirectory, level: level + 1, types); + PrintResourceDirectoryTable(entry.Subdirectory, level: level + 1, types, builder); } /// /// Pretty print the resource data entry information /// - private static void PrintResourceDataEntry(Models.PortableExecutable.ResourceDataEntry entry, int level, List types) + /// StringBuilder to append information to + private static void PrintResourceDataEntry(Models.PortableExecutable.ResourceDataEntry entry, int level, List types, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); // TODO: Use ordered list of base types to determine the shape of the data - Console.WriteLine($"{padding}Base types: {string.Join(", ", types)}"); + builder.AppendLine($"{padding}Base types: {string.Join(", ", types)}"); - Console.WriteLine($"{padding}Entry level: {level}"); - Console.WriteLine($"{padding}Data RVA: {entry.DataRVA} (0x{entry.DataRVA:X})"); - Console.WriteLine($"{padding}Size: {entry.Size} (0x{entry.Size:X})"); - Console.WriteLine($"{padding}Codepage: {entry.Codepage} (0x{entry.Codepage:X})"); - Console.WriteLine($"{padding}Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); + builder.AppendLine($"{padding}Entry level: {level}"); + builder.AppendLine($"{padding}Data RVA: {entry.DataRVA} (0x{entry.DataRVA:X})"); + builder.AppendLine($"{padding}Size: {entry.Size} (0x{entry.Size:X})"); + builder.AppendLine($"{padding}Codepage: {entry.Codepage} (0x{entry.Codepage:X})"); + builder.AppendLine($"{padding}Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); // TODO: Print out per-type data if (types != null && types.Count > 0 && types[0] is uint resourceType) @@ -2051,112 +2056,116 @@ namespace BurnOutSharp.Wrappers switch ((Models.PortableExecutable.ResourceType)resourceType) { case Models.PortableExecutable.ResourceType.RT_CURSOR: - PrintResourceRT_CURSOR(entry, level); + PrintResourceRT_CURSOR(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_BITMAP: - PrintResourceRT_BITMAP(entry, level); + PrintResourceRT_BITMAP(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_ICON: - PrintResourceRT_ICON(entry, level); + PrintResourceRT_ICON(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_MENU: - PrintResourceRT_MENU(entry, level); + PrintResourceRT_MENU(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_DIALOG: - PrintResourceRT_DIALOG(entry, level); + PrintResourceRT_DIALOG(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_STRING: - PrintResourceRT_STRING(entry, level); + PrintResourceRT_STRING(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_FONTDIR: - PrintResourceRT_FONTDIR(entry, level); + PrintResourceRT_FONTDIR(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_FONT: - PrintResourceRT_FONT(entry, level); + PrintResourceRT_FONT(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_ACCELERATOR: - PrintResourceRT_ACCELERATOR(entry, level); + PrintResourceRT_ACCELERATOR(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_RCDATA: - PrintResourceRT_RCDATA(entry, level); + PrintResourceRT_RCDATA(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_MESSAGETABLE: - PrintResourceRT_MESSAGETABLE(entry, level); + PrintResourceRT_MESSAGETABLE(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_GROUP_CURSOR: - PrintResourceRT_GROUP_CURSOR(entry, level); + PrintResourceRT_GROUP_CURSOR(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_GROUP_ICON: - PrintResourceRT_GROUP_ICON(entry, level); + PrintResourceRT_GROUP_ICON(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_VERSION: - PrintResourceRT_VERSION(entry, level); + PrintResourceRT_VERSION(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_DLGINCLUDE: - PrintResourceRT_DLGINCLUDE(entry, level); + PrintResourceRT_DLGINCLUDE(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_PLUGPLAY: - PrintResourceRT_PLUGPLAY(entry, level); + PrintResourceRT_PLUGPLAY(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_VXD: - PrintResourceRT_VXD(entry, level); + PrintResourceRT_VXD(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_ANICURSOR: - PrintResourceRT_ANICURSOR(entry, level); + PrintResourceRT_ANICURSOR(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_ANIICON: - PrintResourceRT_ANIICON(entry, level); + PrintResourceRT_ANIICON(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_HTML: - PrintResourceRT_HTML(entry, level); + PrintResourceRT_HTML(entry, level, builder); break; case Models.PortableExecutable.ResourceType.RT_MANIFEST: - PrintResourceRT_MANIFEST(entry, level); + PrintResourceRT_MANIFEST(entry, level, builder); break; default: - PrintResourceUNKNOWN(entry, level, types[0]); + PrintResourceUNKNOWN(entry, level, types[0], builder); break; } } else if (types != null && types.Count > 0 && types[0] is string resourceString) { - PrintResourceUNKNOWN(entry, level, types[0]); + PrintResourceUNKNOWN(entry, level, types[0], builder); } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print an RT_CURSOR resource /// - private static void PrintResourceRT_CURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_CURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Hardware-dependent cursor resource found, not parsed yet"); + builder.AppendLine($"{padding}Hardware-dependent cursor resource found, not parsed yet"); } /// /// Print an RT_BITMAP resource /// - private static void PrintResourceRT_BITMAP(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_BITMAP(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Bitmap resource found, not parsed yet"); + builder.AppendLine($"{padding}Bitmap resource found, not parsed yet"); } /// /// Print an RT_ICON resource /// - private static void PrintResourceRT_ICON(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_ICON(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Hardware-dependent icon resource found, not parsed yet"); + builder.AppendLine($"{padding}Hardware-dependent icon resource found, not parsed yet"); } /// /// Print an RT_MENU resource /// - private static void PrintResourceRT_MENU(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_MENU(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2164,20 +2173,20 @@ namespace BurnOutSharp.Wrappers try { menu = entry.AsMenu(); } catch { } if (menu == null) { - Console.WriteLine($"{padding}Menu resource found, but malformed"); + builder.AppendLine($"{padding}Menu resource found, but malformed"); return; } if (menu.MenuHeader != null) { - Console.WriteLine($"{padding}Version: {menu.MenuHeader.Version} (0x{menu.MenuHeader.Version:X})"); - Console.WriteLine($"{padding}Header size: {menu.MenuHeader.HeaderSize} (0x{menu.MenuHeader.HeaderSize:X})"); - Console.WriteLine(); - Console.WriteLine($"{padding}Menu items"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Version: {menu.MenuHeader.Version} (0x{menu.MenuHeader.Version:X})"); + builder.AppendLine($"{padding}Header size: {menu.MenuHeader.HeaderSize} (0x{menu.MenuHeader.HeaderSize:X})"); + builder.AppendLine(); + builder.AppendLine($"{padding}Menu items"); + builder.AppendLine($"{padding}-------------------------"); if (menu.MenuItems == null || menu.MenuItems.Length == 0) { - Console.WriteLine($"{padding}No menu items"); + builder.AppendLine($"{padding}No menu items"); return; } @@ -2185,35 +2194,35 @@ namespace BurnOutSharp.Wrappers { var menuItem = menu.MenuItems[i]; - Console.WriteLine($"{padding}Menu item {i}"); + builder.AppendLine($"{padding}Menu item {i}"); if (menuItem.NormalMenuText != null) { - Console.WriteLine($"{padding} Resource info: {menuItem.NormalResInfo} (0x{menuItem.NormalResInfo:X})"); - Console.WriteLine($"{padding} Menu text: {menuItem.NormalMenuText} (0x{menuItem.NormalMenuText:X})"); + builder.AppendLine($"{padding} Resource info: {menuItem.NormalResInfo} (0x{menuItem.NormalResInfo:X})"); + builder.AppendLine($"{padding} Menu text: {menuItem.NormalMenuText} (0x{menuItem.NormalMenuText:X})"); } else { - Console.WriteLine($"{padding} Item type: {menuItem.PopupItemType} (0x{menuItem.PopupItemType:X})"); - Console.WriteLine($"{padding} State: {menuItem.PopupState} (0x{menuItem.PopupState:X})"); - Console.WriteLine($"{padding} ID: {menuItem.PopupID} (0x{menuItem.PopupID:X})"); - Console.WriteLine($"{padding} Resource info: {menuItem.PopupResInfo} (0x{menuItem.PopupResInfo:X})"); - Console.WriteLine($"{padding} Menu text: {menuItem.PopupMenuText} (0x{menuItem.PopupMenuText:X})"); + builder.AppendLine($"{padding} Item type: {menuItem.PopupItemType} (0x{menuItem.PopupItemType:X})"); + builder.AppendLine($"{padding} State: {menuItem.PopupState} (0x{menuItem.PopupState:X})"); + builder.AppendLine($"{padding} ID: {menuItem.PopupID} (0x{menuItem.PopupID:X})"); + builder.AppendLine($"{padding} Resource info: {menuItem.PopupResInfo} (0x{menuItem.PopupResInfo:X})"); + builder.AppendLine($"{padding} Menu text: {menuItem.PopupMenuText} (0x{menuItem.PopupMenuText:X})"); } } } else if (menu.ExtendedMenuHeader != null) { - Console.WriteLine($"{padding}Version: {menu.ExtendedMenuHeader.Version} (0x{menu.ExtendedMenuHeader.Version:X})"); - Console.WriteLine($"{padding}Offset: {menu.ExtendedMenuHeader.Offset} (0x{menu.ExtendedMenuHeader.Offset:X})"); - Console.WriteLine($"{padding}Help ID: {menu.ExtendedMenuHeader.HelpID} (0x{menu.ExtendedMenuHeader.HelpID:X})"); - Console.WriteLine(); - Console.WriteLine($"{padding}Menu items"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Version: {menu.ExtendedMenuHeader.Version} (0x{menu.ExtendedMenuHeader.Version:X})"); + builder.AppendLine($"{padding}Offset: {menu.ExtendedMenuHeader.Offset} (0x{menu.ExtendedMenuHeader.Offset:X})"); + builder.AppendLine($"{padding}Help ID: {menu.ExtendedMenuHeader.HelpID} (0x{menu.ExtendedMenuHeader.HelpID:X})"); + builder.AppendLine(); + builder.AppendLine($"{padding}Menu items"); + builder.AppendLine($"{padding}-------------------------"); if (menu.ExtendedMenuHeader.Offset == 0 || menu.ExtendedMenuItems == null || menu.ExtendedMenuItems.Length == 0) { - Console.WriteLine($"{padding}No menu items"); + builder.AppendLine($"{padding}No menu items"); return; } @@ -2221,24 +2230,25 @@ namespace BurnOutSharp.Wrappers { var menuItem = menu.ExtendedMenuItems[i]; - Console.WriteLine($"{padding}Dialog item template {i}"); - Console.WriteLine($"{padding} Item type: {menuItem.ItemType} (0x{menuItem.ItemType:X})"); - Console.WriteLine($"{padding} State: {menuItem.State} (0x{menuItem.State:X})"); - Console.WriteLine($"{padding} ID: {menuItem.ID} (0x{menuItem.ID:X})"); - Console.WriteLine($"{padding} Flags: {menuItem.Flags} (0x{menuItem.Flags:X})"); - Console.WriteLine($"{padding} Menu text: {menuItem.MenuText} (0x{menuItem.MenuText:X})"); + builder.AppendLine($"{padding}Dialog item template {i}"); + builder.AppendLine($"{padding} Item type: {menuItem.ItemType} (0x{menuItem.ItemType:X})"); + builder.AppendLine($"{padding} State: {menuItem.State} (0x{menuItem.State:X})"); + builder.AppendLine($"{padding} ID: {menuItem.ID} (0x{menuItem.ID:X})"); + builder.AppendLine($"{padding} Flags: {menuItem.Flags} (0x{menuItem.Flags:X})"); + builder.AppendLine($"{padding} Menu text: {menuItem.MenuText} (0x{menuItem.MenuText:X})"); } } else { - Console.WriteLine($"{padding}Menu resource found, but malformed"); + builder.AppendLine($"{padding}Menu resource found, but malformed"); } } /// /// Print an RT_DIALOG resource /// - private static void PrintResourceRT_DIALOG(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_DIALOG(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2246,34 +2256,34 @@ namespace BurnOutSharp.Wrappers try { dialogBox = entry.AsDialogBox(); } catch { } if (dialogBox == null) { - Console.WriteLine($"{padding}Dialog box resource found, but malformed"); + builder.AppendLine($"{padding}Dialog box resource found, but malformed"); return; } if (dialogBox.DialogTemplate != null) { - Console.WriteLine($"{padding}Style: {dialogBox.DialogTemplate.Style} (0x{dialogBox.DialogTemplate.Style:X})"); - Console.WriteLine($"{padding}Extended style: {dialogBox.DialogTemplate.ExtendedStyle} (0x{dialogBox.DialogTemplate.ExtendedStyle:X})"); - Console.WriteLine($"{padding}Item count: {dialogBox.DialogTemplate.ItemCount} (0x{dialogBox.DialogTemplate.ItemCount:X})"); - Console.WriteLine($"{padding}X-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionX} (0x{dialogBox.DialogTemplate.PositionX:X})"); - Console.WriteLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionY} (0x{dialogBox.DialogTemplate.PositionY:X})"); - Console.WriteLine($"{padding}Width of the dialog box: {dialogBox.DialogTemplate.WidthX} (0x{dialogBox.DialogTemplate.WidthX:X})"); - Console.WriteLine($"{padding}Height of the dialog box: {dialogBox.DialogTemplate.HeightY} (0x{dialogBox.DialogTemplate.HeightY:X})"); - Console.WriteLine($"{padding}Menu resource: {dialogBox.DialogTemplate.MenuResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Menu resource ordinal: {dialogBox.DialogTemplate.MenuResourceOrdinal} (0x{dialogBox.DialogTemplate.MenuResourceOrdinal:X})"); - Console.WriteLine($"{padding}Class resource: {dialogBox.DialogTemplate.ClassResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Class resource ordinal: {dialogBox.DialogTemplate.ClassResourceOrdinal} (0x{dialogBox.DialogTemplate.ClassResourceOrdinal:X})"); - Console.WriteLine($"{padding}Title resource: {dialogBox.DialogTemplate.TitleResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Point size value: {dialogBox.DialogTemplate.PointSizeValue} (0x{dialogBox.DialogTemplate.PointSizeValue:X})"); - Console.WriteLine($"{padding}Typeface: {dialogBox.DialogTemplate.Typeface ?? "[EMPTY]"}"); - Console.WriteLine(); - Console.WriteLine($"{padding}Dialog item templates"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Style: {dialogBox.DialogTemplate.Style} (0x{dialogBox.DialogTemplate.Style:X})"); + builder.AppendLine($"{padding}Extended style: {dialogBox.DialogTemplate.ExtendedStyle} (0x{dialogBox.DialogTemplate.ExtendedStyle:X})"); + builder.AppendLine($"{padding}Item count: {dialogBox.DialogTemplate.ItemCount} (0x{dialogBox.DialogTemplate.ItemCount:X})"); + builder.AppendLine($"{padding}X-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionX} (0x{dialogBox.DialogTemplate.PositionX:X})"); + builder.AppendLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionY} (0x{dialogBox.DialogTemplate.PositionY:X})"); + builder.AppendLine($"{padding}Width of the dialog box: {dialogBox.DialogTemplate.WidthX} (0x{dialogBox.DialogTemplate.WidthX:X})"); + builder.AppendLine($"{padding}Height of the dialog box: {dialogBox.DialogTemplate.HeightY} (0x{dialogBox.DialogTemplate.HeightY:X})"); + builder.AppendLine($"{padding}Menu resource: {dialogBox.DialogTemplate.MenuResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Menu resource ordinal: {dialogBox.DialogTemplate.MenuResourceOrdinal} (0x{dialogBox.DialogTemplate.MenuResourceOrdinal:X})"); + builder.AppendLine($"{padding}Class resource: {dialogBox.DialogTemplate.ClassResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Class resource ordinal: {dialogBox.DialogTemplate.ClassResourceOrdinal} (0x{dialogBox.DialogTemplate.ClassResourceOrdinal:X})"); + builder.AppendLine($"{padding}Title resource: {dialogBox.DialogTemplate.TitleResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Point size value: {dialogBox.DialogTemplate.PointSizeValue} (0x{dialogBox.DialogTemplate.PointSizeValue:X})"); + builder.AppendLine($"{padding}Typeface: {dialogBox.DialogTemplate.Typeface ?? "[EMPTY]"}"); + builder.AppendLine(); + builder.AppendLine($"{padding}Dialog item templates"); + builder.AppendLine($"{padding}-------------------------"); if (dialogBox.DialogTemplate.ItemCount == 0 || dialogBox.DialogItemTemplates == null || dialogBox.DialogItemTemplates.Length == 0) { - Console.WriteLine($"{padding}No dialog item templates"); + builder.AppendLine($"{padding}No dialog item templates"); return; } @@ -2281,55 +2291,55 @@ namespace BurnOutSharp.Wrappers { var dialogItemTemplate = dialogBox.DialogItemTemplates[i]; - Console.WriteLine($"{padding}Dialog item template {i}"); - Console.WriteLine($"{padding} Style: {dialogItemTemplate.Style} (0x{dialogItemTemplate.Style:X})"); - Console.WriteLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle} (0x{dialogItemTemplate.ExtendedStyle:X})"); - Console.WriteLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX} (0x{dialogItemTemplate.PositionX:X})"); - Console.WriteLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY} (0x{dialogItemTemplate.PositionY:X})"); - Console.WriteLine($"{padding} Width of the control: {dialogItemTemplate.WidthX} (0x{dialogItemTemplate.WidthX:X})"); - Console.WriteLine($"{padding} Height of the control: {dialogItemTemplate.HeightY} (0x{dialogItemTemplate.HeightY:X})"); - Console.WriteLine($"{padding} ID: {dialogItemTemplate.ID} (0x{dialogItemTemplate.ID:X})"); - Console.WriteLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal} (0x{dialogItemTemplate.ClassResourceOrdinal:X})"); - Console.WriteLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal} (0x{dialogItemTemplate.TitleResourceOrdinal:X})"); - Console.WriteLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize} (0x{dialogItemTemplate.CreationDataSize:X})"); + builder.AppendLine($"{padding}Dialog item template {i}"); + builder.AppendLine($"{padding} Style: {dialogItemTemplate.Style} (0x{dialogItemTemplate.Style:X})"); + builder.AppendLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle} (0x{dialogItemTemplate.ExtendedStyle:X})"); + builder.AppendLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX} (0x{dialogItemTemplate.PositionX:X})"); + builder.AppendLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY} (0x{dialogItemTemplate.PositionY:X})"); + builder.AppendLine($"{padding} Width of the control: {dialogItemTemplate.WidthX} (0x{dialogItemTemplate.WidthX:X})"); + builder.AppendLine($"{padding} Height of the control: {dialogItemTemplate.HeightY} (0x{dialogItemTemplate.HeightY:X})"); + builder.AppendLine($"{padding} ID: {dialogItemTemplate.ID} (0x{dialogItemTemplate.ID:X})"); + builder.AppendLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal} (0x{dialogItemTemplate.ClassResourceOrdinal:X})"); + builder.AppendLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal} (0x{dialogItemTemplate.TitleResourceOrdinal:X})"); + builder.AppendLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize} (0x{dialogItemTemplate.CreationDataSize:X})"); if (dialogItemTemplate.CreationData != null && dialogItemTemplate.CreationData.Length != 0) - Console.WriteLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}"); + builder.AppendLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}"); else - Console.WriteLine($"{padding} Creation data: [EMPTY]"); + builder.AppendLine($"{padding} Creation data: [EMPTY]"); } } else if (dialogBox.ExtendedDialogTemplate != null) { - Console.WriteLine($"{padding}Version: {dialogBox.ExtendedDialogTemplate.Version} (0x{dialogBox.ExtendedDialogTemplate.Version:X})"); - Console.WriteLine($"{padding}Signature: {dialogBox.ExtendedDialogTemplate.Signature} (0x{dialogBox.ExtendedDialogTemplate.Signature:X})"); - Console.WriteLine($"{padding}Help ID: {dialogBox.ExtendedDialogTemplate.HelpID} (0x{dialogBox.ExtendedDialogTemplate.HelpID:X})"); - Console.WriteLine($"{padding}Extended style: {dialogBox.ExtendedDialogTemplate.ExtendedStyle} (0x{dialogBox.ExtendedDialogTemplate.ExtendedStyle:X})"); - Console.WriteLine($"{padding}Style: {dialogBox.ExtendedDialogTemplate.Style} (0x{dialogBox.ExtendedDialogTemplate.Style:X})"); - Console.WriteLine($"{padding}Item count: {dialogBox.ExtendedDialogTemplate.DialogItems} (0x{dialogBox.ExtendedDialogTemplate.DialogItems:X})"); - Console.WriteLine($"{padding}X-coordinate of upper-left corner: {dialogBox.ExtendedDialogTemplate.PositionX} (0x{dialogBox.ExtendedDialogTemplate.PositionX:X})"); - Console.WriteLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.ExtendedDialogTemplate.PositionY} (0x{dialogBox.ExtendedDialogTemplate.PositionY:X})"); - Console.WriteLine($"{padding}Width of the dialog box: {dialogBox.ExtendedDialogTemplate.WidthX} (0x{dialogBox.ExtendedDialogTemplate.WidthX:X})"); - Console.WriteLine($"{padding}Height of the dialog box: {dialogBox.ExtendedDialogTemplate.HeightY} (0x{dialogBox.ExtendedDialogTemplate.HeightY:X})"); - Console.WriteLine($"{padding}Menu resource: {dialogBox.ExtendedDialogTemplate.MenuResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Menu resource ordinal: {dialogBox.ExtendedDialogTemplate.MenuResourceOrdinal} (0x{dialogBox.ExtendedDialogTemplate.MenuResourceOrdinal:X})"); - Console.WriteLine($"{padding}Class resource: {dialogBox.ExtendedDialogTemplate.ClassResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Class resource ordinal: {dialogBox.ExtendedDialogTemplate.ClassResourceOrdinal} (0x{dialogBox.ExtendedDialogTemplate.ClassResourceOrdinal:X})"); - Console.WriteLine($"{padding}Title resource: {dialogBox.ExtendedDialogTemplate.TitleResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding}Point size: {dialogBox.ExtendedDialogTemplate.PointSize} (0x{dialogBox.ExtendedDialogTemplate.PointSize:X})"); - Console.WriteLine($"{padding}Weight: {dialogBox.ExtendedDialogTemplate.Weight} (0x{dialogBox.ExtendedDialogTemplate.Weight:X})"); - Console.WriteLine($"{padding}Italic: {dialogBox.ExtendedDialogTemplate.Italic} (0x{dialogBox.ExtendedDialogTemplate.Italic:X})"); - Console.WriteLine($"{padding}Character set: {dialogBox.ExtendedDialogTemplate.CharSet} (0x{dialogBox.ExtendedDialogTemplate.CharSet:X})"); - Console.WriteLine($"{padding}Typeface: {dialogBox.ExtendedDialogTemplate.Typeface ?? "[EMPTY]"}"); - Console.WriteLine(); - Console.WriteLine($"{padding}Dialog item templates"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Version: {dialogBox.ExtendedDialogTemplate.Version} (0x{dialogBox.ExtendedDialogTemplate.Version:X})"); + builder.AppendLine($"{padding}Signature: {dialogBox.ExtendedDialogTemplate.Signature} (0x{dialogBox.ExtendedDialogTemplate.Signature:X})"); + builder.AppendLine($"{padding}Help ID: {dialogBox.ExtendedDialogTemplate.HelpID} (0x{dialogBox.ExtendedDialogTemplate.HelpID:X})"); + builder.AppendLine($"{padding}Extended style: {dialogBox.ExtendedDialogTemplate.ExtendedStyle} (0x{dialogBox.ExtendedDialogTemplate.ExtendedStyle:X})"); + builder.AppendLine($"{padding}Style: {dialogBox.ExtendedDialogTemplate.Style} (0x{dialogBox.ExtendedDialogTemplate.Style:X})"); + builder.AppendLine($"{padding}Item count: {dialogBox.ExtendedDialogTemplate.DialogItems} (0x{dialogBox.ExtendedDialogTemplate.DialogItems:X})"); + builder.AppendLine($"{padding}X-coordinate of upper-left corner: {dialogBox.ExtendedDialogTemplate.PositionX} (0x{dialogBox.ExtendedDialogTemplate.PositionX:X})"); + builder.AppendLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.ExtendedDialogTemplate.PositionY} (0x{dialogBox.ExtendedDialogTemplate.PositionY:X})"); + builder.AppendLine($"{padding}Width of the dialog box: {dialogBox.ExtendedDialogTemplate.WidthX} (0x{dialogBox.ExtendedDialogTemplate.WidthX:X})"); + builder.AppendLine($"{padding}Height of the dialog box: {dialogBox.ExtendedDialogTemplate.HeightY} (0x{dialogBox.ExtendedDialogTemplate.HeightY:X})"); + builder.AppendLine($"{padding}Menu resource: {dialogBox.ExtendedDialogTemplate.MenuResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Menu resource ordinal: {dialogBox.ExtendedDialogTemplate.MenuResourceOrdinal} (0x{dialogBox.ExtendedDialogTemplate.MenuResourceOrdinal:X})"); + builder.AppendLine($"{padding}Class resource: {dialogBox.ExtendedDialogTemplate.ClassResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Class resource ordinal: {dialogBox.ExtendedDialogTemplate.ClassResourceOrdinal} (0x{dialogBox.ExtendedDialogTemplate.ClassResourceOrdinal:X})"); + builder.AppendLine($"{padding}Title resource: {dialogBox.ExtendedDialogTemplate.TitleResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding}Point size: {dialogBox.ExtendedDialogTemplate.PointSize} (0x{dialogBox.ExtendedDialogTemplate.PointSize:X})"); + builder.AppendLine($"{padding}Weight: {dialogBox.ExtendedDialogTemplate.Weight} (0x{dialogBox.ExtendedDialogTemplate.Weight:X})"); + builder.AppendLine($"{padding}Italic: {dialogBox.ExtendedDialogTemplate.Italic} (0x{dialogBox.ExtendedDialogTemplate.Italic:X})"); + builder.AppendLine($"{padding}Character set: {dialogBox.ExtendedDialogTemplate.CharSet} (0x{dialogBox.ExtendedDialogTemplate.CharSet:X})"); + builder.AppendLine($"{padding}Typeface: {dialogBox.ExtendedDialogTemplate.Typeface ?? "[EMPTY]"}"); + builder.AppendLine(); + builder.AppendLine($"{padding}Dialog item templates"); + builder.AppendLine($"{padding}-------------------------"); if (dialogBox.ExtendedDialogTemplate.DialogItems == 0 || dialogBox.ExtendedDialogItemTemplates == null || dialogBox.ExtendedDialogItemTemplates.Length == 0) { - Console.WriteLine($"{padding}No dialog item templates"); + builder.AppendLine($"{padding}No dialog item templates"); return; } @@ -2337,36 +2347,37 @@ namespace BurnOutSharp.Wrappers { var dialogItemTemplate = dialogBox.ExtendedDialogItemTemplates[i]; - Console.WriteLine($"{padding}Dialog item template {i}"); - Console.WriteLine($"{padding} Help ID: {dialogItemTemplate.HelpID} (0x{dialogItemTemplate.HelpID:X})"); - Console.WriteLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle} (0x{dialogItemTemplate.ExtendedStyle:X})"); - Console.WriteLine($"{padding} Style: {dialogItemTemplate.Style} (0x{dialogItemTemplate.Style:X})"); - Console.WriteLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX} (0x{dialogItemTemplate.PositionX:X})"); - Console.WriteLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY} (0x{dialogItemTemplate.PositionY:X})"); - Console.WriteLine($"{padding} Width of the control: {dialogItemTemplate.WidthX} (0x{dialogItemTemplate.WidthX:X})"); - Console.WriteLine($"{padding} Height of the control: {dialogItemTemplate.HeightY} (0x{dialogItemTemplate.HeightY:X})"); - Console.WriteLine($"{padding} ID: {dialogItemTemplate.ID} (0x{dialogItemTemplate.ID:X})"); - Console.WriteLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal} (0x{dialogItemTemplate.ClassResourceOrdinal:X})"); - Console.WriteLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}"); - Console.WriteLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal} (0x{dialogItemTemplate.TitleResourceOrdinal:X})"); - Console.WriteLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize} (0x{dialogItemTemplate.CreationDataSize:X})"); + builder.AppendLine($"{padding}Dialog item template {i}"); + builder.AppendLine($"{padding} Help ID: {dialogItemTemplate.HelpID} (0x{dialogItemTemplate.HelpID:X})"); + builder.AppendLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle} (0x{dialogItemTemplate.ExtendedStyle:X})"); + builder.AppendLine($"{padding} Style: {dialogItemTemplate.Style} (0x{dialogItemTemplate.Style:X})"); + builder.AppendLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX} (0x{dialogItemTemplate.PositionX:X})"); + builder.AppendLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY} (0x{dialogItemTemplate.PositionY:X})"); + builder.AppendLine($"{padding} Width of the control: {dialogItemTemplate.WidthX} (0x{dialogItemTemplate.WidthX:X})"); + builder.AppendLine($"{padding} Height of the control: {dialogItemTemplate.HeightY} (0x{dialogItemTemplate.HeightY:X})"); + builder.AppendLine($"{padding} ID: {dialogItemTemplate.ID} (0x{dialogItemTemplate.ID:X})"); + builder.AppendLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal} (0x{dialogItemTemplate.ClassResourceOrdinal:X})"); + builder.AppendLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}"); + builder.AppendLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal} (0x{dialogItemTemplate.TitleResourceOrdinal:X})"); + builder.AppendLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize} (0x{dialogItemTemplate.CreationDataSize:X})"); if (dialogItemTemplate.CreationData != null && dialogItemTemplate.CreationData.Length != 0) - Console.WriteLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}"); + builder.AppendLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}"); else - Console.WriteLine($"{padding} Creation data: [EMPTY]"); + builder.AppendLine($"{padding} Creation data: [EMPTY]"); } } else { - Console.WriteLine($"{padding}Dialog box resource found, but malformed"); + builder.AppendLine($"{padding}Dialog box resource found, but malformed"); } } /// /// Print an RT_STRING resource /// - private static void PrintResourceRT_STRING(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_STRING(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2374,7 +2385,7 @@ namespace BurnOutSharp.Wrappers try { stringTable = entry.AsStringTable(); } catch { } if (stringTable == null) { - Console.WriteLine($"{padding}String table resource found, but malformed"); + builder.AppendLine($"{padding}String table resource found, but malformed"); return; } @@ -2382,32 +2393,35 @@ namespace BurnOutSharp.Wrappers { int index = kvp.Key; string stringValue = kvp.Value; - Console.WriteLine($"{padding}String entry {index}: {stringValue}"); + builder.AppendLine($"{padding}String entry {index}: {stringValue}"); } } /// /// Print an RT_FONTDIR resource /// - private static void PrintResourceRT_FONTDIR(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_FONTDIR(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Font directory resource found, not parsed yet"); + builder.AppendLine($"{padding}Font directory resource found, not parsed yet"); } /// /// Print an RT_FONT resource /// - private static void PrintResourceRT_FONT(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_FONT(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Font resource found, not parsed yet"); + builder.AppendLine($"{padding}Font resource found, not parsed yet"); } /// /// Print an RT_ACCELERATOR resource /// - private static void PrintResourceRT_ACCELERATOR(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_ACCELERATOR(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2415,55 +2429,57 @@ namespace BurnOutSharp.Wrappers try { acceleratorTable = entry.AsAcceleratorTableResource(); } catch { } if (acceleratorTable == null) { - Console.WriteLine($"{padding}Accelerator table resource found, but malformed"); + builder.AppendLine($"{padding}Accelerator table resource found, but malformed"); return; } for (int i = 0; i < acceleratorTable.Length; i++) { var acceleratorTableEntry = acceleratorTable[i]; - Console.WriteLine($"{padding}Accelerator Table Entry {i}:"); - Console.WriteLine($"{padding} Flags: {acceleratorTableEntry.Flags} (0x{acceleratorTableEntry.Flags:X})"); - Console.WriteLine($"{padding} Ansi: {acceleratorTableEntry.Ansi} (0x{acceleratorTableEntry.Ansi:X})"); - Console.WriteLine($"{padding} Id: {acceleratorTableEntry.Id} (0x{acceleratorTableEntry.Id:X})"); - Console.WriteLine($"{padding} Padding: {acceleratorTableEntry.Padding} (0x{acceleratorTableEntry.Padding:X})"); + builder.AppendLine($"{padding}Accelerator Table Entry {i}:"); + builder.AppendLine($"{padding} Flags: {acceleratorTableEntry.Flags} (0x{acceleratorTableEntry.Flags:X})"); + builder.AppendLine($"{padding} Ansi: {acceleratorTableEntry.Ansi} (0x{acceleratorTableEntry.Ansi:X})"); + builder.AppendLine($"{padding} Id: {acceleratorTableEntry.Id} (0x{acceleratorTableEntry.Id:X})"); + builder.AppendLine($"{padding} Padding: {acceleratorTableEntry.Padding} (0x{acceleratorTableEntry.Padding:X})"); } } /// /// Print an RT_RCDATA resource /// - private static void PrintResourceRT_RCDATA(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_RCDATA(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Application-defined resource found, not parsed yet"); + builder.AppendLine($"{padding}Application-defined resource found, not parsed yet"); // Then print the data, if needed if (entry.Data[0] == 0x4D && entry.Data[1] == 0x5A) { - Console.WriteLine($"{padding}Data: [Embedded Executable File]"); // TODO: Parse this out and print separately + builder.AppendLine($"{padding}Data: [Embedded Executable File]"); // TODO: Parse this out and print separately } else if (entry.Data[0] == 0x4D && entry.Data[1] == 0x53 && entry.Data[2] == 0x46 && entry.Data[3] == 0x54) { - Console.WriteLine($"{padding}Data: [Embedded OLE Library File]"); // TODO: Parse this out and print separately + builder.AppendLine($"{padding}Data: [Embedded OLE Library File]"); // TODO: Parse this out and print separately } else { //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (Byte Data): {BitConverter.ToString(entry.Data).Replace('-', ' ')}"); + // builder.AppendLine($"{padding}Value (Byte Data): {BitConverter.ToString(entry.Data).Replace('-', ' ')}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); } } /// /// Print an RT_MESSAGETABLE resource /// - private static void PrintResourceRT_MESSAGETABLE(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_MESSAGETABLE(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2471,19 +2487,19 @@ namespace BurnOutSharp.Wrappers try { messageTable = entry.AsMessageResourceData(); } catch { } if (messageTable == null) { - Console.WriteLine($"{padding}Message resource data found, but malformed"); + builder.AppendLine($"{padding}Message resource data found, but malformed"); return; } - Console.WriteLine($"{padding}Number of blocks: {messageTable.NumberOfBlocks} (0x{messageTable.NumberOfBlocks:X})"); - Console.WriteLine(); - Console.WriteLine($"{padding}Message resource blocks"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Number of blocks: {messageTable.NumberOfBlocks} (0x{messageTable.NumberOfBlocks:X})"); + builder.AppendLine(); + builder.AppendLine($"{padding}Message resource blocks"); + builder.AppendLine($"{padding}-------------------------"); if (messageTable.NumberOfBlocks == 0 || messageTable.Blocks == null || messageTable.Blocks.Length == 0) { - Console.WriteLine($"{padding}No message resource blocks"); + builder.AppendLine($"{padding}No message resource blocks"); } else { @@ -2491,20 +2507,20 @@ namespace BurnOutSharp.Wrappers { var messageResourceBlock = messageTable.Blocks[i]; - Console.WriteLine($"{padding}Message resource block {i}"); - Console.WriteLine($"{padding} Low ID: {messageResourceBlock.LowId} (0x{messageResourceBlock.LowId:X})"); - Console.WriteLine($"{padding} High ID: {messageResourceBlock.HighId} (0x{messageResourceBlock.HighId:X})"); - Console.WriteLine($"{padding} Offset to entries: {messageResourceBlock.OffsetToEntries} (0x{messageResourceBlock.OffsetToEntries:X})"); + builder.AppendLine($"{padding}Message resource block {i}"); + builder.AppendLine($"{padding} Low ID: {messageResourceBlock.LowId} (0x{messageResourceBlock.LowId:X})"); + builder.AppendLine($"{padding} High ID: {messageResourceBlock.HighId} (0x{messageResourceBlock.HighId:X})"); + builder.AppendLine($"{padding} Offset to entries: {messageResourceBlock.OffsetToEntries} (0x{messageResourceBlock.OffsetToEntries:X})"); } } - Console.WriteLine(); + builder.AppendLine(); - Console.WriteLine($"{padding}Message resource entries"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}Message resource entries"); + builder.AppendLine($"{padding}-------------------------"); if (messageTable.Entries == null || messageTable.Entries.Count == 0) { - Console.WriteLine($"{padding}No message resource entries"); + builder.AppendLine($"{padding}No message resource entries"); } else { @@ -2513,10 +2529,10 @@ namespace BurnOutSharp.Wrappers uint index = kvp.Key; var messageResourceEntry = kvp.Value; - Console.WriteLine($"{padding}Message resource entry {index}"); - Console.WriteLine($"{padding} Length: {messageResourceEntry.Length} (0x{messageResourceEntry.Length:X})"); - Console.WriteLine($"{padding} Flags: {messageResourceEntry.Flags} (0x{messageResourceEntry.Flags:X})"); - Console.WriteLine($"{padding} Text: {messageResourceEntry.Text}"); + builder.AppendLine($"{padding}Message resource entry {index}"); + builder.AppendLine($"{padding} Length: {messageResourceEntry.Length} (0x{messageResourceEntry.Length:X})"); + builder.AppendLine($"{padding} Flags: {messageResourceEntry.Flags} (0x{messageResourceEntry.Flags:X})"); + builder.AppendLine($"{padding} Text: {messageResourceEntry.Text}"); } } } @@ -2524,25 +2540,28 @@ namespace BurnOutSharp.Wrappers /// /// Print an RT_GROUP_CURSOR resource /// - private static void PrintResourceRT_GROUP_CURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_GROUP_CURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Hardware-independent cursor resource found, not parsed yet"); + builder.AppendLine($"{padding}Hardware-independent cursor resource found, not parsed yet"); } /// /// Print an RT_GROUP_ICON resource /// - private static void PrintResourceRT_GROUP_ICON(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_GROUP_ICON(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Hardware-independent icon resource found, not parsed yet"); + builder.AppendLine($"{padding}Hardware-independent icon resource found, not parsed yet"); } /// /// Print an RT_VERSION resource /// - private static void PrintResourceRT_VERSION(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_VERSION(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2550,42 +2569,42 @@ namespace BurnOutSharp.Wrappers try { versionInfo = entry.AsVersionInfo(); } catch { } if (versionInfo == null) { - Console.WriteLine($"{padding}Version info resource found, but malformed"); + builder.AppendLine($"{padding}Version info resource found, but malformed"); return; } - Console.WriteLine($"{padding}Length: {versionInfo.Length} (0x{versionInfo.Length:X})"); - Console.WriteLine($"{padding}Value length: {versionInfo.ValueLength} (0x{versionInfo.ValueLength:X})"); - Console.WriteLine($"{padding}Resource type: {versionInfo.ResourceType} (0x{versionInfo.ResourceType:X})"); - Console.WriteLine($"{padding}Key: {versionInfo.Key}"); + builder.AppendLine($"{padding}Length: {versionInfo.Length} (0x{versionInfo.Length:X})"); + builder.AppendLine($"{padding}Value length: {versionInfo.ValueLength} (0x{versionInfo.ValueLength:X})"); + builder.AppendLine($"{padding}Resource type: {versionInfo.ResourceType} (0x{versionInfo.ResourceType:X})"); + builder.AppendLine($"{padding}Key: {versionInfo.Key}"); if (versionInfo.ValueLength != 0 && versionInfo.Value != null) { - Console.WriteLine($"{padding}[Fixed File Info] Signature: {versionInfo.Value.Signature} (0x{versionInfo.Value.Signature:X})"); - Console.WriteLine($"{padding}[Fixed File Info] Struct version: {versionInfo.Value.StrucVersion} (0x{versionInfo.Value.StrucVersion:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File version (MS): {versionInfo.Value.FileVersionMS} (0x{versionInfo.Value.FileVersionMS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File version (LS): {versionInfo.Value.FileVersionLS} (0x{versionInfo.Value.FileVersionLS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] Product version (MS): {versionInfo.Value.ProductVersionMS} (0x{versionInfo.Value.ProductVersionMS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] Product version (LS): {versionInfo.Value.ProductVersionLS} (0x{versionInfo.Value.ProductVersionLS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File flags mask: {versionInfo.Value.FileFlagsMask} (0x{versionInfo.Value.FileFlagsMask:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File flags: {versionInfo.Value.FileFlags} (0x{versionInfo.Value.FileFlags:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File OS: {versionInfo.Value.FileOS} (0x{versionInfo.Value.FileOS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] Type: {versionInfo.Value.FileType} (0x{versionInfo.Value.FileType:X})"); - Console.WriteLine($"{padding}[Fixed File Info] Subtype: {versionInfo.Value.FileSubtype} (0x{versionInfo.Value.FileSubtype:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File date (MS): {versionInfo.Value.FileDateMS} (0x{versionInfo.Value.FileDateMS:X})"); - Console.WriteLine($"{padding}[Fixed File Info] File date (LS): {versionInfo.Value.FileDateLS} (0x{versionInfo.Value.FileDateLS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Signature: {versionInfo.Value.Signature} (0x{versionInfo.Value.Signature:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Struct version: {versionInfo.Value.StrucVersion} (0x{versionInfo.Value.StrucVersion:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File version (MS): {versionInfo.Value.FileVersionMS} (0x{versionInfo.Value.FileVersionMS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File version (LS): {versionInfo.Value.FileVersionLS} (0x{versionInfo.Value.FileVersionLS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Product version (MS): {versionInfo.Value.ProductVersionMS} (0x{versionInfo.Value.ProductVersionMS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Product version (LS): {versionInfo.Value.ProductVersionLS} (0x{versionInfo.Value.ProductVersionLS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File flags mask: {versionInfo.Value.FileFlagsMask} (0x{versionInfo.Value.FileFlagsMask:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File flags: {versionInfo.Value.FileFlags} (0x{versionInfo.Value.FileFlags:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File OS: {versionInfo.Value.FileOS} (0x{versionInfo.Value.FileOS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Type: {versionInfo.Value.FileType} (0x{versionInfo.Value.FileType:X})"); + builder.AppendLine($"{padding}[Fixed File Info] Subtype: {versionInfo.Value.FileSubtype} (0x{versionInfo.Value.FileSubtype:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File date (MS): {versionInfo.Value.FileDateMS} (0x{versionInfo.Value.FileDateMS:X})"); + builder.AppendLine($"{padding}[Fixed File Info] File date (LS): {versionInfo.Value.FileDateLS} (0x{versionInfo.Value.FileDateLS:X})"); } if (versionInfo.StringFileInfo != null) { - Console.WriteLine($"{padding}[String File Info] Length: {versionInfo.StringFileInfo.Length} (0x{versionInfo.StringFileInfo.Length:X})"); - Console.WriteLine($"{padding}[String File Info] Value length: {versionInfo.StringFileInfo.ValueLength} (0x{versionInfo.StringFileInfo.ValueLength:X})"); - Console.WriteLine($"{padding}[String File Info] Resource type: {versionInfo.StringFileInfo.ResourceType} (0x{versionInfo.StringFileInfo.ResourceType:X})"); - Console.WriteLine($"{padding}[String File Info] Key: {versionInfo.StringFileInfo.Key}"); - Console.WriteLine($"{padding}Children:"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}[String File Info] Length: {versionInfo.StringFileInfo.Length} (0x{versionInfo.StringFileInfo.Length:X})"); + builder.AppendLine($"{padding}[String File Info] Value length: {versionInfo.StringFileInfo.ValueLength} (0x{versionInfo.StringFileInfo.ValueLength:X})"); + builder.AppendLine($"{padding}[String File Info] Resource type: {versionInfo.StringFileInfo.ResourceType} (0x{versionInfo.StringFileInfo.ResourceType:X})"); + builder.AppendLine($"{padding}[String File Info] Key: {versionInfo.StringFileInfo.Key}"); + builder.AppendLine($"{padding}Children:"); + builder.AppendLine($"{padding}-------------------------"); if (versionInfo.StringFileInfo.Children == null || versionInfo.StringFileInfo.Children.Length == 0) { - Console.WriteLine($"{padding}No string file info children"); + builder.AppendLine($"{padding}No string file info children"); } else { @@ -2593,15 +2612,15 @@ namespace BurnOutSharp.Wrappers { var stringFileInfoChildEntry = versionInfo.StringFileInfo.Children[i]; - Console.WriteLine($"{padding} [String Table {i}] Length: {stringFileInfoChildEntry.Length} (0x{stringFileInfoChildEntry.Length:X})"); - Console.WriteLine($"{padding} [String Table {i}] Value length: {stringFileInfoChildEntry.ValueLength} (0x{stringFileInfoChildEntry.ValueLength:X})"); - Console.WriteLine($"{padding} [String Table {i}] ResourceType: {stringFileInfoChildEntry.ResourceType} (0x{stringFileInfoChildEntry.ResourceType:X})"); - Console.WriteLine($"{padding} [String Table {i}] Key: {stringFileInfoChildEntry.Key}"); - Console.WriteLine($"{padding} [String Table {i}] Children:"); - Console.WriteLine($"{padding} -------------------------"); + builder.AppendLine($"{padding} [String Table {i}] Length: {stringFileInfoChildEntry.Length} (0x{stringFileInfoChildEntry.Length:X})"); + builder.AppendLine($"{padding} [String Table {i}] Value length: {stringFileInfoChildEntry.ValueLength} (0x{stringFileInfoChildEntry.ValueLength:X})"); + builder.AppendLine($"{padding} [String Table {i}] ResourceType: {stringFileInfoChildEntry.ResourceType} (0x{stringFileInfoChildEntry.ResourceType:X})"); + builder.AppendLine($"{padding} [String Table {i}] Key: {stringFileInfoChildEntry.Key}"); + builder.AppendLine($"{padding} [String Table {i}] Children:"); + builder.AppendLine($"{padding} -------------------------"); if (stringFileInfoChildEntry.Children == null || stringFileInfoChildEntry.Children.Length == 0) { - Console.WriteLine($"{padding} No string table {i} children"); + builder.AppendLine($"{padding} No string table {i} children"); } else { @@ -2609,11 +2628,11 @@ namespace BurnOutSharp.Wrappers { var stringDataEntry = stringFileInfoChildEntry.Children[j]; - Console.WriteLine($"{padding} [String Data {j}] Length: {stringDataEntry.Length} (0x{stringDataEntry.Length:X})"); - Console.WriteLine($"{padding} [String Data {j}] Value length: {stringDataEntry.ValueLength} (0x{stringDataEntry.ValueLength:X})"); - Console.WriteLine($"{padding} [String Data {j}] ResourceType: {stringDataEntry.ResourceType} (0x{stringDataEntry.ResourceType:X})"); - Console.WriteLine($"{padding} [String Data {j}] Key: {stringDataEntry.Key}"); - Console.WriteLine($"{padding} [String Data {j}] Value: {stringDataEntry.Value}"); + builder.AppendLine($"{padding} [String Data {j}] Length: {stringDataEntry.Length} (0x{stringDataEntry.Length:X})"); + builder.AppendLine($"{padding} [String Data {j}] Value length: {stringDataEntry.ValueLength} (0x{stringDataEntry.ValueLength:X})"); + builder.AppendLine($"{padding} [String Data {j}] ResourceType: {stringDataEntry.ResourceType} (0x{stringDataEntry.ResourceType:X})"); + builder.AppendLine($"{padding} [String Data {j}] Key: {stringDataEntry.Key}"); + builder.AppendLine($"{padding} [String Data {j}] Value: {stringDataEntry.Value}"); } } } @@ -2622,15 +2641,15 @@ namespace BurnOutSharp.Wrappers if (versionInfo.VarFileInfo != null) { - Console.WriteLine($"{padding}[Var File Info] Length: {versionInfo.VarFileInfo.Length} (0x{versionInfo.VarFileInfo.Length:X})"); - Console.WriteLine($"{padding}[Var File Info] Value length: {versionInfo.VarFileInfo.ValueLength} (0x{versionInfo.VarFileInfo.ValueLength:X})"); - Console.WriteLine($"{padding}[Var File Info] Resource type: {versionInfo.VarFileInfo.ResourceType} (0x{versionInfo.VarFileInfo.ResourceType:X})"); - Console.WriteLine($"{padding}[Var File Info] Key: {versionInfo.VarFileInfo.Key}"); - Console.WriteLine($"{padding}Children:"); - Console.WriteLine($"{padding}-------------------------"); + builder.AppendLine($"{padding}[Var File Info] Length: {versionInfo.VarFileInfo.Length} (0x{versionInfo.VarFileInfo.Length:X})"); + builder.AppendLine($"{padding}[Var File Info] Value length: {versionInfo.VarFileInfo.ValueLength} (0x{versionInfo.VarFileInfo.ValueLength:X})"); + builder.AppendLine($"{padding}[Var File Info] Resource type: {versionInfo.VarFileInfo.ResourceType} (0x{versionInfo.VarFileInfo.ResourceType:X})"); + builder.AppendLine($"{padding}[Var File Info] Key: {versionInfo.VarFileInfo.Key}"); + builder.AppendLine($"{padding}Children:"); + builder.AppendLine($"{padding}-------------------------"); if (versionInfo.VarFileInfo.Children == null || versionInfo.VarFileInfo.Children.Length == 0) { - Console.WriteLine($"{padding}No var file info children"); + builder.AppendLine($"{padding}No var file info children"); } else { @@ -2638,11 +2657,11 @@ namespace BurnOutSharp.Wrappers { var varFileInfoChildEntry = versionInfo.VarFileInfo.Children[i]; - Console.WriteLine($"{padding} [String Table {i}] Length: {varFileInfoChildEntry.Length} (0x{varFileInfoChildEntry.Length:X})"); - Console.WriteLine($"{padding} [String Table {i}] Value length: {varFileInfoChildEntry.ValueLength} (0x{varFileInfoChildEntry.ValueLength:X})"); - Console.WriteLine($"{padding} [String Table {i}] ResourceType: {varFileInfoChildEntry.ResourceType} (0x{varFileInfoChildEntry.ResourceType:X})"); - Console.WriteLine($"{padding} [String Table {i}] Key: {varFileInfoChildEntry.Key}"); - Console.WriteLine($"{padding} [String Table {i}] Value: {string.Join(",", varFileInfoChildEntry.Value)}"); + builder.AppendLine($"{padding} [String Table {i}] Length: {varFileInfoChildEntry.Length} (0x{varFileInfoChildEntry.Length:X})"); + builder.AppendLine($"{padding} [String Table {i}] Value length: {varFileInfoChildEntry.ValueLength} (0x{varFileInfoChildEntry.ValueLength:X})"); + builder.AppendLine($"{padding} [String Table {i}] ResourceType: {varFileInfoChildEntry.ResourceType} (0x{varFileInfoChildEntry.ResourceType:X})"); + builder.AppendLine($"{padding} [String Table {i}] Key: {varFileInfoChildEntry.Key}"); + builder.AppendLine($"{padding} [String Table {i}] Value: {string.Join(",", varFileInfoChildEntry.Value)}"); } } } @@ -2651,68 +2670,75 @@ namespace BurnOutSharp.Wrappers /// /// Print an RT_DLGINCLUDE resource /// - private static void PrintResourceRT_DLGINCLUDE(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_DLGINCLUDE(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}External header resource found, not parsed yet"); + builder.AppendLine($"{padding}External header resource found, not parsed yet"); } /// /// Print an RT_PLUGPLAY resource /// - private static void PrintResourceRT_PLUGPLAY(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_PLUGPLAY(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Plug and Play resource found, not parsed yet"); + builder.AppendLine($"{padding}Plug and Play resource found, not parsed yet"); } /// /// Print an RT_VXD resource /// - private static void PrintResourceRT_VXD(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_VXD(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}VXD found, not parsed yet"); + builder.AppendLine($"{padding}VXD found, not parsed yet"); } /// /// Print an RT_ANICURSOR resource /// - private static void PrintResourceRT_ANICURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_ANICURSOR(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Animated cursor found, not parsed yet"); + builder.AppendLine($"{padding}Animated cursor found, not parsed yet"); } /// /// Print an RT_ANIICON resource /// - private static void PrintResourceRT_ANIICON(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_ANIICON(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}Animated icon found, not parsed yet"); + builder.AppendLine($"{padding}Animated icon found, not parsed yet"); } /// /// Print an RT_HTML resource /// - private static void PrintResourceRT_HTML(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_HTML(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); - Console.WriteLine($"{padding}HTML resource found, not parsed yet"); + builder.AppendLine($"{padding}HTML resource found, not parsed yet"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); } /// /// Print an RT_MANIFEST resource /// - private static void PrintResourceRT_MANIFEST(Models.PortableExecutable.ResourceDataEntry entry, int level) + /// StringBuilder to append information to + private static void PrintResourceRT_MANIFEST(Models.PortableExecutable.ResourceDataEntry entry, int level, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); @@ -2720,39 +2746,39 @@ namespace BurnOutSharp.Wrappers try { assemblyManifest = entry.AsAssemblyManifest(); } catch { } if (assemblyManifest == null) { - Console.WriteLine($"{padding}Assembly manifest found, but malformed"); + builder.AppendLine($"{padding}Assembly manifest found, but malformed"); return; } - Console.WriteLine($"{padding}Manifest version: {assemblyManifest.ManifestVersion}"); + builder.AppendLine($"{padding}Manifest version: {assemblyManifest.ManifestVersion}"); if (assemblyManifest.AssemblyIdentities != null && assemblyManifest.AssemblyIdentities.Length > 0) { for (int i = 0; i < assemblyManifest.AssemblyIdentities.Length; i++) { var assemblyIdentity = assemblyManifest.AssemblyIdentities[i]; - Console.WriteLine($"{padding}[Assembly Identity {i}] Name: {assemblyIdentity.Name}"); - Console.WriteLine($"{padding}[Assembly Identity {i}] Version: {assemblyIdentity.Version}"); - Console.WriteLine($"{padding}[Assembly Identity {i}] Type: {assemblyIdentity.Type}"); - Console.WriteLine($"{padding}[Assembly Identity {i}] Processor architecture: {assemblyIdentity.ProcessorArchitecture}"); - Console.WriteLine($"{padding}[Assembly Identity {i}] Public key token: {assemblyIdentity.PublicKeyToken}"); - Console.WriteLine($"{padding}[Assembly Identity {i}] Language: {assemblyIdentity.Language}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Name: {assemblyIdentity.Name}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Version: {assemblyIdentity.Version}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Type: {assemblyIdentity.Type}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Processor architecture: {assemblyIdentity.ProcessorArchitecture}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Public key token: {assemblyIdentity.PublicKeyToken}"); + builder.AppendLine($"{padding}[Assembly Identity {i}] Language: {assemblyIdentity.Language}"); } } if (assemblyManifest.Description != null) - Console.WriteLine($"{padding}[Assembly Description] Value: {assemblyManifest.Description.Value}"); + builder.AppendLine($"{padding}[Assembly Description] Value: {assemblyManifest.Description.Value}"); if (assemblyManifest.COMInterfaceExternalProxyStub != null && assemblyManifest.COMInterfaceExternalProxyStub.Length > 0) { for (int i = 0; i < assemblyManifest.COMInterfaceExternalProxyStub.Length; i++) { var comInterfaceExternalProxyStub = assemblyManifest.COMInterfaceExternalProxyStub[i]; - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] IID: {comInterfaceExternalProxyStub.IID}"); - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] Name: {comInterfaceExternalProxyStub.Name}"); - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] TLBID: {comInterfaceExternalProxyStub.TLBID}"); - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] Number of methods: {comInterfaceExternalProxyStub.NumMethods}"); - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] Proxy stub (CLSID32): {comInterfaceExternalProxyStub.ProxyStubClsid32}"); - Console.WriteLine($"{padding}[COM Interface External Proxy Stub {i}] Base interface: {comInterfaceExternalProxyStub.BaseInterface}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] IID: {comInterfaceExternalProxyStub.IID}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] Name: {comInterfaceExternalProxyStub.Name}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] TLBID: {comInterfaceExternalProxyStub.TLBID}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] Number of methods: {comInterfaceExternalProxyStub.NumMethods}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] Proxy stub (CLSID32): {comInterfaceExternalProxyStub.ProxyStubClsid32}"); + builder.AppendLine($"{padding}[COM Interface External Proxy Stub {i}] Base interface: {comInterfaceExternalProxyStub.BaseInterface}"); } } @@ -2765,25 +2791,25 @@ namespace BurnOutSharp.Wrappers { if (dependency.DependentAssembly.AssemblyIdentity != null) { - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Name: {dependency.DependentAssembly.AssemblyIdentity.Name}"); - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Version: {dependency.DependentAssembly.AssemblyIdentity.Version}"); - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Type: {dependency.DependentAssembly.AssemblyIdentity.Type}"); - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Processor architecture: {dependency.DependentAssembly.AssemblyIdentity.ProcessorArchitecture}"); - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Public key token: {dependency.DependentAssembly.AssemblyIdentity.PublicKeyToken}"); - Console.WriteLine($"{padding}[Dependency {i} Assembly Identity] Language: {dependency.DependentAssembly.AssemblyIdentity.Language}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Name: {dependency.DependentAssembly.AssemblyIdentity.Name}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Version: {dependency.DependentAssembly.AssemblyIdentity.Version}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Type: {dependency.DependentAssembly.AssemblyIdentity.Type}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Processor architecture: {dependency.DependentAssembly.AssemblyIdentity.ProcessorArchitecture}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Public key token: {dependency.DependentAssembly.AssemblyIdentity.PublicKeyToken}"); + builder.AppendLine($"{padding}[Dependency {i} Assembly Identity] Language: {dependency.DependentAssembly.AssemblyIdentity.Language}"); } if (dependency.DependentAssembly.BindingRedirect != null && dependency.DependentAssembly.BindingRedirect.Length > 0) { for (int j = 0; j < dependency.DependentAssembly.BindingRedirect.Length; j++) { var bindingRedirect = dependency.DependentAssembly.BindingRedirect[j]; - Console.WriteLine($"{padding}[Dependency {i} Binding Redirect {j}] Old version: {bindingRedirect.OldVersion}"); - Console.WriteLine($"{padding}[Dependency {i} Binding Redirect {j}] New version: {bindingRedirect.NewVersion}"); + builder.AppendLine($"{padding}[Dependency {i} Binding Redirect {j}] Old version: {bindingRedirect.OldVersion}"); + builder.AppendLine($"{padding}[Dependency {i} Binding Redirect {j}] New version: {bindingRedirect.NewVersion}"); } } } - Console.WriteLine($"{padding}[Dependency {i}] Optional: {dependency.Optional}"); + builder.AppendLine($"{padding}[Dependency {i}] Optional: {dependency.Optional}"); } } @@ -2792,28 +2818,28 @@ namespace BurnOutSharp.Wrappers for (int i = 0; i < assemblyManifest.File.Length; i++) { var file = assemblyManifest.File[i]; - Console.WriteLine($"{padding}[File {i}] Name: {file.Name}"); - Console.WriteLine($"{padding}[File {i}] Hash: {file.Hash}"); - Console.WriteLine($"{padding}[File {i}] Hash algorithm: {file.HashAlgorithm}"); - Console.WriteLine($"{padding}[File {i}] Size: {file.Size}"); + builder.AppendLine($"{padding}[File {i}] Name: {file.Name}"); + builder.AppendLine($"{padding}[File {i}] Hash: {file.Hash}"); + builder.AppendLine($"{padding}[File {i}] Hash algorithm: {file.HashAlgorithm}"); + builder.AppendLine($"{padding}[File {i}] Size: {file.Size}"); if (file.COMClass != null && file.COMClass.Length > 0) { for (int j = 0; j < file.COMClass.Length; j++) { var comClass = file.COMClass[j]; - Console.WriteLine($"{padding}[File {i} COM Class {j}] CLSID: {comClass.CLSID}"); - Console.WriteLine($"{padding}[File {i} COM Class {j}] Threading model: {comClass.ThreadingModel}"); - Console.WriteLine($"{padding}[File {i} COM Class {j}] Prog ID: {comClass.ProgID}"); - Console.WriteLine($"{padding}[File {i} COM Class {j}] TLBID: {comClass.TLBID}"); - Console.WriteLine($"{padding}[File {i} COM Class {j}] Description: {comClass.Description}"); + builder.AppendLine($"{padding}[File {i} COM Class {j}] CLSID: {comClass.CLSID}"); + builder.AppendLine($"{padding}[File {i} COM Class {j}] Threading model: {comClass.ThreadingModel}"); + builder.AppendLine($"{padding}[File {i} COM Class {j}] Prog ID: {comClass.ProgID}"); + builder.AppendLine($"{padding}[File {i} COM Class {j}] TLBID: {comClass.TLBID}"); + builder.AppendLine($"{padding}[File {i} COM Class {j}] Description: {comClass.Description}"); if (comClass.ProgIDs != null && comClass.ProgIDs.Length > 0) { for (int k = 0; k < comClass.ProgIDs.Length; k++) { var progId = comClass.ProgIDs[k]; - Console.WriteLine($"{padding}[File {i} COM Class {j} Prog ID {k}] Value: {progId.Value}"); + builder.AppendLine($"{padding}[File {i} COM Class {j} Prog ID {k}] Value: {progId.Value}"); } } } @@ -2824,12 +2850,12 @@ namespace BurnOutSharp.Wrappers for (int j = 0; j < file.COMInterfaceProxyStub.Length; j++) { var comInterfaceProxyStub = file.COMInterfaceProxyStub[j]; - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] IID: {comInterfaceProxyStub.IID}"); - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Name: {comInterfaceProxyStub.Name}"); - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] TLBID: {comInterfaceProxyStub.TLBID}"); - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Number of methods: {comInterfaceProxyStub.NumMethods}"); - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Proxy stub (CLSID32): {comInterfaceProxyStub.ProxyStubClsid32}"); - Console.WriteLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Base interface: {comInterfaceProxyStub.BaseInterface}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] IID: {comInterfaceProxyStub.IID}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Name: {comInterfaceProxyStub.Name}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] TLBID: {comInterfaceProxyStub.TLBID}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Number of methods: {comInterfaceProxyStub.NumMethods}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Proxy stub (CLSID32): {comInterfaceProxyStub.ProxyStubClsid32}"); + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] Base interface: {comInterfaceProxyStub.BaseInterface}"); } } @@ -2838,11 +2864,11 @@ namespace BurnOutSharp.Wrappers for (int j = 0; j < file.Typelib.Length; j++) { var typeLib = file.Typelib[j]; - Console.WriteLine($"{padding}[File {i} Type Lib {j}] TLBID: {typeLib.TLBID}"); - Console.WriteLine($"{padding}[File {i} Type Lib {j}] Version: {typeLib.Version}"); - Console.WriteLine($"{padding}[File {i} Type Lib {j}] Help directory: {typeLib.HelpDir}"); - Console.WriteLine($"{padding}[File {i} Type Lib {j}] Resource ID: {typeLib.ResourceID}"); - Console.WriteLine($"{padding}[File {i} Type Lib {j}] Flags: {typeLib.Flags}"); + builder.AppendLine($"{padding}[File {i} Type Lib {j}] TLBID: {typeLib.TLBID}"); + builder.AppendLine($"{padding}[File {i} Type Lib {j}] Version: {typeLib.Version}"); + builder.AppendLine($"{padding}[File {i} Type Lib {j}] Help directory: {typeLib.HelpDir}"); + builder.AppendLine($"{padding}[File {i} Type Lib {j}] Resource ID: {typeLib.ResourceID}"); + builder.AppendLine($"{padding}[File {i} Type Lib {j}] Flags: {typeLib.Flags}"); } } @@ -2851,8 +2877,8 @@ namespace BurnOutSharp.Wrappers for (int j = 0; j < file.WindowClass.Length; j++) { var windowClass = file.WindowClass[j]; - Console.WriteLine($"{padding}[File {i} Window Class {j}] Versioned: {windowClass.Versioned}"); - Console.WriteLine($"{padding}[File {i} Window Class {j}] Value: {windowClass.Value}"); + builder.AppendLine($"{padding}[File {i} Window Class {j}] Versioned: {windowClass.Versioned}"); + builder.AppendLine($"{padding}[File {i} Window Class {j}] Value: {windowClass.Value}"); } } } @@ -2865,11 +2891,11 @@ namespace BurnOutSharp.Wrappers var thing = assemblyManifest.EverythingElse[i]; if (thing is XmlElement element) { - Console.WriteLine($"{padding}Unparsed XML Element {i}: {element.OuterXml}"); + builder.AppendLine($"{padding}Unparsed XML Element {i}: {element.OuterXml}"); } else { - Console.WriteLine($"{padding}Unparsed Item {i}: {thing}"); + builder.AppendLine($"{padding}Unparsed Item {i}: {thing}"); } } } @@ -2878,22 +2904,23 @@ namespace BurnOutSharp.Wrappers /// /// Print an UNKNOWN or custom resource /// - private static void PrintResourceUNKNOWN(Models.PortableExecutable.ResourceDataEntry entry, int level, object resourceType) + /// StringBuilder to append information to + private static void PrintResourceUNKNOWN(Models.PortableExecutable.ResourceDataEntry entry, int level, object resourceType, StringBuilder builder) { string padding = new string(' ', (level + 1) * 2); // Print the type first if (resourceType is uint numericType) - Console.WriteLine($"{padding}Type {(Models.PortableExecutable.ResourceType)numericType} found, not parsed yet"); + builder.AppendLine($"{padding}Type {(Models.PortableExecutable.ResourceType)numericType} found, not parsed yet"); else if (resourceType is string stringType) - Console.WriteLine($"{padding}Type {stringType} found, not parsed yet"); + builder.AppendLine($"{padding}Type {stringType} found, not parsed yet"); else - Console.WriteLine($"{padding}Unknown type {resourceType} found, not parsed yet"); + builder.AppendLine($"{padding}Unknown type {resourceType} found, not parsed yet"); // Then print the data, if needed if (entry.Data == null) { - Console.WriteLine($"{padding}Data: [NULL] (This may indicate a very large resource)"); + builder.AppendLine($"{padding}Data: [NULL] (This may indicate a very large resource)"); } else { @@ -2902,24 +2929,24 @@ namespace BurnOutSharp.Wrappers if (entry.Data[0] == 0x4D && entry.Data[1] == 0x5A) { - Console.WriteLine($"{padding}Data: [Embedded Executable File]"); // TODO: Parse this out and print separately + builder.AppendLine($"{padding}Data: [Embedded Executable File]"); // TODO: Parse this out and print separately } else if (entry.Data[0] == 0x4D && entry.Data[1] == 0x53 && entry.Data[2] == 0x46 && entry.Data[3] == 0x54) { - Console.WriteLine($"{padding}Data: [Embedded OLE Library File]"); // TODO: Parse this out and print separately + builder.AppendLine($"{padding}Data: [Embedded OLE Library File]"); // TODO: Parse this out and print separately } else { - Console.WriteLine($"{padding}Data: {BitConverter.ToString(magic).Replace('-', ' ')} ..."); + builder.AppendLine($"{padding}Data: {BitConverter.ToString(magic).Replace('-', ' ')} ..."); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (Byte Data): {BitConverter.ToString(entry.Data).Replace('-', ' ')}"); + // builder.AppendLine($"{padding}Value (Byte Data): {BitConverter.ToString(entry.Data).Replace('-', ' ')}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (ASCII): {Encoding.ASCII.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (UTF-8): {Encoding.UTF8.GetString(entry.Data)}"); //if (entry.Data != null) - // Console.WriteLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); + // builder.AppendLine($"{padding}Value (Unicode): {Encoding.Unicode.GetString(entry.Data)}"); } } } diff --git a/BurnOutSharp.Wrappers/Quantum.cs b/BurnOutSharp.Wrappers/Quantum.cs index 1604696c..9b09b692 100644 --- a/BurnOutSharp.Wrappers/Quantum.cs +++ b/BurnOutSharp.Wrappers/Quantum.cs @@ -1,7 +1,5 @@ -using System; using System.IO; -using System.Linq; -using BurnOutSharp.Compression.Quantum; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -221,63 +219,69 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("Quantum Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintFileList(); - Console.WriteLine($" Compressed data offset: {CompressedDataOffset} (0x{CompressedDataOffset:X})"); - Console.WriteLine(); + builder.AppendLine("Quantum Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintFileList(builder); + builder.AppendLine($" Compressed data offset: {CompressedDataOffset} (0x{CompressedDataOffset:X})"); + builder.AppendLine(); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); - Console.WriteLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); - Console.WriteLine($" File count: {FileCount} (0x{FileCount:X})"); - Console.WriteLine($" Table size: {TableSize} (0x{TableSize:X})"); - Console.WriteLine($" Compression flags: {CompressionFlags} (0x{CompressionFlags:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); + builder.AppendLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); + builder.AppendLine($" File count: {FileCount} (0x{FileCount:X})"); + builder.AppendLine($" Table size: {TableSize} (0x{TableSize:X})"); + builder.AppendLine($" Compression flags: {CompressionFlags} (0x{CompressionFlags:X})"); + builder.AppendLine(); } /// /// Print file list information /// - private void PrintFileList() + /// StringBuilder to append information to + private void PrintFileList(StringBuilder builder) { - Console.WriteLine(" File List Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" File List Information:"); + builder.AppendLine(" -------------------------"); if (FileCount == 0 || FileList == null || FileList.Length == 0) { - Console.WriteLine(" No file list items"); + builder.AppendLine(" No file list items"); } else { for (int i = 0; i < FileList.Length; i++) { var fileDescriptor = FileList[i]; - Console.WriteLine($" File Descriptor {i}"); - Console.WriteLine($" File name size: {fileDescriptor.FileNameSize} (0x{fileDescriptor.FileNameSize:X})"); - Console.WriteLine($" File name: {fileDescriptor.FileName ?? "[NULL]"}"); - Console.WriteLine($" Comment field size: {fileDescriptor.CommentFieldSize} (0x{fileDescriptor.CommentFieldSize:X})"); - Console.WriteLine($" Comment field: {fileDescriptor.CommentField ?? "[NULL]"}"); - Console.WriteLine($" Expanded file size: {fileDescriptor.ExpandedFileSize} (0x{fileDescriptor.ExpandedFileSize:X})"); - Console.WriteLine($" File time: {fileDescriptor.FileTime} (0x{fileDescriptor.FileTime:X})"); - Console.WriteLine($" File date: {fileDescriptor.FileDate} (0x{fileDescriptor.FileDate:X})"); + builder.AppendLine($" File Descriptor {i}"); + builder.AppendLine($" File name size: {fileDescriptor.FileNameSize} (0x{fileDescriptor.FileNameSize:X})"); + builder.AppendLine($" File name: {fileDescriptor.FileName ?? "[NULL]"}"); + builder.AppendLine($" Comment field size: {fileDescriptor.CommentFieldSize} (0x{fileDescriptor.CommentFieldSize:X})"); + builder.AppendLine($" Comment field: {fileDescriptor.CommentField ?? "[NULL]"}"); + builder.AppendLine($" Expanded file size: {fileDescriptor.ExpandedFileSize} (0x{fileDescriptor.ExpandedFileSize:X})"); + builder.AppendLine($" File time: {fileDescriptor.FileTime} (0x{fileDescriptor.FileTime:X})"); + builder.AppendLine($" File date: {fileDescriptor.FileDate} (0x{fileDescriptor.FileDate:X})"); if (fileDescriptor.Unknown != null) - Console.WriteLine($" Unknown (Checksum?): {fileDescriptor.Unknown} (0x{fileDescriptor.Unknown:X})"); + builder.AppendLine($" Unknown (Checksum?): {fileDescriptor.Unknown} (0x{fileDescriptor.Unknown:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/SGA.cs b/BurnOutSharp.Wrappers/SGA.cs index b2583a23..58db6fc0 100644 --- a/BurnOutSharp.Wrappers/SGA.cs +++ b/BurnOutSharp.Wrappers/SGA.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using ICSharpCode.SharpZipLib.Zip.Compression; namespace BurnOutSharp.Wrappers @@ -414,223 +415,232 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("SGA Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); + + builder.AppendLine("SGA Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); // Header - PrintHeader(); + PrintHeader(builder); // Directory - PrintDirectoryHeader(); - PrintSections(); - PrintFolders(); - PrintFiles(); + PrintDirectoryHeader(builder); + PrintSections(builder); + PrintFolders(builder); + PrintFiles(builder); // TODO: Should we print the string table? + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); - Console.WriteLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); - Console.WriteLine($" File MD5: {(FileMD5 == null ? "[NULL]" : BitConverter.ToString(FileMD5).Replace("-", string.Empty))}"); - Console.WriteLine($" Name: {Name ?? "[NULL]"}"); - Console.WriteLine($" Header MD5: {(HeaderMD5 == null ? "[NULL]" : BitConverter.ToString(HeaderMD5).Replace("-", string.Empty))}"); - Console.WriteLine($" Header length: {HeaderLength?.ToString() ?? "[NULL]"} (0x{HeaderLength?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" File data offset: {FileDataOffset?.ToString() ?? "[NULL]"} (0x{FileDataOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Dummy 0: {Dummy0?.ToString() ?? "[NULL]"} (0x{Dummy0?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Major version: {MajorVersion} (0x{MajorVersion:X})"); + builder.AppendLine($" Minor version: {MinorVersion} (0x{MinorVersion:X})"); + builder.AppendLine($" File MD5: {(FileMD5 == null ? "[NULL]" : BitConverter.ToString(FileMD5).Replace("-", string.Empty))}"); + builder.AppendLine($" Name: {Name ?? "[NULL]"}"); + builder.AppendLine($" Header MD5: {(HeaderMD5 == null ? "[NULL]" : BitConverter.ToString(HeaderMD5).Replace("-", string.Empty))}"); + builder.AppendLine($" Header length: {HeaderLength?.ToString() ?? "[NULL]"} (0x{HeaderLength?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" File data offset: {FileDataOffset?.ToString() ?? "[NULL]"} (0x{FileDataOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Dummy 0: {Dummy0?.ToString() ?? "[NULL]"} (0x{Dummy0?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine(); } /// /// Print directory header information /// - private void PrintDirectoryHeader() + /// StringBuilder to append information to + private void PrintDirectoryHeader(StringBuilder builder) { - Console.WriteLine(" Directory Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Section offset: {SectionOffset?.ToString() ?? "[NULL]"} (0x{SectionOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Section count: {SectionCount?.ToString() ?? "[NULL]"} (0x{SectionCount?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Folder offset: {FolderOffset?.ToString() ?? "[NULL]"} (0x{FolderOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Folder count: {FolderCount?.ToString() ?? "[NULL]"} (0x{FolderCount?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" File offset: {FileOffset?.ToString() ?? "[NULL]"} (0x{FileOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" File count: {FileCount?.ToString() ?? "[NULL]"} (0x{FileCount?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" String table offset: {StringTableOffset?.ToString() ?? "[NULL]"} (0x{StringTableOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" String table count: {StringTableCount?.ToString() ?? "[NULL]"} (0x{StringTableCount?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Hash table offset: {HashTableOffset?.ToString() ?? "[NULL]"} (0x{HashTableOffset?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine($" Block size: {BlockSize?.ToString() ?? "[NULL]"} (0x{BlockSize?.ToString("X") ?? "[NULL]"})"); - Console.WriteLine(); + builder.AppendLine(" Directory Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Section offset: {SectionOffset?.ToString() ?? "[NULL]"} (0x{SectionOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Section count: {SectionCount?.ToString() ?? "[NULL]"} (0x{SectionCount?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Folder offset: {FolderOffset?.ToString() ?? "[NULL]"} (0x{FolderOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Folder count: {FolderCount?.ToString() ?? "[NULL]"} (0x{FolderCount?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" File offset: {FileOffset?.ToString() ?? "[NULL]"} (0x{FileOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" File count: {FileCount?.ToString() ?? "[NULL]"} (0x{FileCount?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" String table offset: {StringTableOffset?.ToString() ?? "[NULL]"} (0x{StringTableOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" String table count: {StringTableCount?.ToString() ?? "[NULL]"} (0x{StringTableCount?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Hash table offset: {HashTableOffset?.ToString() ?? "[NULL]"} (0x{HashTableOffset?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine($" Block size: {BlockSize?.ToString() ?? "[NULL]"} (0x{BlockSize?.ToString("X") ?? "[NULL]"})"); + builder.AppendLine(); } /// /// Print sections information /// - private void PrintSections() + /// StringBuilder to append information to + private void PrintSections(StringBuilder builder) { - Console.WriteLine(" Sections Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Sections Information:"); + builder.AppendLine(" -------------------------"); if (Sections == null || Sections.Length == 0) { - Console.WriteLine(" No sections"); + builder.AppendLine(" No sections"); } else { for (int i = 0; i < Sections.Length; i++) { - Console.WriteLine($" Section {i}"); + builder.AppendLine($" Section {i}"); switch (MajorVersion) { case 4: var section4 = Sections[i] as Models.SGA.Section4; - Console.WriteLine($" Alias: {section4.Alias ?? "[NULL]"}"); - Console.WriteLine($" Name: {section4.Name ?? "[NULL]"}"); - Console.WriteLine($" Folder start index: {section4.FolderStartIndex} (0x{section4.FolderStartIndex:X})"); - Console.WriteLine($" Folder end index: {section4.FolderEndIndex} (0x{section4.FolderEndIndex:X})"); - Console.WriteLine($" File start index: {section4.FileStartIndex} (0x{section4.FileStartIndex:X})"); - Console.WriteLine($" File end index: {section4.FileEndIndex} (0x{section4.FileEndIndex:X})"); - Console.WriteLine($" Folder root index: {section4.FolderRootIndex} (0x{section4.FolderRootIndex:X})"); + builder.AppendLine($" Alias: {section4.Alias ?? "[NULL]"}"); + builder.AppendLine($" Name: {section4.Name ?? "[NULL]"}"); + builder.AppendLine($" Folder start index: {section4.FolderStartIndex} (0x{section4.FolderStartIndex:X})"); + builder.AppendLine($" Folder end index: {section4.FolderEndIndex} (0x{section4.FolderEndIndex:X})"); + builder.AppendLine($" File start index: {section4.FileStartIndex} (0x{section4.FileStartIndex:X})"); + builder.AppendLine($" File end index: {section4.FileEndIndex} (0x{section4.FileEndIndex:X})"); + builder.AppendLine($" Folder root index: {section4.FolderRootIndex} (0x{section4.FolderRootIndex:X})"); break; case 5: case 6: case 7: var section5 = Sections[i] as Models.SGA.Section5; - Console.WriteLine($" Alias: {section5.Alias ?? "[NULL]"}"); - Console.WriteLine($" Name: {section5.Name ?? "[NULL]"}"); - Console.WriteLine($" Folder start index: {section5.FolderStartIndex} (0x{section5.FolderStartIndex:X})"); - Console.WriteLine($" Folder end index: {section5.FolderEndIndex} (0x{section5.FolderEndIndex:X})"); - Console.WriteLine($" File start index: {section5.FileStartIndex} (0x{section5.FileStartIndex:X})"); - Console.WriteLine($" File end index: {section5.FileEndIndex} (0x{section5.FileEndIndex:X})"); - Console.WriteLine($" Folder root index: {section5.FolderRootIndex} (0x{section5.FolderRootIndex:X})"); + builder.AppendLine($" Alias: {section5.Alias ?? "[NULL]"}"); + builder.AppendLine($" Name: {section5.Name ?? "[NULL]"}"); + builder.AppendLine($" Folder start index: {section5.FolderStartIndex} (0x{section5.FolderStartIndex:X})"); + builder.AppendLine($" Folder end index: {section5.FolderEndIndex} (0x{section5.FolderEndIndex:X})"); + builder.AppendLine($" File start index: {section5.FileStartIndex} (0x{section5.FileStartIndex:X})"); + builder.AppendLine($" File end index: {section5.FileEndIndex} (0x{section5.FileEndIndex:X})"); + builder.AppendLine($" Folder root index: {section5.FolderRootIndex} (0x{section5.FolderRootIndex:X})"); break; default: - Console.WriteLine($" Unknown format for version {MajorVersion}"); + builder.AppendLine($" Unknown format for version {MajorVersion}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print folders information /// - private void PrintFolders() + /// StringBuilder to append information to + private void PrintFolders(StringBuilder builder) { - Console.WriteLine(" Folders Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Folders Information:"); + builder.AppendLine(" -------------------------"); if (Folders == null || Folders.Length == 0) { - Console.WriteLine(" No folders"); + builder.AppendLine(" No folders"); } else { for (int i = 0; i < Folders.Length; i++) { - Console.WriteLine($" Folder {i}"); + builder.AppendLine($" Folder {i}"); switch (MajorVersion) { case 4: var folder4 = Folders[i] as Models.SGA.Folder4; - Console.WriteLine($" Name offset: {folder4.NameOffset} (0x{folder4.NameOffset:X})"); - Console.WriteLine($" Name: {folder4.Name ?? "[NULL]"}"); - Console.WriteLine($" Folder start index: {folder4.FolderStartIndex} (0x{folder4.FolderStartIndex:X})"); - Console.WriteLine($" Folder end index: {folder4.FolderEndIndex} (0x{folder4.FolderEndIndex:X})"); - Console.WriteLine($" File start index: {folder4.FileStartIndex} (0x{folder4.FileStartIndex:X})"); - Console.WriteLine($" File end index: {folder4.FileEndIndex} (0x{folder4.FileEndIndex:X})"); + builder.AppendLine($" Name offset: {folder4.NameOffset} (0x{folder4.NameOffset:X})"); + builder.AppendLine($" Name: {folder4.Name ?? "[NULL]"}"); + builder.AppendLine($" Folder start index: {folder4.FolderStartIndex} (0x{folder4.FolderStartIndex:X})"); + builder.AppendLine($" Folder end index: {folder4.FolderEndIndex} (0x{folder4.FolderEndIndex:X})"); + builder.AppendLine($" File start index: {folder4.FileStartIndex} (0x{folder4.FileStartIndex:X})"); + builder.AppendLine($" File end index: {folder4.FileEndIndex} (0x{folder4.FileEndIndex:X})"); break; case 5: case 6: case 7: var folder5 = Folders[i] as Models.SGA.Folder5; - Console.WriteLine($" Name offset: {folder5.NameOffset} (0x{folder5.NameOffset:X})"); - Console.WriteLine($" Name: {folder5.Name ?? "[NULL]"}"); - Console.WriteLine($" Folder start index: {folder5.FolderStartIndex} (0x{folder5.FolderStartIndex:X})"); - Console.WriteLine($" Folder end index: {folder5.FolderEndIndex} (0x{folder5.FolderEndIndex:X})"); - Console.WriteLine($" File start index: {folder5.FileStartIndex} (0x{folder5.FileStartIndex:X})"); - Console.WriteLine($" File end index: {folder5.FileEndIndex} (0x{folder5.FileEndIndex:X})"); + builder.AppendLine($" Name offset: {folder5.NameOffset} (0x{folder5.NameOffset:X})"); + builder.AppendLine($" Name: {folder5.Name ?? "[NULL]"}"); + builder.AppendLine($" Folder start index: {folder5.FolderStartIndex} (0x{folder5.FolderStartIndex:X})"); + builder.AppendLine($" Folder end index: {folder5.FolderEndIndex} (0x{folder5.FolderEndIndex:X})"); + builder.AppendLine($" File start index: {folder5.FileStartIndex} (0x{folder5.FileStartIndex:X})"); + builder.AppendLine($" File end index: {folder5.FileEndIndex} (0x{folder5.FileEndIndex:X})"); break; default: - Console.WriteLine($" Unknown format for version {MajorVersion}"); + builder.AppendLine($" Unknown format for version {MajorVersion}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print files information /// - private void PrintFiles() + /// StringBuilder to append information to + private void PrintFiles(StringBuilder builder) { - Console.WriteLine(" Files Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Files Information:"); + builder.AppendLine(" -------------------------"); if (Files == null || Files.Length == 0) { - Console.WriteLine(" No files"); + builder.AppendLine(" No files"); } else { for (int i = 0; i < Files.Length; i++) { - Console.WriteLine($" File {i}"); + builder.AppendLine($" File {i}"); switch (MajorVersion) { case 4: case 5: var file4 = Files[i] as Models.SGA.File4; - Console.WriteLine($" Name offset: {file4.NameOffset} (0x{file4.NameOffset:X})"); - Console.WriteLine($" Name: {file4.Name ?? "[NULL]"}"); - Console.WriteLine($" Offset: {file4.Offset} (0x{file4.Offset:X})"); - Console.WriteLine($" Size on disk: {file4.SizeOnDisk} (0x{file4.SizeOnDisk:X})"); - Console.WriteLine($" Size: {file4.Size} (0x{file4.Size:X})"); - Console.WriteLine($" Time modified: {file4.TimeModified} (0x{file4.TimeModified:X})"); - Console.WriteLine($" Dummy 0: {file4.Dummy0} (0x{file4.Dummy0:X})"); - Console.WriteLine($" Type: {file4.Type} (0x{file4.Type:X})"); + builder.AppendLine($" Name offset: {file4.NameOffset} (0x{file4.NameOffset:X})"); + builder.AppendLine($" Name: {file4.Name ?? "[NULL]"}"); + builder.AppendLine($" Offset: {file4.Offset} (0x{file4.Offset:X})"); + builder.AppendLine($" Size on disk: {file4.SizeOnDisk} (0x{file4.SizeOnDisk:X})"); + builder.AppendLine($" Size: {file4.Size} (0x{file4.Size:X})"); + builder.AppendLine($" Time modified: {file4.TimeModified} (0x{file4.TimeModified:X})"); + builder.AppendLine($" Dummy 0: {file4.Dummy0} (0x{file4.Dummy0:X})"); + builder.AppendLine($" Type: {file4.Type} (0x{file4.Type:X})"); break; case 6: var file6 = Files[i] as Models.SGA.File6; - Console.WriteLine($" Name offset: {file6.NameOffset} (0x{file6.NameOffset:X})"); - Console.WriteLine($" Name: {file6.Name ?? "[NULL]"}"); - Console.WriteLine($" Offset: {file6.Offset} (0x{file6.Offset:X})"); - Console.WriteLine($" Size on disk: {file6.SizeOnDisk} (0x{file6.SizeOnDisk:X})"); - Console.WriteLine($" Size: {file6.Size} (0x{file6.Size:X})"); - Console.WriteLine($" Time modified: {file6.TimeModified} (0x{file6.TimeModified:X})"); - Console.WriteLine($" Dummy 0: {file6.Dummy0} (0x{file6.Dummy0:X})"); - Console.WriteLine($" Type: {file6.Type} (0x{file6.Type:X})"); - Console.WriteLine($" CRC32: {file6.CRC32} (0x{file6.CRC32:X})"); + builder.AppendLine($" Name offset: {file6.NameOffset} (0x{file6.NameOffset:X})"); + builder.AppendLine($" Name: {file6.Name ?? "[NULL]"}"); + builder.AppendLine($" Offset: {file6.Offset} (0x{file6.Offset:X})"); + builder.AppendLine($" Size on disk: {file6.SizeOnDisk} (0x{file6.SizeOnDisk:X})"); + builder.AppendLine($" Size: {file6.Size} (0x{file6.Size:X})"); + builder.AppendLine($" Time modified: {file6.TimeModified} (0x{file6.TimeModified:X})"); + builder.AppendLine($" Dummy 0: {file6.Dummy0} (0x{file6.Dummy0:X})"); + builder.AppendLine($" Type: {file6.Type} (0x{file6.Type:X})"); + builder.AppendLine($" CRC32: {file6.CRC32} (0x{file6.CRC32:X})"); break; case 7: var file7 = Files[i] as Models.SGA.File7; - Console.WriteLine($" Name offset: {file7.NameOffset} (0x{file7.NameOffset:X})"); - Console.WriteLine($" Name: {file7.Name ?? "[NULL]"}"); - Console.WriteLine($" Offset: {file7.Offset} (0x{file7.Offset:X})"); - Console.WriteLine($" Size on disk: {file7.SizeOnDisk} (0x{file7.SizeOnDisk:X})"); - Console.WriteLine($" Size: {file7.Size} (0x{file7.Size:X})"); - Console.WriteLine($" Time modified: {file7.TimeModified} (0x{file7.TimeModified:X})"); - Console.WriteLine($" Dummy 0: {file7.Dummy0} (0x{file7.Dummy0:X})"); - Console.WriteLine($" Type: {file7.Type} (0x{file7.Type:X})"); - Console.WriteLine($" CRC32: {file7.CRC32} (0x{file7.CRC32:X})"); - Console.WriteLine($" Hash offset: {file7.HashOffset} (0x{file7.HashOffset:X})"); + builder.AppendLine($" Name offset: {file7.NameOffset} (0x{file7.NameOffset:X})"); + builder.AppendLine($" Name: {file7.Name ?? "[NULL]"}"); + builder.AppendLine($" Offset: {file7.Offset} (0x{file7.Offset:X})"); + builder.AppendLine($" Size on disk: {file7.SizeOnDisk} (0x{file7.SizeOnDisk:X})"); + builder.AppendLine($" Size: {file7.Size} (0x{file7.Size:X})"); + builder.AppendLine($" Time modified: {file7.TimeModified} (0x{file7.TimeModified:X})"); + builder.AppendLine($" Dummy 0: {file7.Dummy0} (0x{file7.Dummy0:X})"); + builder.AppendLine($" Type: {file7.Type} (0x{file7.Type:X})"); + builder.AppendLine($" CRC32: {file7.CRC32} (0x{file7.CRC32:X})"); + builder.AppendLine($" Hash offset: {file7.HashOffset} (0x{file7.HashOffset:X})"); break; default: - Console.WriteLine($" Unknown format for version {MajorVersion}"); + builder.AppendLine($" Unknown format for version {MajorVersion}"); break; } } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/VBSP.cs b/BurnOutSharp.Wrappers/VBSP.cs index fdb0760d..1f763495 100644 --- a/BurnOutSharp.Wrappers/VBSP.cs +++ b/BurnOutSharp.Wrappers/VBSP.cs @@ -1,5 +1,5 @@ -using System; using System.IO; +using System.Text; using static BurnOutSharp.Models.VBSP.Constants; namespace BurnOutSharp.Wrappers @@ -94,41 +94,47 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("VBSP Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintLumps(); + builder.AppendLine("VBSP Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintLumps(builder); + + return builder; } /// /// Print header information /// + /// StringBuilder to append information to /// Slightly out of order due to the lumps - private void PrintHeader() + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine($" Map revision: {MapRevision} (0x{MapRevision:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine($" Map revision: {MapRevision} (0x{MapRevision:X})"); + builder.AppendLine(); } /// /// Print lumps information /// + /// StringBuilder to append information to /// Technically part of the header - private void PrintLumps() + private void PrintLumps(StringBuilder builder) { - Console.WriteLine(" Lumps Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Lumps Information:"); + builder.AppendLine(" -------------------------"); if (Lumps == null || Lumps.Length == 0) { - Console.WriteLine(" No lumps"); + builder.AppendLine(" No lumps"); } else { @@ -146,14 +152,14 @@ namespace BurnOutSharp.Wrappers break; } - Console.WriteLine($" Lump {i}{specialLumpName}"); - Console.WriteLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); - Console.WriteLine($" Length: {lump.Length} (0x{lump.Length:X})"); - Console.WriteLine($" Version: {lump.Version} (0x{lump.Version:X})"); - Console.WriteLine($" 4CC: {string.Join(", ", lump.FourCC)}"); + builder.AppendLine($" Lump {i}{specialLumpName}"); + builder.AppendLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); + builder.AppendLine($" Length: {lump.Length} (0x{lump.Length:X})"); + builder.AppendLine($" Version: {lump.Version} (0x{lump.Version:X})"); + builder.AppendLine($" 4CC: {string.Join(", ", lump.FourCC)}"); } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/VPK.cs b/BurnOutSharp.Wrappers/VPK.cs index 7f031607..f7c713a7 100644 --- a/BurnOutSharp.Wrappers/VPK.cs +++ b/BurnOutSharp.Wrappers/VPK.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Text; using BurnOutSharp.Utilities; using static BurnOutSharp.Models.VPK.Constants; @@ -176,122 +177,131 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("VPK Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintExtendedHeader(); - PrintArchiveHashes(); - PrintDirectoryItems(); + builder.AppendLine("VPK Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintExtendedHeader(builder); + PrintArchiveHashes(builder); + PrintDirectoryItems(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature} (0x{Signature:X})"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine($" Directory length: {DirectoryLength} (0x{DirectoryLength:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature} (0x{Signature:X})"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine($" Directory length: {DirectoryLength} (0x{DirectoryLength:X})"); + builder.AppendLine(); } /// /// Print extended header information /// - private void PrintExtendedHeader() + /// StringBuilder to append information to + private void PrintExtendedHeader(StringBuilder builder) { - Console.WriteLine(" Extended Header Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Extended Header Information:"); + builder.AppendLine(" -------------------------"); if (_file.ExtendedHeader == null) { - Console.WriteLine(" No extended header"); + builder.AppendLine(" No extended header"); } else { - Console.WriteLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); - Console.WriteLine($" Archive hash length: {ArchiveHashLength} (0x{ArchiveHashLength:X})"); - Console.WriteLine($" Extra length: {ExtraLength} (0x{ExtraLength:X})"); - Console.WriteLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); - Console.WriteLine(); + builder.AppendLine($" Dummy 0: {Dummy0} (0x{Dummy0:X})"); + builder.AppendLine($" Archive hash length: {ArchiveHashLength} (0x{ArchiveHashLength:X})"); + builder.AppendLine($" Extra length: {ExtraLength} (0x{ExtraLength:X})"); + builder.AppendLine($" Dummy 1: {Dummy1} (0x{Dummy1:X})"); + builder.AppendLine(); } } /// /// Print archive hashes information /// - private void PrintArchiveHashes() + /// StringBuilder to append information to + private void PrintArchiveHashes(StringBuilder builder) { - Console.WriteLine(" Archive Hashes Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Archive Hashes Information:"); + builder.AppendLine(" -------------------------"); if (ArchiveHashes == null || ArchiveHashes.Length == 0) { - Console.WriteLine(" No archive hashes"); + builder.AppendLine(" No archive hashes"); } else { for (int i = 0; i < ArchiveHashes.Length; i++) { var archiveHash = ArchiveHashes[i]; - Console.WriteLine($" Archive Hash {i}"); - Console.WriteLine($" Archive index: {archiveHash.ArchiveIndex} (0x{archiveHash.ArchiveIndex:X})"); - Console.WriteLine($" Archive offset: {archiveHash.ArchiveOffset} (0x{archiveHash.ArchiveOffset:X})"); - Console.WriteLine($" Length: {archiveHash.Length} (0x{archiveHash.Length:X})"); - Console.WriteLine($" Hash: {BitConverter.ToString(archiveHash.Hash).Replace("-", string.Empty)}"); + builder.AppendLine($" Archive Hash {i}"); + builder.AppendLine($" Archive index: {archiveHash.ArchiveIndex} (0x{archiveHash.ArchiveIndex:X})"); + builder.AppendLine($" Archive offset: {archiveHash.ArchiveOffset} (0x{archiveHash.ArchiveOffset:X})"); + builder.AppendLine($" Length: {archiveHash.Length} (0x{archiveHash.Length:X})"); + builder.AppendLine($" Hash: {BitConverter.ToString(archiveHash.Hash).Replace("-", string.Empty)}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory items information /// - private void PrintDirectoryItems() + /// StringBuilder to append information to + private void PrintDirectoryItems(StringBuilder builder) { - Console.WriteLine(" Directory Items Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Items Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryItems == null || DirectoryItems.Length == 0) { - Console.WriteLine(" No directory items"); + builder.AppendLine(" No directory items"); } else { for (int i = 0; i < DirectoryItems.Length; i++) { var directoryItem = DirectoryItems[i]; - Console.WriteLine($" Directory Item {i}"); - Console.WriteLine($" Extension: {directoryItem.Extension}"); - Console.WriteLine($" Path: {directoryItem.Path}"); - Console.WriteLine($" Name: {directoryItem.Name}"); - PrintDirectoryEntry(directoryItem.DirectoryEntry); + builder.AppendLine($" Directory Item {i}"); + builder.AppendLine($" Extension: {directoryItem.Extension}"); + builder.AppendLine($" Path: {directoryItem.Path}"); + builder.AppendLine($" Name: {directoryItem.Name}"); + PrintDirectoryEntry(directoryItem.DirectoryEntry, builder); // TODO: Print out preload data? } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory entry information /// - private void PrintDirectoryEntry(Models.VPK.DirectoryEntry directoryEntry) + /// StringBuilder to append information to + private void PrintDirectoryEntry(Models.VPK.DirectoryEntry directoryEntry, StringBuilder builder) { if (directoryEntry == null) { - Console.WriteLine(" Directory entry: [NULL]"); + builder.AppendLine(" Directory entry: [NULL]"); } else { - Console.WriteLine($" Directory entry CRC: {directoryEntry.CRC} (0x{directoryEntry.CRC:X})"); - Console.WriteLine($" Directory entry preload bytes: {directoryEntry.PreloadBytes} (0x{directoryEntry.PreloadBytes:X})"); - Console.WriteLine($" Directory entry archive index: {directoryEntry.ArchiveIndex} (0x{directoryEntry.ArchiveIndex:X})"); - Console.WriteLine($" Directory entry entry offset: {directoryEntry.EntryOffset} (0x{directoryEntry.EntryOffset:X})"); - Console.WriteLine($" Directory entry entry length: {directoryEntry.EntryLength} (0x{directoryEntry.EntryLength:X})"); - Console.WriteLine($" Directory entry dummy 0: {directoryEntry.Dummy0} (0x{directoryEntry.Dummy0:X})"); + builder.AppendLine($" Directory entry CRC: {directoryEntry.CRC} (0x{directoryEntry.CRC:X})"); + builder.AppendLine($" Directory entry preload bytes: {directoryEntry.PreloadBytes} (0x{directoryEntry.PreloadBytes:X})"); + builder.AppendLine($" Directory entry archive index: {directoryEntry.ArchiveIndex} (0x{directoryEntry.ArchiveIndex:X})"); + builder.AppendLine($" Directory entry entry offset: {directoryEntry.EntryOffset} (0x{directoryEntry.EntryOffset:X})"); + builder.AppendLine($" Directory entry entry length: {directoryEntry.EntryLength} (0x{directoryEntry.EntryLength:X})"); + builder.AppendLine($" Directory entry dummy 0: {directoryEntry.Dummy0} (0x{directoryEntry.Dummy0:X})"); } } diff --git a/BurnOutSharp.Wrappers/WAD.cs b/BurnOutSharp.Wrappers/WAD.cs index 10b26056..9c0cdaf8 100644 --- a/BurnOutSharp.Wrappers/WAD.cs +++ b/BurnOutSharp.Wrappers/WAD.cs @@ -1,5 +1,5 @@ -using System; using System.IO; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -108,95 +108,102 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("WAD Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintLumps(); - PrintLumpInfos(); + builder.AppendLine("WAD Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintLumps(builder); + PrintLumpInfos(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Lump count: {LumpCount} (0x{LumpCount:X})"); - Console.WriteLine($" Lump offset: {LumpOffset} (0x{LumpOffset:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Lump count: {LumpCount} (0x{LumpCount:X})"); + builder.AppendLine($" Lump offset: {LumpOffset} (0x{LumpOffset:X})"); + builder.AppendLine(); } /// /// Print lumps information /// - private void PrintLumps() + /// StringBuilder to append information to + private void PrintLumps(StringBuilder builder) { - Console.WriteLine(" Lumps Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Lumps Information:"); + builder.AppendLine(" -------------------------"); if (Lumps == null || Lumps.Length == 0) { - Console.WriteLine(" No lumps"); + builder.AppendLine(" No lumps"); } else { for (int i = 0; i < Lumps.Length; i++) { var lump = Lumps[i]; - Console.WriteLine($" Lump {i}"); - Console.WriteLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); - Console.WriteLine($" Disk length: {lump.DiskLength} (0x{lump.DiskLength:X})"); - Console.WriteLine($" Length: {lump.Length} (0x{lump.Length:X})"); - Console.WriteLine($" Type: {lump.Type} (0x{lump.Type:X})"); - Console.WriteLine($" Compression: {lump.Compression} (0x{lump.Compression:X})"); - Console.WriteLine($" Padding 0: {lump.Padding0} (0x{lump.Padding0:X})"); - Console.WriteLine($" Padding 1: {lump.Padding1} (0x{lump.Padding1:X})"); - Console.WriteLine($" Name: {lump.Name ?? "[NULL]"}"); + builder.AppendLine($" Lump {i}"); + builder.AppendLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); + builder.AppendLine($" Disk length: {lump.DiskLength} (0x{lump.DiskLength:X})"); + builder.AppendLine($" Length: {lump.Length} (0x{lump.Length:X})"); + builder.AppendLine($" Type: {lump.Type} (0x{lump.Type:X})"); + builder.AppendLine($" Compression: {lump.Compression} (0x{lump.Compression:X})"); + builder.AppendLine($" Padding 0: {lump.Padding0} (0x{lump.Padding0:X})"); + builder.AppendLine($" Padding 1: {lump.Padding1} (0x{lump.Padding1:X})"); + builder.AppendLine($" Name: {lump.Name ?? "[NULL]"}"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print lump infos information /// - private void PrintLumpInfos() + /// StringBuilder to append information to + private void PrintLumpInfos(StringBuilder builder) { - Console.WriteLine(" Lump Infos Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Lump Infos Information:"); + builder.AppendLine(" -------------------------"); if (LumpInfos == null || LumpInfos.Length == 0) { - Console.WriteLine(" No lump infos"); + builder.AppendLine(" No lump infos"); } else { for (int i = 0; i < LumpInfos.Length; i++) { var lumpInfo = LumpInfos[i]; - Console.WriteLine($" Lump Info {i}"); + builder.AppendLine($" Lump Info {i}"); if (lumpInfo == null) { - Console.WriteLine(" Lump is compressed"); + builder.AppendLine(" Lump is compressed"); } else { - Console.WriteLine($" Name: {lumpInfo.Name ?? "[NULL]"}"); - Console.WriteLine($" Width: {lumpInfo.Width} (0x{lumpInfo.Width:X})"); - Console.WriteLine($" Height: {lumpInfo.Height} (0x{lumpInfo.Height:X})"); - Console.WriteLine($" Pixel offset: {lumpInfo.PixelOffset} (0x{lumpInfo.PixelOffset:X})"); + builder.AppendLine($" Name: {lumpInfo.Name ?? "[NULL]"}"); + builder.AppendLine($" Width: {lumpInfo.Width} (0x{lumpInfo.Width:X})"); + builder.AppendLine($" Height: {lumpInfo.Height} (0x{lumpInfo.Height:X})"); + builder.AppendLine($" Pixel offset: {lumpInfo.PixelOffset} (0x{lumpInfo.PixelOffset:X})"); // TODO: Print unknown data? // TODO: Print pixel data? - Console.WriteLine($" Palette size: {lumpInfo.PaletteSize} (0x{lumpInfo.PaletteSize:X})"); + builder.AppendLine($" Palette size: {lumpInfo.PaletteSize} (0x{lumpInfo.PaletteSize:X})"); // TODO: Print palette data? } } } - Console.WriteLine(); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/WrapperBase.cs b/BurnOutSharp.Wrappers/WrapperBase.cs index a875d877..d5a94188 100644 --- a/BurnOutSharp.Wrappers/WrapperBase.cs +++ b/BurnOutSharp.Wrappers/WrapperBase.cs @@ -283,9 +283,9 @@ namespace BurnOutSharp.Wrappers #region Printing /// - /// Pretty print the item information + /// Export the item information as pretty-printed text /// - public abstract void PrettyPrint(); + public abstract StringBuilder PrettyPrint(); #if NET6_0_OR_GREATER diff --git a/BurnOutSharp.Wrappers/XZP.cs b/BurnOutSharp.Wrappers/XZP.cs index 74d4b76d..6d0a0c92 100644 --- a/BurnOutSharp.Wrappers/XZP.cs +++ b/BurnOutSharp.Wrappers/XZP.cs @@ -1,6 +1,6 @@ -using System; using System.IO; using System.Linq; +using System.Text; namespace BurnOutSharp.Wrappers { @@ -151,148 +151,158 @@ namespace BurnOutSharp.Wrappers #region Printing /// - public override void PrettyPrint() + public override StringBuilder PrettyPrint() { - Console.WriteLine("XZP Information:"); - Console.WriteLine("-------------------------"); - Console.WriteLine(); + StringBuilder builder = new StringBuilder(); - PrintHeader(); - PrintDirectoryEntries(); - PrintPreloadDirectoryEntries(); - PrintPreloadDirectoryMappings(); - PrintDirectoryItems(); - PrintFooter(); + builder.AppendLine("XZP Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + PrintHeader(builder); + PrintDirectoryEntries(builder); + PrintPreloadDirectoryEntries(builder); + PrintPreloadDirectoryMappings(builder); + PrintDirectoryItems(builder); + PrintFooter(builder); + + return builder; } /// /// Print header information /// - private void PrintHeader() + /// StringBuilder to append information to + private void PrintHeader(StringBuilder builder) { - Console.WriteLine(" Header Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {Signature}"); - Console.WriteLine($" Version: {Version} (0x{Version:X})"); - Console.WriteLine($" Preload directory entry count: {PreloadDirectoryEntryCount} (0x{PreloadDirectoryEntryCount:X})"); - Console.WriteLine($" Directory entry count: {DirectoryEntryCount} (0x{DirectoryEntryCount:X})"); - Console.WriteLine($" Preload bytes: {PreloadBytes} (0x{PreloadBytes:X})"); - Console.WriteLine($" Header length: {HeaderLength} (0x{HeaderLength:X})"); - Console.WriteLine($" Directory item count: {DirectoryItemCount} (0x{DirectoryItemCount:X})"); - Console.WriteLine($" Directory item offset: {DirectoryItemOffset} (0x{DirectoryItemOffset:X})"); - Console.WriteLine($" Directory item length: {DirectoryItemLength} (0x{DirectoryItemLength:X})"); - Console.WriteLine(); + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" Signature: {Signature}"); + builder.AppendLine($" Version: {Version} (0x{Version:X})"); + builder.AppendLine($" Preload directory entry count: {PreloadDirectoryEntryCount} (0x{PreloadDirectoryEntryCount:X})"); + builder.AppendLine($" Directory entry count: {DirectoryEntryCount} (0x{DirectoryEntryCount:X})"); + builder.AppendLine($" Preload bytes: {PreloadBytes} (0x{PreloadBytes:X})"); + builder.AppendLine($" Header length: {HeaderLength} (0x{HeaderLength:X})"); + builder.AppendLine($" Directory item count: {DirectoryItemCount} (0x{DirectoryItemCount:X})"); + builder.AppendLine($" Directory item offset: {DirectoryItemOffset} (0x{DirectoryItemOffset:X})"); + builder.AppendLine($" Directory item length: {DirectoryItemLength} (0x{DirectoryItemLength:X})"); + builder.AppendLine(); } /// /// Print directory entries information /// - private void PrintDirectoryEntries() + /// StringBuilder to append information to + private void PrintDirectoryEntries(StringBuilder builder) { - Console.WriteLine(" Directory Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Entries Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryEntries == null || DirectoryEntries.Length == 0) { - Console.WriteLine(" No directory entries"); + builder.AppendLine(" No directory entries"); } else { for (int i = 0; i < DirectoryEntries.Length; i++) { var directoryEntry = DirectoryEntries[i]; - Console.WriteLine($" Directory Entry {i}"); - Console.WriteLine($" File name CRC: {directoryEntry.FileNameCRC} (0x{directoryEntry.FileNameCRC:X})"); - Console.WriteLine($" Entry length: {directoryEntry.EntryLength} (0x{directoryEntry.EntryLength:X})"); - Console.WriteLine($" Entry offset: {directoryEntry.EntryOffset} (0x{directoryEntry.EntryOffset:X})"); + builder.AppendLine($" Directory Entry {i}"); + builder.AppendLine($" File name CRC: {directoryEntry.FileNameCRC} (0x{directoryEntry.FileNameCRC:X})"); + builder.AppendLine($" Entry length: {directoryEntry.EntryLength} (0x{directoryEntry.EntryLength:X})"); + builder.AppendLine($" Entry offset: {directoryEntry.EntryOffset} (0x{directoryEntry.EntryOffset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print preload directory entries information /// - private void PrintPreloadDirectoryEntries() + /// StringBuilder to append information to + private void PrintPreloadDirectoryEntries(StringBuilder builder) { - Console.WriteLine(" Preload Directory Entries Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Preload Directory Entries Information:"); + builder.AppendLine(" -------------------------"); if (PreloadDirectoryEntries == null || PreloadDirectoryEntries.Length == 0) { - Console.WriteLine(" No preload directory entries"); + builder.AppendLine(" No preload directory entries"); } else { for (int i = 0; i < PreloadDirectoryEntries.Length; i++) { var preloadDirectoryEntry = PreloadDirectoryEntries[i]; - Console.WriteLine($" Directory Entry {i}"); - Console.WriteLine($" File name CRC: {preloadDirectoryEntry.FileNameCRC} (0x{preloadDirectoryEntry.FileNameCRC:X})"); - Console.WriteLine($" Entry length: {preloadDirectoryEntry.EntryLength} (0x{preloadDirectoryEntry.EntryLength:X})"); - Console.WriteLine($" Entry offset: {preloadDirectoryEntry.EntryOffset} (0x{preloadDirectoryEntry.EntryOffset:X})"); + builder.AppendLine($" Directory Entry {i}"); + builder.AppendLine($" File name CRC: {preloadDirectoryEntry.FileNameCRC} (0x{preloadDirectoryEntry.FileNameCRC:X})"); + builder.AppendLine($" Entry length: {preloadDirectoryEntry.EntryLength} (0x{preloadDirectoryEntry.EntryLength:X})"); + builder.AppendLine($" Entry offset: {preloadDirectoryEntry.EntryOffset} (0x{preloadDirectoryEntry.EntryOffset:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print preload directory mappings information /// - private void PrintPreloadDirectoryMappings() + /// StringBuilder to append information to + private void PrintPreloadDirectoryMappings(StringBuilder builder) { - Console.WriteLine(" Preload Directory Mappings Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Preload Directory Mappings Information:"); + builder.AppendLine(" -------------------------"); if (PreloadDirectoryMappings == null || PreloadDirectoryMappings.Length == 0) { - Console.WriteLine(" No preload directory mappings"); + builder.AppendLine(" No preload directory mappings"); } else { for (int i = 0; i < PreloadDirectoryMappings.Length; i++) { var preloadDirectoryMapping = PreloadDirectoryMappings[i]; - Console.WriteLine($" Directory Mapping {i}"); - Console.WriteLine($" Preload directory entry index: {preloadDirectoryMapping.PreloadDirectoryEntryIndex} (0x{preloadDirectoryMapping.PreloadDirectoryEntryIndex:X})"); + builder.AppendLine($" Directory Mapping {i}"); + builder.AppendLine($" Preload directory entry index: {preloadDirectoryMapping.PreloadDirectoryEntryIndex} (0x{preloadDirectoryMapping.PreloadDirectoryEntryIndex:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print directory items information /// - private void PrintDirectoryItems() + /// StringBuilder to append information to + private void PrintDirectoryItems(StringBuilder builder) { - Console.WriteLine(" Directory Items Information:"); - Console.WriteLine(" -------------------------"); + builder.AppendLine(" Directory Items Information:"); + builder.AppendLine(" -------------------------"); if (DirectoryItems == null || DirectoryItems.Length == 0) { - Console.WriteLine(" No directory items"); + builder.AppendLine(" No directory items"); } else { for (int i = 0; i < DirectoryItems.Length; i++) { var directoryItem = DirectoryItems[i]; - Console.WriteLine($" Directory Item {i}"); - Console.WriteLine($" File name CRC: {directoryItem.FileNameCRC} (0x{directoryItem.FileNameCRC:X})"); - Console.WriteLine($" Name offset: {directoryItem.NameOffset} (0x{directoryItem.NameOffset:X})"); - Console.WriteLine($" Name: {directoryItem.Name ?? "[NULL]"}"); - Console.WriteLine($" Time created: {directoryItem.TimeCreated} (0x{directoryItem.TimeCreated:X})"); + builder.AppendLine($" Directory Item {i}"); + builder.AppendLine($" File name CRC: {directoryItem.FileNameCRC} (0x{directoryItem.FileNameCRC:X})"); + builder.AppendLine($" Name offset: {directoryItem.NameOffset} (0x{directoryItem.NameOffset:X})"); + builder.AppendLine($" Name: {directoryItem.Name ?? "[NULL]"}"); + builder.AppendLine($" Time created: {directoryItem.TimeCreated} (0x{directoryItem.TimeCreated:X})"); } } - Console.WriteLine(); + builder.AppendLine(); } /// /// Print footer information /// - private void PrintFooter() + /// StringBuilder to append information to + private void PrintFooter(StringBuilder builder) { - Console.WriteLine(" Footer Information:"); - Console.WriteLine(" -------------------------"); - Console.WriteLine($" File length: {F_FileLength} (0x{F_FileLength:X})"); - Console.WriteLine($" Signature: {F_Signature}"); - Console.WriteLine(); + builder.AppendLine(" Footer Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine($" File length: {F_FileLength} (0x{F_FileLength:X})"); + builder.AppendLine($" Signature: {F_Signature}"); + builder.AppendLine(); } #if NET6_0_OR_GREATER diff --git a/Test/Printer.cs b/Test/Printer.cs index fd2a51ea..b2c2f7b5 100644 --- a/Test/Printer.cs +++ b/Test/Printer.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; using BurnOutSharp; using BurnOutSharp.Matching; using BurnOutSharp.Utilities; @@ -257,7 +258,10 @@ namespace Test #endif // If we don't have the JSON flag if (!json) - wrapper.PrettyPrint(); + { + StringBuilder builder = wrapper.PrettyPrint(); + Console.WriteLine(builder); + } } } }