diff --git a/BinaryObjectScanner.Utilities/FileTypes.cs b/BinaryObjectScanner.Utilities/FileTypes.cs index e1467753..47c70f41 100644 --- a/BinaryObjectScanner.Utilities/FileTypes.cs +++ b/BinaryObjectScanner.Utilities/FileTypes.cs @@ -388,7 +388,7 @@ namespace BinaryObjectScanner.Utilities #region BDPlusSVM - if (extension.Equals(value: "svm", StringComparison.OrdinalIgnoreCase)) + if (extension.Equals("svm", StringComparison.OrdinalIgnoreCase)) return SupportedFileType.BDPlusSVM; #endregion @@ -513,7 +513,7 @@ namespace BinaryObjectScanner.Utilities return SupportedFileType.N3DS; // CIA package -- Not currently supported - // else if (extension.Equals(value: "cia", StringComparison.OrdinalIgnoreCase)) + // else if (extension.Equals("cia", StringComparison.OrdinalIgnoreCase)) // return SupportedFileType.N3DS; #endregion diff --git a/BinaryObjectScanner.Wrappers/AACSMediaKeyBlock.cs b/BinaryObjectScanner.Wrappers/AACSMediaKeyBlock.cs index 09f28ffa..767914aa 100644 --- a/BinaryObjectScanner.Wrappers/AACSMediaKeyBlock.cs +++ b/BinaryObjectScanner.Wrappers/AACSMediaKeyBlock.cs @@ -142,6 +142,12 @@ namespace BinaryObjectScanner.Wrappers { var record = Records[i]; builder.AppendLine($" Record Entry {i}"); + if (record == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Record type: {record.RecordType} (0x{record.RecordType:X})"); builder.AppendLine($" Record length: {record.RecordLength} (0x{record.RecordLength:X})"); @@ -149,14 +155,17 @@ namespace BinaryObjectScanner.Wrappers { case SabreTools.Models.AACS.RecordType.EndOfMediaKeyBlock: var eomkb = record as SabreTools.Models.AACS.EndOfMediaKeyBlockRecord; - builder.AppendLine($" Signature data: {(eomkb.SignatureData == null ? "[NULL]" : BitConverter.ToString(eomkb.SignatureData).Replace('-', ' '))}"); + if (eomkb != null) + { + builder.AppendLine($" Signature data: {(eomkb.SignatureData == null ? "[NULL]" : BitConverter.ToString(eomkb.SignatureData).Replace('-', ' '))}"); + } break; case SabreTools.Models.AACS.RecordType.ExplicitSubsetDifference: var esd = record as SabreTools.Models.AACS.ExplicitSubsetDifferenceRecord; builder.AppendLine($" Subset Differences:"); builder.AppendLine(" -------------------------"); - if (esd.SubsetDifferences == null || esd.SubsetDifferences.Length == 0) + if (esd?.SubsetDifferences == null || esd.SubsetDifferences.Length == 0) { builder.AppendLine($" No subset differences"); } @@ -166,8 +175,15 @@ namespace BinaryObjectScanner.Wrappers { var sd = esd.SubsetDifferences[j]; builder.AppendLine($" Subset Difference {j}"); - builder.AppendLine($" Mask: {sd.Mask} (0x{sd.Mask:X})"); - builder.AppendLine($" Number: {sd.Number} (0x{sd.Number:X})"); + if (sd == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Mask: {sd.Mask} (0x{sd.Mask:X})"); + builder.AppendLine($" Number: {sd.Number} (0x{sd.Number:X})"); + } } } break; @@ -176,7 +192,7 @@ namespace BinaryObjectScanner.Wrappers var mkd = record as SabreTools.Models.AACS.MediaKeyDataRecord; builder.AppendLine($" Media Keys:"); builder.AppendLine(" -------------------------"); - if (mkd.MediaKeyData == null || mkd.MediaKeyData.Length == 0) + if (mkd?.MediaKeyData == null || mkd.MediaKeyData.Length == 0) { builder.AppendLine($" No media keys"); } @@ -192,10 +208,11 @@ namespace BinaryObjectScanner.Wrappers case SabreTools.Models.AACS.RecordType.SubsetDifferenceIndex: var sdi = record as SabreTools.Models.AACS.SubsetDifferenceIndexRecord; - builder.AppendLine($" Span: {sdi.Span} (0x{sdi.Span:X})"); + if (sdi != null) + builder.AppendLine($" Span: {sdi.Span} (0x{sdi.Span:X})"); builder.AppendLine($" Offsets:"); builder.AppendLine(" -------------------------"); - if (sdi.Offsets == null || sdi.Offsets.Length == 0) + if (sdi?.Offsets == null || sdi.Offsets.Length == 0) { builder.AppendLine($" No offsets"); } @@ -211,16 +228,20 @@ namespace BinaryObjectScanner.Wrappers case SabreTools.Models.AACS.RecordType.TypeAndVersion: var tav = record as SabreTools.Models.AACS.TypeAndVersionRecord; - builder.AppendLine($" Media key block type: {tav.MediaKeyBlockType} (0x{tav.MediaKeyBlockType:X})"); - builder.AppendLine($" Version number: {tav.VersionNumber} (0x{tav.VersionNumber:X})"); + if (tav != null) + { + builder.AppendLine($" Media key block type: {tav.MediaKeyBlockType} (0x{tav.MediaKeyBlockType:X})"); + builder.AppendLine($" Version number: {tav.VersionNumber} (0x{tav.VersionNumber:X})"); + } break; case SabreTools.Models.AACS.RecordType.DriveRevocationList: var drl = record as SabreTools.Models.AACS.DriveRevocationListRecord; - builder.AppendLine($" Total number of entries: {drl.TotalNumberOfEntries} (0x{drl.TotalNumberOfEntries:X})"); + if (drl != null) + 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) + if (drl?.SignatureBlocks == null || drl.SignatureBlocks.Length == 0) { builder.AppendLine($" No signature blocks"); } @@ -230,21 +251,35 @@ namespace BinaryObjectScanner.Wrappers { var block = drl.SignatureBlocks[j]; 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) + if (block == null) { - builder.AppendLine($" No entry fields"); + builder.AppendLine(" [NULL]"); } else { - for (int k = 0; k < block.EntryFields.Length; k++) + builder.AppendLine($" Number of entries: {block.NumberOfEntries}"); + builder.AppendLine($" Entry Fields:"); + builder.AppendLine(" -------------------------"); + if (block.EntryFields == null || block.EntryFields.Length == 0) { - var ef = block.EntryFields[k]; - builder.AppendLine($" Entry {k}"); - builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); - builder.AppendLine($" Drive ID: {(ef.DriveID == null ? "[NULL]" : BitConverter.ToString(ef.DriveID).Replace('-', ' '))}"); + builder.AppendLine($" No entry fields"); + } + else + { + for (int k = 0; k < block.EntryFields.Length; k++) + { + var ef = block.EntryFields[k]; + builder.AppendLine($" Entry {k}"); + if (ef == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); + builder.AppendLine($" Drive ID: {(ef.DriveID == null ? "[NULL]" : BitConverter.ToString(ef.DriveID).Replace('-', ' '))}"); + } + } } } } @@ -253,10 +288,11 @@ namespace BinaryObjectScanner.Wrappers case SabreTools.Models.AACS.RecordType.HostRevocationList: var hrl = record as SabreTools.Models.AACS.HostRevocationListRecord; - builder.AppendLine($" Total number of entries: {hrl.TotalNumberOfEntries} (0x{hrl.TotalNumberOfEntries:X})"); + if (hrl != null) + 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) + if (hrl?.SignatureBlocks == null || hrl.SignatureBlocks.Length == 0) { builder.AppendLine($" No signature blocks"); } @@ -264,23 +300,38 @@ namespace BinaryObjectScanner.Wrappers { for (int j = 0; j < hrl.SignatureBlocks.Length; j++) { - var block = hrl.SignatureBlocks[j]; 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) + var block = hrl.SignatureBlocks[j]; + if (block == null) { - builder.AppendLine($" No entry fields"); + builder.AppendLine(" [NULL]"); } else { - for (int k = 0; k < block.EntryFields.Length; k++) + builder.AppendLine($" Number of entries: {block.NumberOfEntries}"); + builder.AppendLine($" Entry Fields:"); + builder.AppendLine(" -------------------------"); + if (block.EntryFields == null || block.EntryFields.Length == 0) { - var ef = block.EntryFields[k]; - builder.AppendLine($" Entry {k}"); - builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); - builder.AppendLine($" Host ID: {(ef.HostID == null ? "[NULL]" : BitConverter.ToString(ef.HostID).Replace('-', ' '))}"); + builder.AppendLine($" No entry fields"); + } + else + { + for (int k = 0; k < block.EntryFields.Length; k++) + { + var ef = block.EntryFields[k]; + builder.AppendLine($" Entry {k}"); + if (ef == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + + builder.AppendLine($" Range: {ef.Range} (0x{ef.Range:X})"); + builder.AppendLine($" Host ID: {(ef.HostID == null ? "[NULL]" : BitConverter.ToString(ef.HostID).Replace('-', ' '))}"); + } + } } } } @@ -289,12 +340,14 @@ namespace BinaryObjectScanner.Wrappers case SabreTools.Models.AACS.RecordType.VerifyMediaKey: var vmk = record as SabreTools.Models.AACS.VerifyMediaKeyRecord; - builder.AppendLine($" Ciphertext value: {(vmk.CiphertextValue == null ? "[NULL]" : BitConverter.ToString(vmk.CiphertextValue).Replace('-', ' '))}"); + if (vmk != null) + builder.AppendLine($" Ciphertext value: {(vmk.CiphertextValue == null ? "[NULL]" : BitConverter.ToString(vmk.CiphertextValue).Replace('-', ' '))}"); break; case SabreTools.Models.AACS.RecordType.Copyright: var c = record as SabreTools.Models.AACS.CopyrightRecord; - builder.AppendLine($" Copyright: {c.Copyright ?? "[NULL]"}"); + if (c != null) + builder.AppendLine($" Copyright: {c.Copyright ?? "[NULL]"}"); break; } } diff --git a/BinaryObjectScanner.Wrappers/BFPK.cs b/BinaryObjectScanner.Wrappers/BFPK.cs index 47badd86..88747b43 100644 --- a/BinaryObjectScanner.Wrappers/BFPK.cs +++ b/BinaryObjectScanner.Wrappers/BFPK.cs @@ -22,14 +22,22 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Magic => _model.Header.Magic; #else - public string? Magic => _model.Header.Magic; + public string? Magic => _model.Header?.Magic; #endif /// +#if NET48 public int Version => _model.Header.Version; +#else + public int? Version => _model.Header?.Version; +#endif /// +#if NET48 public int Files => _model.Header.Files; +#else + public int? Files => _model.Header?.Files; +#endif #endregion @@ -271,11 +279,19 @@ namespace BinaryObjectScanner.Wrappers { var entry = FileTable[i]; 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})"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + else + { + 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})"); + } } } builder.AppendLine(); diff --git a/BinaryObjectScanner.Wrappers/BSP.cs b/BinaryObjectScanner.Wrappers/BSP.cs index 307a2151..7245928f 100644 --- a/BinaryObjectScanner.Wrappers/BSP.cs +++ b/BinaryObjectScanner.Wrappers/BSP.cs @@ -20,7 +20,11 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint Version => _model.Header.Version; +#else + public uint? Version => _model.Header?.Version; +#endif #endregion @@ -38,13 +42,17 @@ namespace BinaryObjectScanner.Wrappers #region Texture Header /// +#if NET48 public uint TextureCount => _model.TextureHeader.TextureCount; +#else + public uint? TextureCount => _model.TextureHeader?.TextureCount; +#endif /// #if NET48 public uint[] Offsets => _model.TextureHeader.Offsets; #else - public uint[]? Offsets => _model.TextureHeader.Offsets; + public uint[]? Offsets => _model.TextureHeader?.Offsets; #endif #endregion @@ -202,8 +210,15 @@ namespace BinaryObjectScanner.Wrappers } builder.AppendLine($" Lump {i}{specialLumpName}"); - builder.AppendLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); - builder.AppendLine($" Length: {lump.Length} (0x{lump.Length:X})"); + if (lump == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Offset: {lump.Offset} (0x{lump.Offset:X})"); + builder.AppendLine($" Length: {lump.Length} (0x{lump.Length:X})"); + } } } builder.AppendLine(); @@ -219,9 +234,16 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine(" -------------------------"); builder.AppendLine($" Texture count: {TextureCount}"); builder.AppendLine($" Offsets:"); - for (int i = 0; i < Offsets.Length; i++) + if (Offsets == null || Offsets.Length == 0) { - builder.AppendLine($" Offset {i}: {Offsets[i]} (0x{Offsets[i]:X})"); + builder.AppendLine(" No offsets"); + } + else + { + for (int i = 0; i < Offsets.Length; i++) + { + builder.AppendLine($" Offset {i}: {Offsets[i]} (0x{Offsets[i]:X})"); + } } builder.AppendLine(); } @@ -244,17 +266,31 @@ namespace BinaryObjectScanner.Wrappers { var texture = Textures[i]; 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++) + if (texture == null) { - builder.AppendLine($" Offset {j}: {Offsets[i]} (0x{texture.Offsets[j]:X})"); + builder.AppendLine(" [NULL]"); + } + else + { + 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:"); + if (texture.Offsets == null || texture.Offsets.Length == 0) + { + builder.AppendLine($" No offsets"); + } + else + { + for (int j = 0; j < texture.Offsets.Length; j++) + { + builder.AppendLine($" Offset {j}: {texture.Offsets[i]} (0x{texture.Offsets[j]:X})"); + } + } + // Skip texture data + builder.AppendLine($" Palette size: {texture.PaletteSize} (0x{texture.PaletteSize:X})"); + // Skip palette data } - // Skip texture data - builder.AppendLine($" Palette size: {texture.PaletteSize} (0x{texture.PaletteSize:X})"); - // Skip palette data } } builder.AppendLine(); @@ -457,6 +493,10 @@ namespace BinaryObjectScanner.Wrappers private static byte[]? CreateTextureData(SabreTools.Models.BSP.Texture texture) #endif { + // If there's no palette data + if (texture.PaletteData == null || texture.PaletteData.Length == 0) + return null; + // If there's no texture data if (texture.TextureData == null || texture.TextureData.Length == 0) return null; diff --git a/BinaryObjectScanner.Wrappers/CFB.cs b/BinaryObjectScanner.Wrappers/CFB.cs index 048f6bab..38a5a0ae 100644 --- a/BinaryObjectScanner.Wrappers/CFB.cs +++ b/BinaryObjectScanner.Wrappers/CFB.cs @@ -19,65 +19,129 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public ulong Signature => _model.Header.Signature; +#else + public ulong? Signature => _model.Header?.Signature; +#endif /// +#if NET48 public Guid CLSID => _model.Header.CLSID; +#else + public Guid? CLSID => _model.Header?.CLSID; +#endif /// +#if NET48 public ushort MinorVersion => _model.Header.MinorVersion; +#else + public ushort? MinorVersion => _model.Header?.MinorVersion; +#endif /// +#if NET48 public ushort MajorVersion => _model.Header.MajorVersion; +#else + public ushort? MajorVersion => _model.Header?.MajorVersion; +#endif /// +#if NET48 public ushort ByteOrder => _model.Header.ByteOrder; +#else + public ushort? ByteOrder => _model.Header?.ByteOrder; +#endif /// +#if NET48 public ushort SectorShift => _model.Header.SectorShift; +#else + public ushort? SectorShift => _model.Header?.SectorShift; +#endif /// +#if NET48 public ushort MiniSectorShift => _model.Header.MiniSectorShift; +#else + public ushort? MiniSectorShift => _model.Header?.MiniSectorShift; +#endif /// #if NET48 public byte[] Reserved => _model.Header.Reserved; #else - public byte[]? Reserved => _model.Header.Reserved; + public byte[]? Reserved => _model.Header?.Reserved; #endif /// +#if NET48 public uint NumberOfDirectorySectors => _model.Header.NumberOfDirectorySectors; +#else + public uint? NumberOfDirectorySectors => _model.Header?.NumberOfDirectorySectors; +#endif /// +#if NET48 public uint NumberOfFATSectors => _model.Header.NumberOfFATSectors; +#else + public uint? NumberOfFATSectors => _model.Header?.NumberOfFATSectors; +#endif /// +#if NET48 public uint FirstDirectorySectorLocation => _model.Header.FirstDirectorySectorLocation; +#else + public uint? FirstDirectorySectorLocation => _model.Header?.FirstDirectorySectorLocation; +#endif /// +#if NET48 public uint TransactionSignatureNumber => _model.Header.TransactionSignatureNumber; +#else + public uint? TransactionSignatureNumber => _model.Header?.TransactionSignatureNumber; +#endif /// +#if NET48 public uint MiniStreamCutoffSize => _model.Header.MiniStreamCutoffSize; +#else + public uint? MiniStreamCutoffSize => _model.Header?.MiniStreamCutoffSize; +#endif /// +#if NET48 public uint FirstMiniFATSectorLocation => _model.Header.FirstMiniFATSectorLocation; +#else + public uint? FirstMiniFATSectorLocation => _model.Header?.FirstMiniFATSectorLocation; +#endif /// +#if NET48 public uint NumberOfMiniFATSectors => _model.Header.NumberOfMiniFATSectors; +#else + public uint? NumberOfMiniFATSectors => _model.Header?.NumberOfMiniFATSectors; +#endif /// +#if NET48 public uint FirstDIFATSectorLocation => _model.Header.FirstDIFATSectorLocation; +#else + public uint? FirstDIFATSectorLocation => _model.Header?.FirstDIFATSectorLocation; +#endif /// +#if NET48 public uint NumberOfDIFATSectors => _model.Header.NumberOfDIFATSectors; +#else + public uint? NumberOfDIFATSectors => _model.Header?.NumberOfDIFATSectors; +#endif /// #if NET48 public SabreTools.Models.CFB.SectorNumber[] DIFAT => _model.Header.DIFAT; #else - public SabreTools.Models.CFB.SectorNumber?[]? DIFAT => _model.Header.DIFAT; + public SabreTools.Models.CFB.SectorNumber?[]? DIFAT => _model.Header?.DIFAT; #endif #endregion @@ -133,12 +197,20 @@ namespace BinaryObjectScanner.Wrappers /// /// Normal sector size in bytes /// +#if NET48 public long SectorSize => (long)Math.Pow(2, SectorShift); +#else + public long SectorSize => (long)Math.Pow(2, SectorShift ?? 0); +#endif /// /// Mini sector size in bytes /// +#if NET48 public long MiniSectorSize => (long)Math.Pow(2, MiniSectorShift); +#else + public long MiniSectorSize => (long)Math.Pow(2, MiniSectorShift ?? 0); +#endif #endregion @@ -236,7 +308,7 @@ namespace BinaryObjectScanner.Wrappers #endif { // If we have an invalid sector - if (startingSector < 0 || (long)startingSector >= FATSectorNumbers.Length) + if (startingSector < 0 || FATSectorNumbers == null || (long)startingSector >= FATSectorNumbers.Length) return null; // Setup the returned list @@ -340,15 +412,15 @@ namespace BinaryObjectScanner.Wrappers #endif { // If we have an invalid sector - if (startingSector < 0 || (long)startingSector >= MiniFATSectorNumbers.Length) + if (startingSector < 0 || MiniFATSectorNumbers == null || (long)startingSector >= MiniFATSectorNumbers.Length) return null; // Setup the returned list - #if NET48 +#if NET48 var sectors = new List { startingSector }; - #else +#else var sectors = new List { startingSector }; - #endif +#endif var lastSector = startingSector; while (true) @@ -476,9 +548,16 @@ namespace BinaryObjectScanner.Wrappers 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++) + if (DIFAT == null || DIFAT.Length == 0) { - builder.AppendLine($" DIFAT Entry {i}: {DIFAT[i]} (0x{DIFAT[i]:X})"); + builder.AppendLine(" No DIFAT entries"); + } + else + { + for (int i = 0; i < DIFAT.Length; i++) + { + builder.AppendLine($" DIFAT Entry {i}: {DIFAT[i]} (0x{DIFAT[i]:X})"); + } } builder.AppendLine(); } @@ -567,19 +646,26 @@ namespace BinaryObjectScanner.Wrappers { var directoryEntry = DirectoryEntries[i]; 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})"); + if (directoryEntry == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); + } } } builder.AppendLine(); diff --git a/BinaryObjectScanner.Wrappers/CIA.cs b/BinaryObjectScanner.Wrappers/CIA.cs index f944f5b0..4457735c 100644 --- a/BinaryObjectScanner.Wrappers/CIA.cs +++ b/BinaryObjectScanner.Wrappers/CIA.cs @@ -18,34 +18,66 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint HeaderSize => _model.Header.HeaderSize; +#else + public uint? HeaderSize => _model.Header?.HeaderSize; +#endif /// +#if NET48 public ushort Type => _model.Header.Type; +#else + public ushort? Type => _model.Header?.Type; +#endif /// +#if NET48 public ushort Version => _model.Header.Version; +#else + public ushort? Version => _model.Header?.Version; +#endif /// +#if NET48 public uint CertificateChainSize => _model.Header.CertificateChainSize; +#else + public uint? CertificateChainSize => _model.Header?.CertificateChainSize; +#endif /// +#if NET48 public uint TicketSize => _model.Header.TicketSize; +#else + public uint? TicketSize => _model.Header?.TicketSize; +#endif /// +#if NET48 public uint TMDFileSize => _model.Header.TMDFileSize; +#else + public uint? TMDFileSize => _model.Header?.TMDFileSize; +#endif /// +#if NET48 public uint MetaSize => _model.Header.MetaSize; +#else + public uint? MetaSize => _model.Header?.MetaSize; +#endif /// +#if NET48 public ulong ContentSize => _model.Header.ContentSize; +#else + public ulong? ContentSize => _model.Header?.ContentSize; +#endif /// #if NET48 public byte[] ContentIndex => _model.Header.ContentIndex; #else - public byte[]? ContentIndex => _model.Header.ContentIndex; + public byte[]? ContentIndex => _model.Header?.ContentIndex; #endif #endregion @@ -64,138 +96,206 @@ namespace BinaryObjectScanner.Wrappers #region Ticket /// +#if NET48 public SabreTools.Models.N3DS.SignatureType T_SignatureType => _model.Ticket.SignatureType; +#else + public SabreTools.Models.N3DS.SignatureType? T_SignatureType => _model.Ticket?.SignatureType; +#endif /// +#if NET48 public ushort T_SignatureSize => _model.Ticket.SignatureSize; +#else + public ushort? T_SignatureSize => _model.Ticket?.SignatureSize; +#endif /// +#if NET48 public byte T_PaddingSize => _model.Ticket.PaddingSize; +#else + public byte? T_PaddingSize => _model.Ticket?.PaddingSize; +#endif /// #if NET48 public byte[] T_Signature => _model.Ticket.Signature; #else - public byte[]? T_Signature => _model.Ticket.Signature; + public byte[]? T_Signature => _model.Ticket?.Signature; #endif /// #if NET48 public byte[] T_Padding => _model.Ticket.Padding; #else - public byte[]? T_Padding => _model.Ticket.Padding; + public byte[]? T_Padding => _model.Ticket?.Padding; #endif /// #if NET48 public string T_Issuer => _model.Ticket.Issuer; #else - public string? T_Issuer => _model.Ticket.Issuer; + public string? T_Issuer => _model.Ticket?.Issuer; #endif /// #if NET48 public byte[] T_ECCPublicKey => _model.Ticket.ECCPublicKey; #else - public byte[]? T_ECCPublicKey => _model.Ticket.ECCPublicKey; + public byte[]? T_ECCPublicKey => _model.Ticket?.ECCPublicKey; #endif /// +#if NET48 public byte T_Version => _model.Ticket.Version; +#else + public byte? T_Version => _model.Ticket?.Version; +#endif /// +#if NET48 public byte T_CaCrlVersion => _model.Ticket.CaCrlVersion; +#else + public byte? T_CaCrlVersion => _model.Ticket?.CaCrlVersion; +#endif /// +#if NET48 public byte T_SignerCrlVersion => _model.Ticket.SignerCrlVersion; +#else + public byte? T_SignerCrlVersion => _model.Ticket?.SignerCrlVersion; +#endif /// #if NET48 public byte[] T_TitleKey => _model.Ticket.TitleKey; #else - public byte[]? T_TitleKey => _model.Ticket.TitleKey; + public byte[]? T_TitleKey => _model.Ticket?.TitleKey; #endif /// +#if NET48 public byte T_Reserved1 => _model.Ticket.Reserved1; +#else + public byte? T_Reserved1 => _model.Ticket?.Reserved1; +#endif /// +#if NET48 public ulong T_TicketID => _model.Ticket.TicketID; +#else + public ulong? T_TicketID => _model.Ticket?.TicketID; +#endif /// +#if NET48 public uint T_ConsoleID => _model.Ticket.ConsoleID; +#else + public uint? T_ConsoleID => _model.Ticket?.ConsoleID; +#endif /// +#if NET48 public ulong T_TitleID => _model.Ticket.TitleID; +#else + public ulong? T_TitleID => _model.Ticket?.TitleID; +#endif /// #if NET48 public byte[] T_Reserved2 => _model.Ticket.Reserved2; #else - public byte[]? T_Reserved2 => _model.Ticket.Reserved2; + public byte[]? T_Reserved2 => _model.Ticket?.Reserved2; #endif /// +#if NET48 public ushort T_TicketTitleVersion => _model.Ticket.TicketTitleVersion; +#else + public ushort? T_TicketTitleVersion => _model.Ticket?.TicketTitleVersion; +#endif /// #if NET48 public byte[] T_Reserved3 => _model.Ticket.Reserved3; #else - public byte[]? T_Reserved3 => _model.Ticket.Reserved3; + public byte[]? T_Reserved3 => _model.Ticket?.Reserved3; #endif /// +#if NET48 public byte T_LicenseType => _model.Ticket.LicenseType; +#else + public byte? T_LicenseType => _model.Ticket?.LicenseType; +#endif /// +#if NET48 public byte T_CommonKeyYIndex => _model.Ticket.CommonKeyYIndex; +#else + public byte? T_CommonKeyYIndex => _model.Ticket?.CommonKeyYIndex; +#endif /// #if NET48 public byte[] T_Reserved4 => _model.Ticket.Reserved4; #else - public byte[]? T_Reserved4 => _model.Ticket.Reserved4; + public byte[]? T_Reserved4 => _model.Ticket?.Reserved4; #endif /// +#if NET48 public uint T_eShopAccountID => _model.Ticket.eShopAccountID; +#else + public uint? T_eShopAccountID => _model.Ticket?.eShopAccountID; +#endif /// +#if NET48 public byte T_Reserved5 => _model.Ticket.Reserved5; +#else + public byte? T_Reserved5 => _model.Ticket?.Reserved5; +#endif /// +#if NET48 public byte T_Audit => _model.Ticket.Audit; +#else + public byte? T_Audit => _model.Ticket?.Audit; +#endif /// #if NET48 public byte[] T_Reserved6 => _model.Ticket.Reserved6; #else - public byte[]? T_Reserved6 => _model.Ticket.Reserved6; + public byte[]? T_Reserved6 => _model.Ticket?.Reserved6; #endif /// #if NET48 public uint[] T_Limits => _model.Ticket.Limits; #else - public uint[]? T_Limits => _model.Ticket.Limits; + public uint[]? T_Limits => _model.Ticket?.Limits; #endif /// +#if NET48 public uint T_ContentIndexSize => _model.Ticket.ContentIndexSize; +#else + public uint? T_ContentIndexSize => _model.Ticket?.ContentIndexSize; +#endif /// #if NET48 public byte[] T_ContentIndex => _model.Ticket.ContentIndex; #else - public byte[]? T_ContentIndex => _model.Ticket.ContentIndex; + public byte[]? T_ContentIndex => _model.Ticket?.ContentIndex; #endif /// #if NET48 public SabreTools.Models.N3DS.Certificate[] T_CertificateChain => _model.Ticket.CertificateChain; #else - public SabreTools.Models.N3DS.Certificate?[]? T_CertificateChain => _model.Ticket.CertificateChain; + public SabreTools.Models.N3DS.Certificate?[]? T_CertificateChain => _model.Ticket?.CertificateChain; #endif #endregion @@ -203,127 +303,199 @@ namespace BinaryObjectScanner.Wrappers #region Title Metadata /// +#if NET48 public SabreTools.Models.N3DS.SignatureType TMD_SignatureType => _model.TMDFileData.SignatureType; +#else + public SabreTools.Models.N3DS.SignatureType? TMD_SignatureType => _model.TMDFileData?.SignatureType; +#endif /// +#if NET48 public ushort TMD_SignatureSize => _model.TMDFileData.SignatureSize; +#else + public ushort? TMD_SignatureSize => _model.TMDFileData?.SignatureSize; +#endif /// +#if NET48 public byte TMD_PaddingSize => _model.TMDFileData.PaddingSize; +#else + public byte? TMD_PaddingSize => _model.TMDFileData?.PaddingSize; +#endif /// #if NET48 public byte[] TMD_Signature => _model.TMDFileData.Signature; #else - public byte[]? TMD_Signature => _model.TMDFileData.Signature; + public byte[]? TMD_Signature => _model.TMDFileData?.Signature; #endif /// #if NET48 public byte[] TMD_Padding1 => _model.TMDFileData.Padding1; #else - public byte[]? TMD_Padding1 => _model.TMDFileData.Padding1; + public byte[]? TMD_Padding1 => _model.TMDFileData?.Padding1; #endif /// #if NET48 public string TMD_Issuer => _model.TMDFileData.Issuer; #else - public string? TMD_Issuer => _model.TMDFileData.Issuer; + public string? TMD_Issuer => _model.TMDFileData?.Issuer; #endif /// +#if NET48 public byte TMD_Version => _model.TMDFileData.Version; +#else + public byte? TMD_Version => _model.TMDFileData?.Version; +#endif /// +#if NET48 public byte TMD_CaCrlVersion => _model.TMDFileData.CaCrlVersion; +#else + public byte? TMD_CaCrlVersion => _model.TMDFileData?.CaCrlVersion; +#endif /// +#if NET48 public byte TMD_SignerCrlVersion => _model.TMDFileData.SignerCrlVersion; +#else + public byte? TMD_SignerCrlVersion => _model.TMDFileData?.SignerCrlVersion; +#endif /// +#if NET48 public byte TMD_Reserved1 => _model.TMDFileData.Reserved1; +#else + public byte? TMD_Reserved1 => _model.TMDFileData?.Reserved1; +#endif /// +#if NET48 public ulong TMD_SystemVersion => _model.TMDFileData.SystemVersion; +#else + public ulong? TMD_SystemVersion => _model.TMDFileData?.SystemVersion; +#endif /// +#if NET48 public ulong TMD_TitleID => _model.TMDFileData.TitleID; +#else + public ulong? TMD_TitleID => _model.TMDFileData?.TitleID; +#endif /// +#if NET48 public uint TMD_TitleType => _model.TMDFileData.TitleType; +#else + public uint? TMD_TitleType => _model.TMDFileData?.TitleType; +#endif /// +#if NET48 public ushort TMD_GroupID => _model.TMDFileData.GroupID; +#else + public ushort? TMD_GroupID => _model.TMDFileData?.GroupID; +#endif /// +#if NET48 public uint TMD_SaveDataSize => _model.TMDFileData.SaveDataSize; +#else + public uint? TMD_SaveDataSize => _model.TMDFileData?.SaveDataSize; +#endif /// +#if NET48 public uint TMD_SRLPrivateSaveDataSize => _model.TMDFileData.SRLPrivateSaveDataSize; +#else + public uint? TMD_SRLPrivateSaveDataSize => _model.TMDFileData?.SRLPrivateSaveDataSize; +#endif /// #if NET48 public byte[] TMD_Reserved2 => _model.TMDFileData.Reserved2; #else - public byte[]? TMD_Reserved2 => _model.TMDFileData.Reserved2; + public byte[]? TMD_Reserved2 => _model.TMDFileData?.Reserved2; #endif /// +#if NET48 public byte TMD_SRLFlag => _model.TMDFileData.SRLFlag; +#else + public byte? TMD_SRLFlag => _model.TMDFileData?.SRLFlag; +#endif /// #if NET48 public byte[] TMD_Reserved3 => _model.TMDFileData.Reserved3; #else - public byte[]? TMD_Reserved3 => _model.TMDFileData.Reserved3; + public byte[]? TMD_Reserved3 => _model.TMDFileData?.Reserved3; #endif /// +#if NET48 public uint TMD_AccessRights => _model.TMDFileData.AccessRights; +#else + public uint? TMD_AccessRights => _model.TMDFileData?.AccessRights; +#endif /// +#if NET48 public ushort TMD_TitleVersion => _model.TMDFileData.TitleVersion; +#else + public ushort? TMD_TitleVersion => _model.TMDFileData?.TitleVersion; +#endif /// +#if NET48 public ushort TMD_ContentCount => _model.TMDFileData.ContentCount; +#else + public ushort? TMD_ContentCount => _model.TMDFileData?.ContentCount; +#endif /// +#if NET48 public ushort TMD_BootContent => _model.TMDFileData.BootContent; +#else + public ushort? TMD_BootContent => _model.TMDFileData?.BootContent; +#endif /// #if NET48 public byte[] TMD_Padding2 => _model.TMDFileData.Padding2; #else - public byte[]? TMD_Padding2 => _model.TMDFileData.Padding2; + public byte[]? TMD_Padding2 => _model.TMDFileData?.Padding2; #endif /// #if NET48 public byte[] TMD_SHA256HashContentInfoRecords => _model.TMDFileData.SHA256HashContentInfoRecords; #else - public byte[]? TMD_SHA256HashContentInfoRecords => _model.TMDFileData.SHA256HashContentInfoRecords; + public byte[]? TMD_SHA256HashContentInfoRecords => _model.TMDFileData?.SHA256HashContentInfoRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.ContentInfoRecord[] TMD_ContentInfoRecords => _model.TMDFileData.ContentInfoRecords; #else - public SabreTools.Models.N3DS.ContentInfoRecord?[]? TMD_ContentInfoRecords => _model.TMDFileData.ContentInfoRecords; + public SabreTools.Models.N3DS.ContentInfoRecord?[]? TMD_ContentInfoRecords => _model.TMDFileData?.ContentInfoRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.ContentChunkRecord[] TMD_ContentChunkRecords => _model.TMDFileData.ContentChunkRecords; #else - public SabreTools.Models.N3DS.ContentChunkRecord?[]? TMD_ContentChunkRecords => _model.TMDFileData.ContentChunkRecords; + public SabreTools.Models.N3DS.ContentChunkRecord?[]? TMD_ContentChunkRecords => _model.TMDFileData?.ContentChunkRecords; #endif /// #if NET48 public SabreTools.Models.N3DS.Certificate[] TMD_CertificateChain => _model.TMDFileData.CertificateChain; #else - public SabreTools.Models.N3DS.Certificate?[]? TMD_CertificateChain => _model.TMDFileData.CertificateChain; + public SabreTools.Models.N3DS.Certificate?[]? TMD_CertificateChain => _model.TMDFileData?.CertificateChain; #endif #endregion @@ -524,6 +696,12 @@ namespace BinaryObjectScanner.Wrappers } builder.AppendLine($" Certificate {i}{certificateName}"); + if (certificate == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -585,9 +763,16 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Audit: {T_Audit} (0x{T_Audit:X})"); builder.AppendLine($" Reserved 6: {(T_Reserved6 == null ? "[NULL]" : BitConverter.ToString(T_Reserved6).Replace('-', ' '))}"); builder.AppendLine($" Limits:"); - for (int i = 0; i < T_Limits.Length; i++) + if (T_Limits == null || T_Limits.Length == 0) { - builder.AppendLine($" Limit {i}: {T_Limits[i]} (0x{T_Limits[i]:X})"); + builder.AppendLine(" No limits"); + } + else + { + for (int i = 0; i < T_Limits.Length; i++) + { + builder.AppendLine($" Limit {i}: {T_Limits[i]} (0x{T_Limits[i]:X})"); + } } builder.AppendLine($" Content index size: {T_ContentIndexSize} (0x{T_ContentIndexSize:X})"); builder.AppendLine($" Content index: {(T_ContentIndex == null ? "[NULL]" : BitConverter.ToString(T_ContentIndex).Replace('-', ' '))}"); @@ -613,6 +798,12 @@ namespace BinaryObjectScanner.Wrappers } builder.AppendLine($" Certificate {i}{certificateName}"); + if (certificate == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -687,6 +878,12 @@ namespace BinaryObjectScanner.Wrappers { var contentInfoRecord = TMD_ContentInfoRecords[i]; builder.AppendLine($" Content Info Record {i}"); + if (contentInfoRecord == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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: {(contentInfoRecord.UnhashedContentRecordsSHA256Hash == null ? "[NULL]" : BitConverter.ToString(contentInfoRecord.UnhashedContentRecordsSHA256Hash).Replace('-', ' '))}"); @@ -706,6 +903,12 @@ namespace BinaryObjectScanner.Wrappers { var contentChunkRecord = TMD_ContentChunkRecords[i]; builder.AppendLine($" Content Chunk Record {i}"); + if (contentChunkRecord == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -735,6 +938,12 @@ namespace BinaryObjectScanner.Wrappers } builder.AppendLine($" Certificate {i}{certificateName}"); + if (certificate == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -780,6 +989,12 @@ namespace BinaryObjectScanner.Wrappers { var partitionHeader = Partitions[i]; builder.AppendLine($" NCCH Partition Header {i}"); + if (partitionHeader == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + if (partitionHeader.MagicID == string.Empty) { builder.AppendLine($" Empty partition, no data can be parsed"); @@ -805,14 +1020,21 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); builder.AppendLine($" Reserved 2: {(partitionHeader.Reserved2 == null ? "[NULL]" : 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})"); + if (partitionHeader.Flags == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); @@ -843,11 +1065,11 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine(" -------------------------"); if (_model.MetaData == null || MetaSize == 0) { - builder.AppendLine(value: " No meta file data"); + builder.AppendLine(" No meta file data"); } else { - builder.AppendLine(value: $" Title ID dependency list: {(MD_TitleIDDependencyList == null ? "[NULL]" : BitConverter.ToString(MD_TitleIDDependencyList).Replace('-', ' '))}"); + builder.AppendLine($" Title ID dependency list: {(MD_TitleIDDependencyList == null ? "[NULL]" : BitConverter.ToString(MD_TitleIDDependencyList).Replace('-', ' '))}"); builder.AppendLine($" Reserved 1: {(MD_Reserved1 == null ? "[NULL]" : BitConverter.ToString(MD_Reserved1).Replace('-', ' '))}"); builder.AppendLine($" Core version: {MD_CoreVersion} (0x{MD_CoreVersion:X})"); builder.AppendLine($" Reserved 2: {(MD_Reserved2 == null ? "[NULL]" : BitConverter.ToString(MD_Reserved2).Replace('-', ' '))}"); diff --git a/BinaryObjectScanner.Wrappers/GCF.cs b/BinaryObjectScanner.Wrappers/GCF.cs index 908e0528..0f4aa636 100644 --- a/BinaryObjectScanner.Wrappers/GCF.cs +++ b/BinaryObjectScanner.Wrappers/GCF.cs @@ -19,65 +19,141 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint Dummy0 => _model.Header.Dummy0; +#else + public uint? Dummy0 => _model.Header?.Dummy0; +#endif /// +#if NET48 public uint MajorVersion => _model.Header.MajorVersion; +#else + public uint? MajorVersion => _model.Header?.MajorVersion; +#endif /// +#if NET48 public uint MinorVersion => _model.Header.MinorVersion; +#else + public uint? MinorVersion => _model.Header?.MinorVersion; +#endif /// +#if NET48 public uint CacheID => _model.Header.CacheID; +#else + public uint? CacheID => _model.Header?.CacheID; +#endif /// +#if NET48 public uint LastVersionPlayed => _model.Header.LastVersionPlayed; +#else + public uint? LastVersionPlayed => _model.Header?.LastVersionPlayed; +#endif /// +#if NET48 public uint Dummy1 => _model.Header.Dummy1; +#else + public uint? Dummy1 => _model.Header?.Dummy1; +#endif /// +#if NET48 public uint Dummy2 => _model.Header.Dummy2; +#else + public uint? Dummy2 => _model.Header?.Dummy2; +#endif /// +#if NET48 public uint FileSize => _model.Header.FileSize; +#else + public uint? FileSize => _model.Header?.FileSize; +#endif /// +#if NET48 public uint BlockSize => _model.Header.BlockSize; +#else + public uint? BlockSize => _model.Header?.BlockSize; +#endif /// +#if NET48 public uint BlockCount => _model.Header.BlockCount; +#else + public uint? BlockCount => _model.Header?.BlockCount; +#endif /// +#if NET48 public uint Dummy3 => _model.Header.Dummy3; +#else + public uint? Dummy3 => _model.Header?.Dummy3; +#endif #endregion #region Block Entry Header /// +#if NET48 public uint BEH_BlockCount => _model.BlockEntryHeader.BlockCount; +#else + public uint? BEH_BlockCount => _model.BlockEntryHeader?.BlockCount; +#endif /// +#if NET48 public uint BEH_BlocksUsed => _model.BlockEntryHeader.BlocksUsed; +#else + public uint? BEH_BlocksUsed => _model.BlockEntryHeader?.BlocksUsed; +#endif /// +#if NET48 public uint BEH_Dummy0 => _model.BlockEntryHeader.Dummy0; +#else + public uint? BEH_Dummy0 => _model.BlockEntryHeader?.Dummy0; +#endif /// +#if NET48 public uint BEH_Dummy1 => _model.BlockEntryHeader.Dummy1; +#else + public uint? BEH_Dummy1 => _model.BlockEntryHeader?.Dummy1; +#endif /// +#if NET48 public uint BEH_Dummy2 => _model.BlockEntryHeader.Dummy2; +#else + public uint? BEH_Dummy2 => _model.BlockEntryHeader?.Dummy2; +#endif /// +#if NET48 public uint BEH_Dummy3 => _model.BlockEntryHeader.Dummy3; +#else + public uint? BEH_Dummy3 => _model.BlockEntryHeader?.Dummy3; +#endif /// +#if NET48 public uint BEH_Dummy4 => _model.BlockEntryHeader.Dummy4; +#else + public uint? BEH_Dummy4 => _model.BlockEntryHeader?.Dummy4; +#endif /// +#if NET48 public uint BEH_Checksum => _model.BlockEntryHeader.Checksum; +#else + public uint? BEH_Checksum => _model.BlockEntryHeader?.Checksum; +#endif #endregion @@ -95,16 +171,32 @@ namespace BinaryObjectScanner.Wrappers #region Fragmentation Map Header /// +#if NET48 public uint FMH_BlockCount => _model.FragmentationMapHeader.BlockCount; +#else + public uint? FMH_BlockCount => _model.FragmentationMapHeader?.BlockCount; +#endif /// +#if NET48 public uint FMH_FirstUnusedEntry => _model.FragmentationMapHeader.FirstUnusedEntry; +#else + public uint? FMH_FirstUnusedEntry => _model.FragmentationMapHeader?.FirstUnusedEntry; +#endif /// +#if NET48 public uint FMH_Terminator => _model.FragmentationMapHeader.Terminator; +#else + public uint? FMH_Terminator => _model.FragmentationMapHeader?.Terminator; +#endif /// +#if NET48 public uint FMH_Checksum => _model.FragmentationMapHeader.Checksum; +#else + public uint? FMH_Checksum => _model.FragmentationMapHeader?.Checksum; +#endif #endregion @@ -152,46 +244,102 @@ namespace BinaryObjectScanner.Wrappers #region Directory Header /// +#if NET48 public uint DH_Dummy0 => _model.DirectoryHeader.Dummy0; +#else + public uint? DH_Dummy0 => _model.DirectoryHeader?.Dummy0; +#endif /// +#if NET48 public uint DH_CacheID => _model.DirectoryHeader.CacheID; +#else + public uint? DH_CacheID => _model.DirectoryHeader?.CacheID; +#endif /// +#if NET48 public uint DH_LastVersionPlayed => _model.DirectoryHeader.LastVersionPlayed; +#else + public uint? DH_LastVersionPlayed => _model.DirectoryHeader?.LastVersionPlayed; +#endif /// +#if NET48 public uint DH_ItemCount => _model.DirectoryHeader.ItemCount; +#else + public uint? DH_ItemCount => _model.DirectoryHeader?.ItemCount; +#endif /// +#if NET48 public uint DH_FileCount => _model.DirectoryHeader.FileCount; +#else + public uint? DH_FileCount => _model.DirectoryHeader?.FileCount; +#endif /// +#if NET48 public uint DH_Dummy1 => _model.DirectoryHeader.Dummy1; +#else + public uint? DH_Dummy1 => _model.DirectoryHeader?.Dummy1; +#endif /// +#if NET48 public uint DH_DirectorySize => _model.DirectoryHeader.DirectorySize; +#else + public uint? DH_DirectorySize => _model.DirectoryHeader?.DirectorySize; +#endif /// +#if NET48 public uint DH_NameSize => _model.DirectoryHeader.NameSize; +#else + public uint? DH_NameSize => _model.DirectoryHeader?.NameSize; +#endif /// +#if NET48 public uint DH_Info1Count => _model.DirectoryHeader.Info1Count; +#else + public uint? DH_Info1Count => _model.DirectoryHeader?.Info1Count; +#endif /// +#if NET48 public uint DH_CopyCount => _model.DirectoryHeader.CopyCount; +#else + public uint? DH_CopyCount => _model.DirectoryHeader?.CopyCount; +#endif /// +#if NET48 public uint DH_LocalCount => _model.DirectoryHeader.LocalCount; +#else + public uint? DH_LocalCount => _model.DirectoryHeader?.LocalCount; +#endif /// +#if NET48 public uint DH_Dummy2 => _model.DirectoryHeader.Dummy2; +#else + public uint? DH_Dummy2 => _model.DirectoryHeader?.Dummy2; +#endif /// +#if NET48 public uint DH_Dummy3 => _model.DirectoryHeader.Dummy3; +#else + public uint? DH_Dummy3 => _model.DirectoryHeader?.Dummy3; +#endif /// +#if NET48 public uint DH_Checksum => _model.DirectoryHeader.Checksum; +#else + public uint? DH_Checksum => _model.DirectoryHeader?.Checksum; +#endif #endregion @@ -285,26 +433,50 @@ namespace BinaryObjectScanner.Wrappers #region Checksum Header /// +#if NET48 public uint CH_Dummy0 => _model.ChecksumHeader.Dummy0; +#else + public uint? CH_Dummy0 => _model.ChecksumHeader?.Dummy0; +#endif /// +#if NET48 public uint CH_ChecksumSize => _model.ChecksumHeader.ChecksumSize; +#else + public uint? CH_ChecksumSize => _model.ChecksumHeader?.ChecksumSize; +#endif #endregion #region Checksum Map Header /// +#if NET48 public uint CMH_Dummy0 => _model.ChecksumMapHeader.Dummy0; +#else + public uint? CMH_Dummy0 => _model.ChecksumMapHeader?.Dummy0; +#endif /// +#if NET48 public uint CMH_Dummy1 => _model.ChecksumMapHeader.Dummy1; +#else + public uint? CMH_Dummy1 => _model.ChecksumMapHeader?.Dummy1; +#endif /// +#if NET48 public uint CMH_ItemCount => _model.ChecksumMapHeader.ItemCount; +#else + public uint? CMH_ItemCount => _model.ChecksumMapHeader?.ItemCount; +#endif /// +#if NET48 public uint CMH_ChecksumCount => _model.ChecksumMapHeader.ChecksumCount; +#else + public uint? CMH_ChecksumCount => _model.ChecksumMapHeader?.ChecksumCount; +#endif #endregion @@ -333,22 +505,46 @@ namespace BinaryObjectScanner.Wrappers #region Data Block Header /// +#if NET48 public uint DBH_LastVersionPlayed => _model.DataBlockHeader.LastVersionPlayed; +#else + public uint? DBH_LastVersionPlayed => _model.DataBlockHeader?.LastVersionPlayed; +#endif /// +#if NET48 public uint DBH_BlockCount => _model.DataBlockHeader.BlockCount; +#else + public uint? DBH_BlockCount => _model.DataBlockHeader?.BlockCount; +#endif /// +#if NET48 public uint DBH_BlockSize => _model.DataBlockHeader.BlockSize; +#else + public uint? DBH_BlockSize => _model.DataBlockHeader?.BlockSize; +#endif /// +#if NET48 public uint DBH_FirstBlockOffset => _model.DataBlockHeader.FirstBlockOffset; +#else + public uint? DBH_FirstBlockOffset => _model.DataBlockHeader?.FirstBlockOffset; +#endif /// +#if NET48 public uint DBH_BlocksUsed => _model.DataBlockHeader.BlocksUsed; +#else + public uint? DBH_BlocksUsed => _model.DataBlockHeader?.BlocksUsed; +#endif /// +#if NET48 public uint DBH_Checksum => _model.DataBlockHeader.Checksum; +#else + public uint? DBH_Checksum => _model.DataBlockHeader?.Checksum; +#endif #endregion @@ -359,7 +555,11 @@ namespace BinaryObjectScanner.Wrappers /// /// Set of all files and their information /// +#if NET48 public FileInfo[] Files +#else + public FileInfo[]? Files +#endif { get { @@ -367,6 +567,10 @@ namespace BinaryObjectScanner.Wrappers if (_files != null) return _files; + // If we don't have a required property + if (DirectoryEntries == null || DirectoryMapEntries == null || BlockEntries == null) + return null; + // Otherwise, scan and build the files var files = new List(); for (int i = 0; i < DirectoryEntries.Length; i++) @@ -374,6 +578,8 @@ namespace BinaryObjectScanner.Wrappers // Get the directory entry var directoryEntry = DirectoryEntries[i]; var directoryMapEntry = DirectoryMapEntries[i]; + if (directoryEntry == null || directoryMapEntry == null) + continue; // If we have a directory, skip for now if (!directoryEntry.DirectoryFlags.HasFlag(SabreTools.Models.GCF.HL_GCF_FLAG.HL_GCF_FLAG_FILE)) @@ -397,6 +603,9 @@ namespace BinaryObjectScanner.Wrappers while (index != 0xFFFFFFFF) { var parentDirectoryEntry = DirectoryEntries[index]; + if (parentDirectoryEntry == null) + break; + pathParts.Add(parentDirectoryEntry.Name ?? string.Empty); index = parentDirectoryEntry.ParentIndex; } @@ -406,6 +615,9 @@ namespace BinaryObjectScanner.Wrappers while (index != DBH_BlockCount) { var nextBlock = BlockEntries[index]; + if (nextBlock == null) + break; + blockEntries.Add(nextBlock); index = nextBlock.NextBlockEntryIndex; } @@ -430,7 +642,11 @@ namespace BinaryObjectScanner.Wrappers /// /// Set of all data block offsets /// +#if NET48 public long[] DataBlockOffsets +#else + public long[]? DataBlockOffsets +#endif { get { @@ -438,11 +654,25 @@ namespace BinaryObjectScanner.Wrappers if (_dataBlockOffsets != null) return _dataBlockOffsets; +#if NET6_0_OR_GREATER + // If we don't have a block count, offset, or size + if (DBH_BlockCount == null || DBH_FirstBlockOffset == null || DBH_BlockSize == null) + return null; +#endif + // Otherwise, build the data block set +#if NET48 _dataBlockOffsets = new long[DBH_BlockCount]; +#else + _dataBlockOffsets = new long[DBH_BlockCount.Value]; +#endif for (int i = 0; i < DBH_BlockCount; i++) { +#if NET48 long dataBlockOffset = DBH_FirstBlockOffset + (i * DBH_BlockSize); +#else + long dataBlockOffset = DBH_FirstBlockOffset.Value + (i * DBH_BlockSize.Value); +#endif _dataBlockOffsets[i] = dataBlockOffset; } @@ -458,12 +688,20 @@ namespace BinaryObjectScanner.Wrappers /// /// Set of all files and their information /// +#if NET48 private FileInfo[] _files = null; +#else + private FileInfo[]? _files = null; +#endif /// /// Set of all data block offsets /// +#if NET48 private long[] _dataBlockOffsets = null; +#else + private long[]? _dataBlockOffsets = null; +#endif #endregion @@ -655,6 +893,12 @@ namespace BinaryObjectScanner.Wrappers { var blockEntry = BlockEntries[i]; builder.AppendLine($" Block Entry {i}"); + if (blockEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -700,6 +944,12 @@ namespace BinaryObjectScanner.Wrappers { var fragmentationMap = FragmentationMaps[i]; builder.AppendLine($" Fragmentation Map {i}"); + if (fragmentationMap == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Next data block index: {fragmentationMap.NextDataBlockIndex} (0x{fragmentationMap.NextDataBlockIndex:X})"); } } @@ -747,6 +997,12 @@ namespace BinaryObjectScanner.Wrappers { var blockEntryMap = BlockEntryMaps[i]; builder.AppendLine($" Block Entry Map {i}"); + if (blockEntryMap == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Previous data block index: {blockEntryMap.PreviousBlockEntryIndex} (0x{blockEntryMap.PreviousBlockEntryIndex:X})"); builder.AppendLine($" Next data block index: {blockEntryMap.NextBlockEntryIndex} (0x{blockEntryMap.NextBlockEntryIndex:X})"); } @@ -797,6 +1053,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryEntry = DirectoryEntries[i]; builder.AppendLine($" Directory Entry {i}"); + if (directoryEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -828,6 +1090,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryInfoEntry = DirectoryInfo1Entries[i]; builder.AppendLine($" Directory Info 1 Entry {i}"); + if (directoryInfoEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } @@ -852,6 +1120,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryInfoEntry = DirectoryInfo2Entries[i]; builder.AppendLine($" Directory Info 2 Entry {i}"); + if (directoryInfoEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } @@ -865,7 +1139,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintDirectoryCopyEntries(StringBuilder builder) { builder.AppendLine(" Directory Copy Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (DirectoryCopyEntries == null || DirectoryCopyEntries.Length == 0) { builder.AppendLine(" No directory copy entries"); @@ -876,6 +1150,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryCopyEntry = DirectoryCopyEntries[i]; builder.AppendLine($" Directory Copy Entry {i}"); + if (directoryCopyEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); } } @@ -889,7 +1169,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintDirectoryLocalEntries(StringBuilder builder) { builder.AppendLine(" Directory Local Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (DirectoryLocalEntries == null || DirectoryLocalEntries.Length == 0) { builder.AppendLine(" No directory local entries"); @@ -900,6 +1180,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryLocalEntry = DirectoryLocalEntries[i]; builder.AppendLine($" Directory Local Entry {i}"); + if (directoryLocalEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); } } @@ -933,7 +1219,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintDirectoryMapEntries(StringBuilder builder) { builder.AppendLine(" Directory Map Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (DirectoryMapEntries == null || DirectoryMapEntries.Length == 0) { builder.AppendLine(" No directory map entries"); @@ -944,6 +1230,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryMapEntry = DirectoryMapEntries[i]; builder.AppendLine($" Directory Map Entry {i}"); + if (directoryMapEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" First block index: {directoryMapEntry.FirstBlockIndex} (0x{directoryMapEntry.FirstBlockIndex:X})"); } } @@ -985,7 +1277,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintChecksumMapEntries(StringBuilder builder) { builder.AppendLine(" Checksum Map Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (ChecksumMapEntries == null || ChecksumMapEntries.Length == 0) { builder.AppendLine(" No checksum map entries"); @@ -996,6 +1288,12 @@ namespace BinaryObjectScanner.Wrappers { var checksumMapEntry = ChecksumMapEntries[i]; builder.AppendLine($" Checksum Map Entry {i}"); + if (checksumMapEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); builder.AppendLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); } @@ -1010,7 +1308,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintChecksumEntries(StringBuilder builder) { builder.AppendLine(" Checksum Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (ChecksumEntries == null || ChecksumEntries.Length == 0) { builder.AppendLine(" No checksum entries"); @@ -1021,6 +1319,12 @@ namespace BinaryObjectScanner.Wrappers { var checksumEntry = ChecksumEntries[i]; builder.AppendLine($" Checksum Entry {i}"); + if (checksumEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); } } @@ -1085,7 +1389,7 @@ namespace BinaryObjectScanner.Wrappers public bool ExtractFile(int index, string outputDirectory) { // If we have no files - if (Files == null || Files.Length == 0) + if (Files == null || Files.Length == 0 || DataBlockOffsets == null) return false; // If the files index is invalid @@ -1094,7 +1398,7 @@ namespace BinaryObjectScanner.Wrappers // Get the file var file = Files[index]; - if (file.Size == 0) + if (file?.BlockEntries == null || file.Size == 0) return false; // If the file is encrypted -- TODO: Revisit later @@ -1106,6 +1410,8 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < file.BlockEntries.Length; i++) { var blockEntry = file.BlockEntries[i]; + if (blockEntry == null) + continue; uint dataBlockIndex = blockEntry.FirstDataBlockIndex; long blockEntrySize = blockEntry.FileDataSize; @@ -1113,12 +1419,20 @@ namespace BinaryObjectScanner.Wrappers { long dataBlockOffset = DataBlockOffsets[dataBlockIndex++]; dataBlockOffsets.Add(dataBlockOffset); +#if NET48 blockEntrySize -= DBH_BlockSize; +#else + blockEntrySize -= DBH_BlockSize ?? 0; +#endif } } // Create the filename +#if NET48 string filename = file.Path; +#else + string? filename = file.Path; +#endif // If we have an invalid output directory if (string.IsNullOrWhiteSpace(outputDirectory)) @@ -1146,11 +1460,11 @@ namespace BinaryObjectScanner.Wrappers long fileSize = file.Size; for (int i = 0; i < dataBlockOffsets.Count; i++) { - int readSize = (int)Math.Min(DBH_BlockSize, fileSize); - #if NET48 + int readSize = (int)Math.Min(DBH_BlockSize, fileSize); byte[] data = ReadFromDataSource((int)dataBlockOffsets[i], readSize); #else + int readSize = (int)Math.Min(DBH_BlockSize ?? 0, fileSize); byte[]? data = ReadFromDataSource((int)dataBlockOffsets[i], readSize); #endif if (data == null) diff --git a/BinaryObjectScanner.Wrappers/InstallShieldCabinet.cs b/BinaryObjectScanner.Wrappers/InstallShieldCabinet.cs index 5e47614b..d19dc96c 100644 --- a/BinaryObjectScanner.Wrappers/InstallShieldCabinet.cs +++ b/BinaryObjectScanner.Wrappers/InstallShieldCabinet.cs @@ -22,188 +22,316 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.CommonHeader.Signature; #else - public string? Signature => _model.CommonHeader.Signature; + public string? Signature => _model.CommonHeader?.Signature; #endif /// +#if NET48 public uint Version => _model.CommonHeader.Version; +#else + public uint? Version => _model.CommonHeader?.Version; +#endif /// +#if NET48 public uint VolumeInfo => _model.CommonHeader.VolumeInfo; +#else + public uint? VolumeInfo => _model.CommonHeader?.VolumeInfo; +#endif /// +#if NET48 public uint DescriptorOffset => _model.CommonHeader.DescriptorOffset; +#else + public uint? DescriptorOffset => _model.CommonHeader?.DescriptorOffset; +#endif /// +#if NET48 public uint DescriptorSize => _model.CommonHeader.DescriptorSize; +#else + public uint? DescriptorSize => _model.CommonHeader?.DescriptorSize; +#endif #endregion #region Volume Header /// +#if NET48 public uint DataOffset => _model.VolumeHeader.DataOffset; +#else + public uint? DataOffset => _model.VolumeHeader?.DataOffset; +#endif /// +#if NET48 public uint DataOffsetHigh => _model.VolumeHeader.DataOffsetHigh; +#else + public uint? DataOffsetHigh => _model.VolumeHeader?.DataOffsetHigh; +#endif /// +#if NET48 public uint FirstFileIndex => _model.VolumeHeader.FirstFileIndex; +#else + public uint? FirstFileIndex => _model.VolumeHeader?.FirstFileIndex; +#endif /// +#if NET48 public uint LastFileIndex => _model.VolumeHeader.LastFileIndex; +#else + public uint? LastFileIndex => _model.VolumeHeader?.LastFileIndex; +#endif /// +#if NET48 public uint FirstFileOffset => _model.VolumeHeader.FirstFileOffset; +#else + public uint? FirstFileOffset => _model.VolumeHeader?.FirstFileOffset; +#endif /// +#if NET48 public uint FirstFileOffsetHigh => _model.VolumeHeader.FirstFileOffsetHigh; +#else + public uint? FirstFileOffsetHigh => _model.VolumeHeader?.FirstFileOffsetHigh; +#endif /// +#if NET48 public uint FirstFileSizeExpanded => _model.VolumeHeader.FirstFileSizeExpanded; +#else + public uint? FirstFileSizeExpanded => _model.VolumeHeader?.FirstFileSizeExpanded; +#endif /// +#if NET48 public uint FirstFileSizeExpandedHigh => _model.VolumeHeader.FirstFileSizeExpandedHigh; +#else + public uint? FirstFileSizeExpandedHigh => _model.VolumeHeader?.FirstFileSizeExpandedHigh; +#endif /// +#if NET48 public uint FirstFileSizeCompressed => _model.VolumeHeader.FirstFileSizeCompressed; +#else + public uint? FirstFileSizeCompressed => _model.VolumeHeader?.FirstFileSizeCompressed; +#endif /// +#if NET48 public uint FirstFileSizeCompressedHigh => _model.VolumeHeader.FirstFileSizeCompressedHigh; +#else + public uint? FirstFileSizeCompressedHigh => _model.VolumeHeader?.FirstFileSizeCompressedHigh; +#endif /// +#if NET48 public uint LastFileOffset => _model.VolumeHeader.LastFileOffset; +#else + public uint? LastFileOffset => _model.VolumeHeader?.LastFileOffset; +#endif /// +#if NET48 public uint LastFileOffsetHigh => _model.VolumeHeader.LastFileOffsetHigh; +#else + public uint? LastFileOffsetHigh => _model.VolumeHeader?.LastFileOffsetHigh; +#endif /// +#if NET48 public uint LastFileSizeExpanded => _model.VolumeHeader.LastFileSizeExpanded; +#else + public uint? LastFileSizeExpanded => _model.VolumeHeader?.LastFileSizeExpanded; +#endif /// +#if NET48 public uint LastFileSizeExpandedHigh => _model.VolumeHeader.LastFileSizeExpandedHigh; +#else + public uint? LastFileSizeExpandedHigh => _model.VolumeHeader?.LastFileSizeExpandedHigh; +#endif /// +#if NET48 public uint LastFileSizeCompressed => _model.VolumeHeader.LastFileSizeCompressed; +#else + public uint? LastFileSizeCompressed => _model.VolumeHeader?.LastFileSizeCompressed; +#endif /// +#if NET48 public uint LastFileSizeCompressedHigh => _model.VolumeHeader.LastFileSizeCompressedHigh; +#else + public uint? LastFileSizeCompressedHigh => _model.VolumeHeader?.LastFileSizeCompressedHigh; +#endif #endregion #region Descriptor /// +#if NET48 public uint StringsOffset => _model.Descriptor.StringsOffset; +#else + public uint? StringsOffset => _model.Descriptor?.StringsOffset; +#endif /// #if NET48 public byte[] Reserved0 => _model.Descriptor.Reserved0; #else - public byte[]? Reserved0 => _model.Descriptor.Reserved0; + public byte[]? Reserved0 => _model.Descriptor?.Reserved0; #endif /// +#if NET48 public uint ComponentListOffset => _model.Descriptor.ComponentListOffset; +#else + public uint? ComponentListOffset => _model.Descriptor?.ComponentListOffset; +#endif /// +#if NET48 public uint FileTableOffset => _model.Descriptor.FileTableOffset; +#else + public uint? FileTableOffset => _model.Descriptor?.FileTableOffset; +#endif /// #if NET48 public byte[] Reserved1 => _model.Descriptor.Reserved1; #else - public byte[]? Reserved1 => _model.Descriptor.Reserved1; + public byte[]? Reserved1 => _model.Descriptor?.Reserved1; #endif /// +#if NET48 public uint FileTableSize => _model.Descriptor.FileTableSize; +#else + public uint? FileTableSize => _model.Descriptor?.FileTableSize; +#endif /// +#if NET48 public uint FileTableSize2 => _model.Descriptor.FileTableSize2; +#else + public uint? FileTableSize2 => _model.Descriptor?.FileTableSize2; +#endif /// +#if NET48 public ushort DirectoryCount => _model.Descriptor.DirectoryCount; +#else + public ushort? DirectoryCount => _model.Descriptor?.DirectoryCount; +#endif /// #if NET48 public byte[] Reserved2 => _model.Descriptor.Reserved2; #else - public byte[]? Reserved2 => _model.Descriptor.Reserved2; + public byte[]? Reserved2 => _model.Descriptor?.Reserved2; #endif /// #if NET48 public byte[] Reserved3 => _model.Descriptor.Reserved3; #else - public byte[]? Reserved3 => _model.Descriptor.Reserved3; + public byte[]? Reserved3 => _model.Descriptor?.Reserved3; #endif /// #if NET48 public byte[] Reserved4 => _model.Descriptor.Reserved4; #else - public byte[]? Reserved4 => _model.Descriptor.Reserved4; + public byte[]? Reserved4 => _model.Descriptor?.Reserved4; #endif /// +#if NET48 public uint FileCount => _model.Descriptor.FileCount; +#else + public uint? FileCount => _model.Descriptor?.FileCount; +#endif /// +#if NET48 public uint FileTableOffset2 => _model.Descriptor.FileTableOffset2; +#else + public uint? FileTableOffset2 => _model.Descriptor?.FileTableOffset2; +#endif /// +#if NET48 public ushort ComponentTableInfoCount => _model.Descriptor.ComponentTableInfoCount; +#else + public ushort? ComponentTableInfoCount => _model.Descriptor?.ComponentTableInfoCount; +#endif /// +#if NET48 public uint ComponentTableOffset => _model.Descriptor.ComponentTableOffset; +#else + public uint? ComponentTableOffset => _model.Descriptor?.ComponentTableOffset; +#endif /// #if NET48 public byte[] Reserved5 => _model.Descriptor.Reserved5; #else - public byte[]? Reserved5 => _model.Descriptor.Reserved5; + public byte[]? Reserved5 => _model.Descriptor?.Reserved5; #endif /// #if NET48 public byte[] Reserved6 => _model.Descriptor.Reserved6; #else - public byte[]? Reserved6 => _model.Descriptor.Reserved6; + public byte[]? Reserved6 => _model.Descriptor?.Reserved6; #endif /// #if NET48 public uint[] D_FileGroupOffsets => _model.Descriptor.FileGroupOffsets; #else - public uint[]? D_FileGroupOffsets => _model.Descriptor.FileGroupOffsets; + public uint[]? D_FileGroupOffsets => _model.Descriptor?.FileGroupOffsets; #endif /// #if NET48 public uint[] D_ComponentOffsets => _model.Descriptor.ComponentOffsets; #else - public uint[]? D_ComponentOffsets => _model.Descriptor.ComponentOffsets; + public uint[]? D_ComponentOffsets => _model.Descriptor?.ComponentOffsets; #endif /// +#if NET48 public uint SetupTypesOffset => _model.Descriptor.SetupTypesOffset; +#else + public uint? SetupTypesOffset => _model.Descriptor?.SetupTypesOffset; +#endif /// +#if NET48 public uint SetupTableOffset => _model.Descriptor.SetupTableOffset; +#else + public uint? SetupTableOffset => _model.Descriptor?.SetupTableOffset; +#endif /// #if NET48 public byte[] Reserved7 => _model.Descriptor.Reserved7; #else - public byte[]? Reserved7 => _model.Descriptor.Reserved7; + public byte[]? Reserved7 => _model.Descriptor?.Reserved7; #endif /// #if NET48 public byte[] Reserved8 => _model.Descriptor.Reserved8; #else - public byte[]? Reserved8 => _model.Descriptor.Reserved8; + public byte[]? Reserved8 => _model.Descriptor?.Reserved8; #endif #endregion @@ -296,7 +424,11 @@ namespace BinaryObjectScanner.Wrappers { get { +#if NET48 uint majorVersion = Version; +#else + uint majorVersion = Version ?? 0; +#endif if (majorVersion >> 24 == 1) { majorVersion = (majorVersion >> 12) & 0x0F; @@ -611,6 +743,12 @@ namespace BinaryObjectScanner.Wrappers { var fileDescriptor = FileDescriptors[i]; builder.AppendLine($" File Descriptor {i}:"); + if (fileDescriptor == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Name offset: {fileDescriptor.NameOffset} (0x{fileDescriptor.NameOffset:X})"); builder.AppendLine($" Name: {fileDescriptor.Name ?? "[NULL]"}"); builder.AppendLine($" Directory index: {fileDescriptor.DirectoryIndex} (0x{fileDescriptor.DirectoryIndex:X})"); diff --git a/BinaryObjectScanner.Wrappers/LinearExecutable.cs b/BinaryObjectScanner.Wrappers/LinearExecutable.cs index bf1b031a..78d11d60 100644 --- a/BinaryObjectScanner.Wrappers/LinearExecutable.cs +++ b/BinaryObjectScanner.Wrappers/LinearExecutable.cs @@ -23,47 +23,99 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Stub_Magic => _model.Stub.Header.Magic; #else - public string? Stub_Magic => _model.Stub.Header.Magic; + public string? Stub_Magic => _model.Stub?.Header?.Magic; #endif /// +#if NET48 public ushort Stub_LastPageBytes => _model.Stub.Header.LastPageBytes; +#else + public ushort? Stub_LastPageBytes => _model.Stub?.Header?.LastPageBytes; +#endif /// +#if NET48 public ushort Stub_Pages => _model.Stub.Header.Pages; +#else + public ushort? Stub_Pages => _model.Stub?.Header?.Pages; +#endif /// +#if NET48 public ushort Stub_RelocationItems => _model.Stub.Header.RelocationItems; +#else + public ushort? Stub_RelocationItems => _model.Stub?.Header?.RelocationItems; +#endif /// +#if NET48 public ushort Stub_HeaderParagraphSize => _model.Stub.Header.HeaderParagraphSize; +#else + public ushort? Stub_HeaderParagraphSize => _model.Stub?.Header?.HeaderParagraphSize; +#endif /// +#if NET48 public ushort Stub_MinimumExtraParagraphs => _model.Stub.Header.MinimumExtraParagraphs; +#else + public ushort? Stub_MinimumExtraParagraphs => _model.Stub?.Header?.MinimumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_MaximumExtraParagraphs => _model.Stub.Header.MaximumExtraParagraphs; +#else + public ushort? Stub_MaximumExtraParagraphs => _model.Stub?.Header?.MaximumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_InitialSSValue => _model.Stub.Header.InitialSSValue; +#else + public ushort? Stub_InitialSSValue => _model.Stub?.Header?.InitialSSValue; +#endif /// +#if NET48 public ushort Stub_InitialSPValue => _model.Stub.Header.InitialSPValue; +#else + public ushort? Stub_InitialSPValue => _model.Stub?.Header?.InitialSPValue; +#endif /// +#if NET48 public ushort Stub_Checksum => _model.Stub.Header.Checksum; +#else + public ushort? Stub_Checksum => _model.Stub?.Header?.Checksum; +#endif /// +#if NET48 public ushort Stub_InitialIPValue => _model.Stub.Header.InitialIPValue; +#else + public ushort? Stub_InitialIPValue => _model.Stub?.Header?.InitialIPValue; +#endif /// +#if NET48 public ushort Stub_InitialCSValue => _model.Stub.Header.InitialCSValue; +#else + public ushort? Stub_InitialCSValue => _model.Stub?.Header?.InitialCSValue; +#endif /// +#if NET48 public ushort Stub_RelocationTableAddr => _model.Stub.Header.RelocationTableAddr; +#else + public ushort? Stub_RelocationTableAddr => _model.Stub?.Header?.RelocationTableAddr; +#endif /// +#if NET48 public ushort Stub_OverlayNumber => _model.Stub.Header.OverlayNumber; +#else + public ushort? Stub_OverlayNumber => _model.Stub?.Header?.OverlayNumber; +#endif #endregion @@ -73,24 +125,36 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public ushort[] Stub_Reserved1 => _model.Stub.Header.Reserved1; #else - public ushort[]? Stub_Reserved1 => _model.Stub.Header.Reserved1; + public ushort[]? Stub_Reserved1 => _model.Stub?.Header?.Reserved1; #endif /// +#if NET48 public ushort Stub_OEMIdentifier => _model.Stub.Header.OEMIdentifier; +#else + public ushort? Stub_OEMIdentifier => _model.Stub?.Header?.OEMIdentifier; +#endif /// +#if NET48 public ushort Stub_OEMInformation => _model.Stub.Header.OEMInformation; +#else + public ushort? Stub_OEMInformation => _model.Stub?.Header?.OEMInformation; +#endif /// #if NET48 public ushort[] Stub_Reserved2 => _model.Stub.Header.Reserved2; #else - public ushort[]? Stub_Reserved2 => _model.Stub.Header.Reserved2; + public ushort[]? Stub_Reserved2 => _model?.Stub?.Header?.Reserved2; #endif /// +#if NET48 public uint Stub_NewExeHeaderAddr => _model.Stub.Header.NewExeHeaderAddr; +#else + public uint? Stub_NewExeHeaderAddr => _model.Stub?.Header?.NewExeHeaderAddr; +#endif #endregion @@ -102,143 +166,323 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.InformationBlock.Signature; #else - public string? Signature => _model.InformationBlock.Signature; + public string? Signature => _model.InformationBlock?.Signature; #endif /// +#if NET48 public SabreTools.Models.LinearExecutable.ByteOrder ByteOrder => _model.InformationBlock.ByteOrder; +#else + public SabreTools.Models.LinearExecutable.ByteOrder? ByteOrder => _model.InformationBlock?.ByteOrder; +#endif /// +#if NET48 public SabreTools.Models.LinearExecutable.WordOrder WordOrder => _model.InformationBlock.WordOrder; +#else + public SabreTools.Models.LinearExecutable.WordOrder? WordOrder => _model.InformationBlock?.WordOrder; +#endif /// +#if NET48 public uint ExecutableFormatLevel => _model.InformationBlock.ExecutableFormatLevel; +#else + public uint? ExecutableFormatLevel => _model.InformationBlock?.ExecutableFormatLevel; +#endif /// +#if NET48 public SabreTools.Models.LinearExecutable.CPUType CPUType => _model.InformationBlock.CPUType; +#else + public SabreTools.Models.LinearExecutable.CPUType? CPUType => _model.InformationBlock?.CPUType; +#endif /// +#if NET48 public SabreTools.Models.LinearExecutable.OperatingSystem ModuleOS => _model.InformationBlock.ModuleOS; +#else + public SabreTools.Models.LinearExecutable.OperatingSystem? ModuleOS => _model.InformationBlock?.ModuleOS; +#endif /// +#if NET48 public uint ModuleVersion => _model.InformationBlock.ModuleVersion; +#else + public uint? ModuleVersion => _model.InformationBlock?.ModuleVersion; +#endif /// +#if NET48 public SabreTools.Models.LinearExecutable.ModuleFlags ModuleTypeFlags => _model.InformationBlock.ModuleTypeFlags; +#else + public SabreTools.Models.LinearExecutable.ModuleFlags? ModuleTypeFlags => _model.InformationBlock?.ModuleTypeFlags; +#endif /// +#if NET48 public uint ModuleNumberPages => _model.InformationBlock.ModuleNumberPages; +#else + public uint? ModuleNumberPages => _model.InformationBlock?.ModuleNumberPages; +#endif /// +#if NET48 public uint InitialObjectCS => _model.InformationBlock.InitialObjectCS; +#else + public uint? InitialObjectCS => _model.InformationBlock?.InitialObjectCS; +#endif /// +#if NET48 public uint InitialEIP => _model.InformationBlock.InitialEIP; +#else + public uint? InitialEIP => _model.InformationBlock?.InitialEIP; +#endif /// +#if NET48 public uint InitialObjectSS => _model.InformationBlock.InitialObjectSS; +#else + public uint? InitialObjectSS => _model.InformationBlock?.InitialObjectSS; +#endif /// +#if NET48 public uint InitialESP => _model.InformationBlock.InitialESP; +#else + public uint? InitialESP => _model.InformationBlock?.InitialESP; +#endif /// +#if NET48 public uint MemoryPageSize => _model.InformationBlock.MemoryPageSize; +#else + public uint? MemoryPageSize => _model.InformationBlock?.MemoryPageSize; +#endif /// +#if NET48 public uint BytesOnLastPage => _model.InformationBlock.BytesOnLastPage; +#else + public uint? BytesOnLastPage => _model.InformationBlock?.BytesOnLastPage; +#endif /// +#if NET48 public uint FixupSectionSize => _model.InformationBlock.FixupSectionSize; +#else + public uint? FixupSectionSize => _model.InformationBlock?.FixupSectionSize; +#endif /// +#if NET48 public uint FixupSectionChecksum => _model.InformationBlock.FixupSectionChecksum; +#else + public uint? FixupSectionChecksum => _model.InformationBlock?.FixupSectionChecksum; +#endif /// +#if NET48 public uint LoaderSectionSize => _model.InformationBlock.LoaderSectionSize; +#else + public uint? LoaderSectionSize => _model.InformationBlock?.LoaderSectionSize; +#endif /// +#if NET48 public uint LoaderSectionChecksum => _model.InformationBlock.LoaderSectionChecksum; +#else + public uint? LoaderSectionChecksum => _model.InformationBlock?.LoaderSectionChecksum; +#endif /// +#if NET48 public uint ObjectTableOffset => _model.InformationBlock.ObjectTableOffset; +#else + public uint? ObjectTableOffset => _model.InformationBlock?.ObjectTableOffset; +#endif /// +#if NET48 public uint ObjectTableCount => _model.InformationBlock.ObjectTableCount; +#else + public uint? ObjectTableCount => _model.InformationBlock?.ObjectTableCount; +#endif /// +#if NET48 public uint ObjectPageMapOffset => _model.InformationBlock.ObjectPageMapOffset; +#else + public uint? ObjectPageMapOffset => _model.InformationBlock?.ObjectPageMapOffset; +#endif /// +#if NET48 public uint ObjectIterateDataMapOffset => _model.InformationBlock.ObjectIterateDataMapOffset; +#else + public uint? ObjectIterateDataMapOffset => _model.InformationBlock?.ObjectIterateDataMapOffset; +#endif /// +#if NET48 public uint ResourceTableOffset => _model.InformationBlock.ResourceTableOffset; +#else + public uint? ResourceTableOffset => _model.InformationBlock?.ResourceTableOffset; +#endif /// +#if NET48 public uint ResourceTableCount => _model.InformationBlock.ResourceTableCount; +#else + public uint? ResourceTableCount => _model.InformationBlock?.ResourceTableCount; +#endif /// +#if NET48 public uint ResidentNamesTableOffset => _model.InformationBlock.ResidentNamesTableOffset; +#else + public uint? ResidentNamesTableOffset => _model.InformationBlock?.ResidentNamesTableOffset; +#endif /// +#if NET48 public uint EntryTableOffset => _model.InformationBlock.EntryTableOffset; +#else + public uint? EntryTableOffset => _model.InformationBlock?.EntryTableOffset; +#endif /// +#if NET48 public uint ModuleDirectivesTableOffset => _model.InformationBlock.ModuleDirectivesTableOffset; +#else + public uint? ModuleDirectivesTableOffset => _model.InformationBlock?.ModuleDirectivesTableOffset; +#endif /// +#if NET48 public uint ModuleDirectivesCount => _model.InformationBlock.ModuleDirectivesCount; +#else + public uint? ModuleDirectivesCount => _model.InformationBlock?.ModuleDirectivesCount; +#endif /// +#if NET48 public uint FixupPageTableOffset => _model.InformationBlock.FixupPageTableOffset; +#else + public uint? FixupPageTableOffset => _model.InformationBlock?.FixupPageTableOffset; +#endif /// +#if NET48 public uint FixupRecordTableOffset => _model.InformationBlock.FixupRecordTableOffset; +#else + public uint? FixupRecordTableOffset => _model.InformationBlock?.FixupRecordTableOffset; +#endif /// +#if NET48 public uint ImportedModulesNameTableOffset => _model.InformationBlock.ImportedModulesNameTableOffset; +#else + public uint? ImportedModulesNameTableOffset => _model.InformationBlock?.ImportedModulesNameTableOffset; +#endif /// +#if NET48 public uint ImportedModulesCount => _model.InformationBlock.ImportedModulesCount; +#else + public uint? ImportedModulesCount => _model.InformationBlock?.ImportedModulesCount; +#endif /// +#if NET48 public uint ImportProcedureNameTableOffset => _model.InformationBlock.ImportProcedureNameTableOffset; +#else + public uint? ImportProcedureNameTableOffset => _model.InformationBlock?.ImportProcedureNameTableOffset; +#endif /// +#if NET48 public uint PerPageChecksumTableOffset => _model.InformationBlock.PerPageChecksumTableOffset; +#else + public uint? PerPageChecksumTableOffset => _model.InformationBlock?.PerPageChecksumTableOffset; +#endif /// +#if NET48 public uint DataPagesOffset => _model.InformationBlock.DataPagesOffset; +#else + public uint? DataPagesOffset => _model.InformationBlock?.DataPagesOffset; +#endif /// +#if NET48 public uint PreloadPageCount => _model.InformationBlock.PreloadPageCount; +#else + public uint? PreloadPageCount => _model.InformationBlock?.PreloadPageCount; +#endif /// +#if NET48 public uint NonResidentNamesTableOffset => _model.InformationBlock.NonResidentNamesTableOffset; +#else + public uint? NonResidentNamesTableOffset => _model.InformationBlock?.NonResidentNamesTableOffset; +#endif /// +#if NET48 public uint NonResidentNamesTableLength => _model.InformationBlock.NonResidentNamesTableLength; +#else + public uint? NonResidentNamesTableLength => _model.InformationBlock?.NonResidentNamesTableLength; +#endif /// +#if NET48 public uint NonResidentNamesTableChecksum => _model.InformationBlock.NonResidentNamesTableChecksum; +#else + public uint? NonResidentNamesTableChecksum => _model.InformationBlock?.NonResidentNamesTableChecksum; +#endif /// +#if NET48 public uint AutomaticDataObject => _model.InformationBlock.AutomaticDataObject; +#else + public uint? AutomaticDataObject => _model.InformationBlock?.AutomaticDataObject; +#endif /// +#if NET48 public uint DebugInformationOffset => _model.InformationBlock.DebugInformationOffset; +#else + public uint? DebugInformationOffset => _model.InformationBlock?.DebugInformationOffset; +#endif /// +#if NET48 public uint DebugInformationLength => _model.InformationBlock.DebugInformationLength; +#else + public uint? DebugInformationLength => _model.InformationBlock?.DebugInformationLength; +#endif /// +#if NET48 public uint PreloadInstancePagesNumber => _model.InformationBlock.PreloadInstancePagesNumber; +#else + public uint? PreloadInstancePagesNumber => _model.InformationBlock?.PreloadInstancePagesNumber; +#endif /// +#if NET48 public uint DemandInstancePagesNumber => _model.InformationBlock.DemandInstancePagesNumber; +#else + public uint? DemandInstancePagesNumber => _model.InformationBlock?.DemandInstancePagesNumber; +#endif /// +#if NET48 public uint ExtraHeapAllocation => _model.InformationBlock.ExtraHeapAllocation; +#else + public uint? ExtraHeapAllocation => _model.InformationBlock?.ExtraHeapAllocation; +#endif #endregion @@ -389,11 +633,11 @@ namespace BinaryObjectScanner.Wrappers { // All logic is handled by the base class }/// - /// Create an LE/LX executable from a byte array and offset - /// - /// Byte array representing the executable - /// Offset within the array to parse - /// An LE/LX executable wrapper on success, null on failure + /// Create an LE/LX executable from a byte array and offset + /// + /// Byte array representing the executable + /// Offset within the array to parse + /// An LE/LX executable wrapper on success, null on failure #if NET48 public static LinearExecutable Create(byte[] data, int offset) #else @@ -599,6 +843,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ObjectTable[i]; builder.AppendLine($" Object Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -628,6 +878,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ObjectPageMap[i]; builder.AppendLine($" Object Page Map Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -654,6 +910,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ResourceTable[i]; builder.AppendLine($" Resource Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -682,6 +944,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ResidentNamesTable[i]; builder.AppendLine($" Resident Names Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -708,6 +976,12 @@ namespace BinaryObjectScanner.Wrappers { var bundle = EntryTable[i]; builder.AppendLine($" Entry Table Bundle {i}"); + if (bundle == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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) @@ -719,6 +993,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = bundle.TableEntries[j]; builder.AppendLine($" Entry Table Entry {j}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + switch (bundle.BundleType & ~SabreTools.Models.LinearExecutable.BundleType.ParameterTypingInformationPresent) { case SabreTools.Models.LinearExecutable.BundleType.UnusedEntry: @@ -781,6 +1061,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ModuleFormatDirectivesTable[i]; builder.AppendLine($" Moduile Format Directives Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -807,6 +1093,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = VerifyRecordDirectiveTable[i]; builder.AppendLine($" Verify Record Directive Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -837,6 +1129,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = FixupPageTable[i]; builder.AppendLine($" Fix-up Page Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); } } @@ -862,6 +1160,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = FixupRecordTable[i]; builder.AppendLine($" Fix-up Record Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Source type: {entry.SourceType} (0x{entry.SourceType:X})"); builder.AppendLine($" Target flags: {entry.TargetFlags} (0x{entry.TargetFlags:X})"); @@ -896,26 +1200,26 @@ namespace BinaryObjectScanner.Wrappers { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + builder.AppendLine($" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); else - builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + builder.AppendLine($" 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(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.EightBitOrdinalFlag)) - builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberByte} (0x{entry.ImportedOrdinalNumberByte:X})"); + builder.AppendLine($" Imported ordinal number: {entry.ImportedOrdinalNumberByte} (0x{entry.ImportedOrdinalNumberByte:X})"); else if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberDWORD} (0x{entry.ImportedOrdinalNumberDWORD:X})"); + builder.AppendLine($" Imported ordinal number: {entry.ImportedOrdinalNumberDWORD} (0x{entry.ImportedOrdinalNumberDWORD:X})"); else - builder.AppendLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberWORD} (0x{entry.ImportedOrdinalNumberWORD:X})"); + builder.AppendLine($" Imported ordinal number: {entry.ImportedOrdinalNumberWORD} (0x{entry.ImportedOrdinalNumberWORD:X})"); // Additive Fixup Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } @@ -924,24 +1228,24 @@ namespace BinaryObjectScanner.Wrappers { // 16-bit Object Number/Module Ordinal Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + builder.AppendLine($" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); else - builder.AppendLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + builder.AppendLine($" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); // 32-bit Target Offset Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - builder.AppendLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableDWORD} (0x{entry.OffsetImportProcedureNameTableDWORD:X})"); + builder.AppendLine($" Offset import procedure name table: {entry.OffsetImportProcedureNameTableDWORD} (0x{entry.OffsetImportProcedureNameTableDWORD:X})"); else - builder.AppendLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableWORD} (0x{entry.OffsetImportProcedureNameTableWORD:X})"); + builder.AppendLine($" Offset import procedure name table: {entry.OffsetImportProcedureNameTableWORD} (0x{entry.OffsetImportProcedureNameTableWORD:X})"); // Additive Fixup Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } @@ -959,9 +1263,9 @@ namespace BinaryObjectScanner.Wrappers { // 32-bit Additive Flag if (entry.TargetFlags.HasFlag(SabreTools.Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); else - builder.AppendLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + builder.AppendLine($" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); } } @@ -1008,6 +1312,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ImportModuleNameTable[i]; builder.AppendLine($" Import Module Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); } @@ -1033,6 +1343,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ImportModuleProcedureNameTable[i]; builder.AppendLine($" Import Module Procedure Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Length: {entry.Length} (0x{entry.Length:X})"); builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); } @@ -1058,6 +1374,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = PerPageChecksumTable[i]; builder.AppendLine($" Per-Page Checksum Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Checksum: {entry.Checksum} (0x{entry.Checksum:X})"); } } @@ -1082,6 +1404,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = NonResidentNamesTable[i]; builder.AppendLine($" Non-Resident Names Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -1145,11 +1473,19 @@ namespace BinaryObjectScanner.Wrappers switch (_dataSource) { case DataSource.ByteArray: +#if NET48 length = _byteArrayData.Length - _byteArrayOffset; +#else + length = _byteArrayData!.Length - _byteArrayOffset; +#endif break; case DataSource.Stream: +#if NET48 length = (int)_streamData.Length; +#else + length = (int)_streamData!.Length; +#endif break; } } diff --git a/BinaryObjectScanner.Wrappers/MSDOS.cs b/BinaryObjectScanner.Wrappers/MSDOS.cs index 1163f38d..547cf653 100644 --- a/BinaryObjectScanner.Wrappers/MSDOS.cs +++ b/BinaryObjectScanner.Wrappers/MSDOS.cs @@ -20,47 +20,99 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Magic => _model.Header.Magic; #else - public string? Magic => _model.Header.Magic; + public string? Magic => _model.Header?.Magic; #endif /// +#if NET48 public ushort LastPageBytes => _model.Header.LastPageBytes; +#else + public ushort? LastPageBytes => _model.Header?.LastPageBytes; +#endif /// +#if NET48 public ushort Pages => _model.Header.Pages; +#else + public ushort? Pages => _model.Header?.Pages; +#endif /// +#if NET48 public ushort RelocationItems => _model.Header.RelocationItems; +#else + public ushort? RelocationItems => _model.Header?.RelocationItems; +#endif /// +#if NET48 public ushort HeaderParagraphSize => _model.Header.HeaderParagraphSize; +#else + public ushort? HeaderParagraphSize => _model.Header?.HeaderParagraphSize; +#endif /// +#if NET48 public ushort MinimumExtraParagraphs => _model.Header.MinimumExtraParagraphs; +#else + public ushort? MinimumExtraParagraphs => _model.Header?.MinimumExtraParagraphs; +#endif /// +#if NET48 public ushort MaximumExtraParagraphs => _model.Header.MaximumExtraParagraphs; +#else + public ushort? MaximumExtraParagraphs => _model.Header?.MaximumExtraParagraphs; +#endif /// +#if NET48 public ushort InitialSSValue => _model.Header.InitialSSValue; +#else + public ushort? InitialSSValue => _model.Header?.InitialSSValue; +#endif /// +#if NET48 public ushort InitialSPValue => _model.Header.InitialSPValue; +#else + public ushort? InitialSPValue => _model.Header?.InitialSPValue; +#endif /// +#if NET48 public ushort Checksum => _model.Header.Checksum; +#else + public ushort? Checksum => _model.Header?.Checksum; +#endif /// +#if NET48 public ushort InitialIPValue => _model.Header.InitialIPValue; +#else + public ushort? InitialIPValue => _model.Header?.InitialIPValue; +#endif /// +#if NET48 public ushort InitialCSValue => _model.Header.InitialCSValue; +#else + public ushort? InitialCSValue => _model.Header?.InitialCSValue; +#endif /// +#if NET48 public ushort RelocationTableAddr => _model.Header.RelocationTableAddr; +#else + public ushort? RelocationTableAddr => _model.Header?.RelocationTableAddr; +#endif /// +#if NET48 public ushort OverlayNumber => _model.Header.OverlayNumber; +#else + public ushort? OverlayNumber => _model.Header?.OverlayNumber; +#endif #endregion @@ -70,24 +122,36 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public ushort[] Reserved1 => _model.Header.Reserved1; #else - public ushort[]? Reserved1 => _model.Header.Reserved1; + public ushort[]? Reserved1 => _model.Header?.Reserved1; #endif /// +#if NET48 public ushort OEMIdentifier => _model.Header.OEMIdentifier; +#else + public ushort? OEMIdentifier => _model.Header?.OEMIdentifier; +#endif /// +#if NET48 public ushort OEMInformation => _model.Header.OEMInformation; +#else + public ushort? OEMInformation => _model.Header?.OEMInformation; +#endif /// #if NET48 public ushort[] Reserved2 => _model.Header.Reserved2; #else - public ushort[]? Reserved2 => _model.Header.Reserved2; + public ushort[]? Reserved2 => _model.Header?.Reserved2; #endif /// +#if NET48 public uint NewExeHeaderAddr => _model.Header.NewExeHeaderAddr; +#else + public uint? NewExeHeaderAddr => _model.Header?.NewExeHeaderAddr; +#endif #endregion @@ -231,7 +295,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Relocation Table Information:"); builder.AppendLine(" -------------------------"); - if (RelocationItems == 0 || RelocationTable.Length == 0) + if (RelocationItems == 0 || RelocationTable == null || RelocationTable.Length == 0) { builder.AppendLine(" No relocation table items"); } @@ -241,6 +305,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = RelocationTable[i]; builder.AppendLine($" Relocation Table Entry {i}"); + if (entry == null) + { + builder.AppendLine($" [NULL]"); + continue; + } + builder.AppendLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); builder.AppendLine($" Segment: {entry.Segment} (0x{entry.Segment:X})"); } diff --git a/BinaryObjectScanner.Wrappers/MicrosoftCabinet.cs b/BinaryObjectScanner.Wrappers/MicrosoftCabinet.cs index 56f62f9d..609b104f 100644 --- a/BinaryObjectScanner.Wrappers/MicrosoftCabinet.cs +++ b/BinaryObjectScanner.Wrappers/MicrosoftCabinet.cs @@ -22,87 +22,147 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public uint Reserved1 => _model.Header.Reserved1; +#else + public uint? Reserved1 => _model.Header?.Reserved1; +#endif /// +#if NET48 public uint CabinetSize => _model.Header.CabinetSize; +#else + public uint? CabinetSize => _model.Header?.CabinetSize; +#endif /// +#if NET48 public uint Reserved2 => _model.Header.Reserved2; +#else + public uint? Reserved2 => _model.Header?.Reserved2; +#endif /// +#if NET48 public uint FilesOffset => _model.Header.FilesOffset; +#else + public uint? FilesOffset => _model.Header?.FilesOffset; +#endif /// +#if NET48 public uint Reserved3 => _model.Header.Reserved3; +#else + public uint? Reserved3 => _model.Header?.Reserved3; +#endif /// +#if NET48 public byte VersionMinor => _model.Header.VersionMinor; +#else + public byte? VersionMinor => _model.Header?.VersionMinor; +#endif /// +#if NET48 public byte VersionMajor => _model.Header.VersionMajor; +#else + public byte? VersionMajor => _model.Header?.VersionMajor; +#endif /// +#if NET48 public ushort FolderCount => _model.Header.FolderCount; +#else + public ushort? FolderCount => _model.Header?.FolderCount; +#endif /// +#if NET48 public ushort FileCount => _model.Header.FileCount; +#else + public ushort? FileCount => _model.Header?.FileCount; +#endif /// +#if NET48 public SabreTools.Models.MicrosoftCabinet.HeaderFlags Flags => _model.Header.Flags; +#else + public SabreTools.Models.MicrosoftCabinet.HeaderFlags? Flags => _model.Header?.Flags; +#endif /// +#if NET48 public ushort SetID => _model.Header.SetID; +#else + public ushort? SetID => _model.Header?.SetID; +#endif /// +#if NET48 public ushort CabinetIndex => _model.Header.CabinetIndex; +#else + public ushort? CabinetIndex => _model.Header?.CabinetIndex; +#endif /// +#if NET48 public ushort HeaderReservedSize => _model.Header.HeaderReservedSize; +#else + public ushort? HeaderReservedSize => _model.Header?.HeaderReservedSize; +#endif /// +#if NET48 public byte FolderReservedSize => _model.Header.FolderReservedSize; +#else + public byte? FolderReservedSize => _model.Header?.FolderReservedSize; +#endif /// +#if NET48 public byte DataReservedSize => _model.Header.DataReservedSize; +#else + public byte? DataReservedSize => _model.Header?.DataReservedSize; +#endif /// #if NET48 public byte[] ReservedData => _model.Header.ReservedData; #else - public byte[]? ReservedData => _model.Header.ReservedData; + public byte[]? ReservedData => _model.Header?.ReservedData; #endif /// #if NET48 public string CabinetPrev => _model.Header.CabinetPrev; #else - public string? CabinetPrev => _model.Header.CabinetPrev; + public string? CabinetPrev => _model.Header?.CabinetPrev; #endif /// #if NET48 public string DiskPrev => _model.Header.DiskPrev; #else - public string? DiskPrev => _model.Header.DiskPrev; + public string? DiskPrev => _model.Header?.DiskPrev; #endif /// #if NET48 public string CabinetNext => _model.Header.CabinetNext; #else - public string? CabinetNext => _model.Header.CabinetNext; + public string? CabinetNext => _model.Header?.CabinetNext; #endif /// #if NET48 public string DiskNext => _model.Header.DiskNext; #else - public string? DiskNext => _model.Header.DiskNext; + public string? DiskNext => _model.Header?.DiskNext; #endif #endregion @@ -262,7 +322,7 @@ namespace BinaryObjectScanner.Wrappers #endif { // If we have an invalid folder index - if (folderIndex < 0 || folderIndex >= Folders.Length) + if (folderIndex < 0 || Folders == null || folderIndex >= Folders.Length) return null; // Get the folder header @@ -288,6 +348,9 @@ namespace BinaryObjectScanner.Wrappers List data = new List(); foreach (var dataBlock in folder.DataBlocks) { + if (dataBlock == null) + continue; + byte[] decompressed = new byte[dataBlock.UncompressedSize]; switch (folder.CompressionType & SabreTools.Models.MicrosoftCabinet.CompressionType.MASK_TYPE) { @@ -350,7 +413,7 @@ namespace BinaryObjectScanner.Wrappers public bool ExtractFile(int index, string outputDirectory) { // If we have an invalid file index - if (index < 0 || index >= Files.Length) + if (index < 0 || Files == null || index >= Files.Length) return false; // If we have an invalid output directory @@ -369,7 +432,11 @@ namespace BinaryObjectScanner.Wrappers string fileName = Path.Combine(outputDirectory, file.Name ?? $"file{index}"); // Get the file data, if possible +#if NET48 byte[] fileData = GetFileData(index); +#else + byte[]? fileData = GetFileData(index); +#endif if (fileData == null) return false; @@ -390,7 +457,7 @@ namespace BinaryObjectScanner.Wrappers public DateTime? GetDateTime(int fileIndex) { // If we have an invalid file index - if (fileIndex < 0 || fileIndex >= Files.Length) + if (fileIndex < 0 || Files == null || fileIndex >= Files.Length) return null; // Get the file header @@ -434,7 +501,7 @@ namespace BinaryObjectScanner.Wrappers #endif { // If we have an invalid file index - if (fileIndex < 0 || fileIndex >= Files.Length) + if (fileIndex < 0 || Files == null || fileIndex >= Files.Length) return null; // Get the file header @@ -443,7 +510,11 @@ namespace BinaryObjectScanner.Wrappers return null; // Get the parent folder data +#if NET48 byte[] folderData = GetUncompressedData((int)file.FolderIndex); +#else + byte[]? folderData = GetUncompressedData((int)file.FolderIndex); +#endif if (folderData == null || folderData.Length == 0) return null; @@ -499,7 +570,11 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Set ID: {SetID} (0x{SetID:X})"); builder.AppendLine($" Cabinet index: {CabinetIndex} (0x{CabinetIndex:X})"); +#if NET48 if (Flags.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.RESERVE_PRESENT)) +#else + if (Flags != null && Flags.Value.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.RESERVE_PRESENT)) +#endif { builder.AppendLine($" Header reserved size: {HeaderReservedSize} (0x{HeaderReservedSize:X})"); builder.AppendLine($" Folder reserved size: {FolderReservedSize} (0x{FolderReservedSize:X})"); @@ -510,13 +585,21 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Reserved data = {BitConverter.ToString(ReservedData).Replace("-", " ")}"); } +#if NET48 if (Flags.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.PREV_CABINET)) +#else + if (Flags != null && Flags.Value.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.PREV_CABINET)) +#endif { builder.AppendLine($" Previous cabinet: {CabinetPrev}"); builder.AppendLine($" Previous disk: {DiskPrev}"); } +#if NET48 if (Flags.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.NEXT_CABINET)) +#else + if (Flags != null && Flags.Value.HasFlag(SabreTools.Models.MicrosoftCabinet.HeaderFlags.NEXT_CABINET)) +#endif { builder.AppendLine($" Next cabinet: {CabinetNext}"); builder.AppendLine($" Next disk: {DiskNext}"); @@ -543,14 +626,17 @@ namespace BinaryObjectScanner.Wrappers { var entry = Folders[i]; builder.AppendLine($" Folder {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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 & SabreTools.Models.MicrosoftCabinet.CompressionType.MASK_TYPE}"); - if (entry.ReservedData == null) - builder.AppendLine($" Reserved data = [NULL]"); - else - builder.AppendLine($" Reserved data = {BitConverter.ToString(entry.ReservedData).Replace("-", " ")}"); + builder.AppendLine($" Reserved data = {(entry.ReservedData == null ? "[NULL]" : BitConverter.ToString(entry.ReservedData).Replace("-", " "))}"); builder.AppendLine(); builder.AppendLine(" Data Blocks"); @@ -565,13 +651,16 @@ namespace BinaryObjectScanner.Wrappers { SabreTools.Models.MicrosoftCabinet.CFDATA dataBlock = entry.DataBlocks[j]; builder.AppendLine($" Data Block {j}"); + if (dataBlock == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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) - builder.AppendLine($" Reserved data = [NULL]"); - else - builder.AppendLine($" Reserved data = {BitConverter.ToString(dataBlock.ReservedData).Replace("-", " ")}"); + builder.AppendLine($" Reserved data = {(dataBlock.ReservedData == null ? "[NULL]" : BitConverter.ToString(dataBlock.ReservedData).Replace("-", " "))}"); //builder.AppendLine($" Compressed data = {BitConverter.ToString(dataBlock.CompressedData).Replace("-", " ")}"); } } @@ -598,6 +687,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = Files[i]; builder.AppendLine($" File {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/N3DS.cs b/BinaryObjectScanner.Wrappers/N3DS.cs index 3aa70518..5eb6d588 100644 --- a/BinaryObjectScanner.Wrappers/N3DS.cs +++ b/BinaryObjectScanner.Wrappers/N3DS.cs @@ -23,41 +23,49 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public byte[] RSA2048Signature => _model.Header.RSA2048Signature; #else - public byte[]? RSA2048Signature => _model.Header.RSA2048Signature; + public byte[]? RSA2048Signature => _model.Header?.RSA2048Signature; #endif /// #if NET48 public string MagicNumber => _model.Header.MagicNumber; #else - public string? MagicNumber => _model.Header.MagicNumber; + public string? MagicNumber => _model.Header?.MagicNumber; #endif /// +#if NET48 public uint ImageSizeInMediaUnits => _model.Header.ImageSizeInMediaUnits; +#else + public uint? ImageSizeInMediaUnits => _model.Header?.ImageSizeInMediaUnits; +#endif /// #if NET48 public byte[] MediaId => _model.Header.MediaId; #else - public byte[]? MediaId => _model.Header.MediaId; + public byte[]? MediaId => _model.Header?.MediaId; #endif /// +#if NET48 public SabreTools.Models.N3DS.FilesystemType PartitionsFSType => _model.Header.PartitionsFSType; +#else + public SabreTools.Models.N3DS.FilesystemType? PartitionsFSType => _model.Header?.PartitionsFSType; +#endif /// #if NET48 public byte[] PartitionsCryptType => _model.Header.PartitionsCryptType; #else - public byte[]? PartitionsCryptType => _model.Header.PartitionsCryptType; + public byte[]? PartitionsCryptType => _model.Header?.PartitionsCryptType; #endif /// #if NET48 public SabreTools.Models.N3DS.PartitionTableEntry[] PartitionsTable => _model.Header.PartitionsTable; #else - public SabreTools.Models.N3DS.PartitionTableEntry?[]? PartitionsTable => _model.Header.PartitionsTable; + public SabreTools.Models.N3DS.PartitionTableEntry?[]? PartitionsTable => _model.Header?.PartitionsTable; #endif #endregion @@ -68,48 +76,64 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public byte[] ExheaderHash => _model.Header.ExheaderHash; #else - public byte[]? ExheaderHash => _model.Header.ExheaderHash; + public byte[]? ExheaderHash => _model.Header?.ExheaderHash; #endif /// +#if NET48 public uint AdditionalHeaderSize => _model.Header.AdditionalHeaderSize; +#else + public uint? AdditionalHeaderSize => _model.Header?.AdditionalHeaderSize; +#endif /// +#if NET48 public uint SectorZeroOffset => _model.Header.SectorZeroOffset; +#else + public uint? SectorZeroOffset => _model.Header?.SectorZeroOffset; +#endif /// #if NET48 public byte[] PartitionFlags => _model.Header.PartitionFlags; #else - public byte[]? PartitionFlags => _model.Header.PartitionFlags; + public byte[]? PartitionFlags => _model.Header?.PartitionFlags; #endif /// #if NET48 public ulong[] PartitionIdTable => _model.Header.PartitionIdTable; #else - public ulong[]? PartitionIdTable => _model.Header.PartitionIdTable; + public ulong[]? PartitionIdTable => _model.Header?.PartitionIdTable; #endif /// #if NET48 public byte[] Reserved1 => _model.Header.Reserved1; #else - public byte[]? Reserved1 => _model.Header.Reserved1; + public byte[]? Reserved1 => _model.Header?.Reserved1; #endif /// #if NET48 public byte[] Reserved2 => _model.Header.Reserved2; #else - public byte[]? Reserved2 => _model.Header.Reserved2; + public byte[]? Reserved2 => _model.Header?.Reserved2; #endif /// +#if NET48 public byte FirmUpdateByte1 => _model.Header.FirmUpdateByte1; +#else + public byte? FirmUpdateByte1 => _model.Header?.FirmUpdateByte1; +#endif /// +#if NET48 public byte FirmUpdateByte2 => _model.Header.FirmUpdateByte2; +#else + public byte? FirmUpdateByte2 => _model.Header?.FirmUpdateByte2; +#endif #endregion @@ -119,14 +143,14 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public byte[] Unknown => _model.Header.Unknown; #else - public byte[]? Unknown => _model.Header.Unknown; + public byte[]? Unknown => _model.Header?.Unknown; #endif /// #if NET48 public byte[] EncryptedMBR => _model.Header.EncryptedMBR; #else - public byte[]? EncryptedMBR => _model.Header.EncryptedMBR; + public byte[]? EncryptedMBR => _model.Header?.EncryptedMBR; #endif #endregion @@ -136,56 +160,80 @@ namespace BinaryObjectScanner.Wrappers #region Card Info Header /// +#if NET48 public uint CIH_WritableAddressMediaUnits => _model.CardInfoHeader.WritableAddressMediaUnits; +#else + public uint? CIH_WritableAddressMediaUnits => _model.CardInfoHeader?.WritableAddressMediaUnits; +#endif /// +#if NET48 public uint CIH_CardInfoBitmask => _model.CardInfoHeader.CardInfoBitmask; +#else + public uint? CIH_CardInfoBitmask => _model.CardInfoHeader?.CardInfoBitmask; +#endif /// #if NET48 public byte[] CIH_Reserved1 => _model.CardInfoHeader.Reserved1; #else - public byte[]? CIH_Reserved1 => _model.CardInfoHeader.Reserved1; + public byte[]? CIH_Reserved1 => _model.CardInfoHeader?.Reserved1; #endif /// +#if NET48 public uint CIH_FilledSize => _model.CardInfoHeader.FilledSize; +#else + public uint? CIH_FilledSize => _model.CardInfoHeader?.FilledSize; +#endif /// #if NET48 public byte[] CIH_Reserved2 => _model.CardInfoHeader.Reserved2; #else - public byte[]? CIH_Reserved2 => _model.CardInfoHeader.Reserved2; + public byte[]? CIH_Reserved2 => _model.CardInfoHeader?.Reserved2; #endif /// +#if NET48 public ushort CIH_TitleVersion => _model.CardInfoHeader.TitleVersion; +#else + public ushort? CIH_TitleVersion => _model.CardInfoHeader?.TitleVersion; +#endif /// +#if NET48 public ushort CIH_CardRevision => _model.CardInfoHeader.CardRevision; +#else + public ushort? CIH_CardRevision => _model.CardInfoHeader?.CardRevision; +#endif /// #if NET48 public byte[] CIH_Reserved3 => _model.CardInfoHeader.Reserved3; #else - public byte[]? CIH_Reserved3 => _model.CardInfoHeader.Reserved3; + public byte[]? CIH_Reserved3 => _model.CardInfoHeader?.Reserved3; #endif /// #if NET48 public byte[] CIH_CVerTitleID => _model.CardInfoHeader.CVerTitleID; #else - public byte[]? CIH_CVerTitleID => _model.CardInfoHeader.CVerTitleID; + public byte[]? CIH_CVerTitleID => _model.CardInfoHeader?.CVerTitleID; #endif /// +#if NET48 public ushort CIH_CVerVersionNumber => _model.CardInfoHeader.CVerVersionNumber; +#else + public ushort? CIH_CVerVersionNumber => _model.CardInfoHeader?.CVerVersionNumber; +#endif /// #if NET48 public byte[] CIH_Reserved4 => _model.CardInfoHeader.Reserved4; #else - public byte[]? CIH_Reserved4 => _model.CardInfoHeader.Reserved4; + public byte[]? CIH_Reserved4 => _model.CardInfoHeader?.Reserved4; #endif #endregion @@ -497,12 +545,25 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Partition table:"); builder.AppendLine(" -------------------------"); - for (int i = 0; i < PartitionsTable.Length; i++) + if (PartitionsTable == null || PartitionsTable.Length == 0) { - var partitionTableEntry = PartitionsTable[i]; - builder.AppendLine($" Partition table entry {i}"); - builder.AppendLine($" Offset: {partitionTableEntry.Offset} (0x{partitionTableEntry.Offset:X})"); - builder.AppendLine($" Length: {partitionTableEntry.Length} (0x{partitionTableEntry.Length:X})"); + builder.AppendLine(" No partition table entries"); + } + else + { + for (int i = 0; i < PartitionsTable.Length; i++) + { + var partitionTableEntry = PartitionsTable[i]; + builder.AppendLine($" Partition table entry {i}"); + if (partitionTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine($" Offset: {partitionTableEntry.Offset} (0x{partitionTableEntry.Offset:X})"); + builder.AppendLine($" Length: {partitionTableEntry.Length} (0x{partitionTableEntry.Length:X})"); + } } builder.AppendLine(); @@ -517,9 +578,16 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Partition ID table:"); builder.AppendLine(" -------------------------"); - for (int i = 0; i < PartitionIdTable.Length; i++) + if (PartitionIdTable == null || PartitionIdTable.Length == 0) { - builder.AppendLine($" Partition {i} ID: {PartitionIdTable[i]} (0x{PartitionIdTable[i]:X})"); + builder.AppendLine(" No partition ID table entries"); + } + else + { + for (int i = 0; i < PartitionIdTable.Length; i++) + { + builder.AppendLine($" Partition {i} ID: {PartitionIdTable[i]} (0x{PartitionIdTable[i]:X})"); + } } builder.AppendLine(); @@ -587,34 +655,41 @@ namespace BinaryObjectScanner.Wrappers 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: {(DCIH_ID_BackupHeader.ProgramId == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.ProgramId).Replace('-', ' '))}"); - builder.AppendLine($" Reserved 1: {(DCIH_ID_BackupHeader.Reserved1 == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved1).Replace('-', ' '))}"); - builder.AppendLine($" Logo region SHA-256 hash: {(DCIH_ID_BackupHeader.LogoRegionHash == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.ExtendedHeaderHash == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved2 == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved3 == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved4 == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved4).Replace('-', ' '))}"); - builder.AppendLine($" ExeFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.ExeFSSuperblockHash == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.ExeFSSuperblockHash).Replace('-', ' '))}"); - builder.AppendLine($" RomFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.RomFSSuperblockHash == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.RomFSSuperblockHash).Replace('-', ' '))}"); + if (DCIH_ID_BackupHeader == null) + { + builder.AppendLine(" No backup header"); + } + else + { + 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: {(DCIH_ID_BackupHeader.ProgramId == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.ProgramId).Replace('-', ' '))}"); + builder.AppendLine($" Reserved 1: {(DCIH_ID_BackupHeader.Reserved1 == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved1).Replace('-', ' '))}"); + builder.AppendLine($" Logo region SHA-256 hash: {(DCIH_ID_BackupHeader.LogoRegionHash == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.ExtendedHeaderHash == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved2 == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved3 == null ? "[NULL]" : 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: {(DCIH_ID_BackupHeader.Reserved4 == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.Reserved4).Replace('-', ' '))}"); + builder.AppendLine($" ExeFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.ExeFSSuperblockHash == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.ExeFSSuperblockHash).Replace('-', ' '))}"); + builder.AppendLine($" RomFS superblock SHA-256 hash: {(DCIH_ID_BackupHeader.RomFSSuperblockHash == null ? "[NULL]" : BitConverter.ToString(DCIH_ID_BackupHeader.RomFSSuperblockHash).Replace('-', ' '))}"); + } builder.AppendLine(); builder.AppendLine($" Card device reserved 1: {(DCIH_CardDeviceReserved1 == null ? "[NULL]" : BitConverter.ToString(DCIH_CardDeviceReserved1).Replace('-', ' '))}"); @@ -657,6 +732,12 @@ namespace BinaryObjectScanner.Wrappers { var partitionHeader = Partitions[i]; builder.AppendLine($" NCCH Partition Header {i}"); + if (partitionHeader == null) + { + builder.AppendLine($" [NULL]"); + continue; + } + if (partitionHeader.MagicID == string.Empty) { builder.AppendLine($" Empty partition, no data can be parsed"); @@ -682,14 +763,21 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($" Extended header size in bytes: {partitionHeader.ExtendedHeaderSizeInBytes} (0x{partitionHeader.ExtendedHeaderSizeInBytes:X})"); builder.AppendLine($" Reserved 2: {(partitionHeader.Reserved2 == null ? "[NULL]" : 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})"); + if (partitionHeader.Flags == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); @@ -735,101 +823,204 @@ namespace BinaryObjectScanner.Wrappers else { builder.AppendLine($" System control info:"); - builder.AppendLine($" Application title: {extendedHeader.SCI.ApplicationTitle}"); - builder.AppendLine($" Reserved 1: {(extendedHeader.SCI.Reserved1 == null ? "[NULL]" : 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})"); + if (extendedHeader.SCI == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Application title: {extendedHeader.SCI.ApplicationTitle}"); + builder.AppendLine($" Reserved 1: {(extendedHeader.SCI.Reserved1 == null ? "[NULL]" : 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})"); - 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})"); + builder.AppendLine($" Text code set info:"); + if (extendedHeader.SCI.TextCodeSetInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); + } - builder.AppendLine($" Stack size: {extendedHeader.SCI.StackSize} (0x{extendedHeader.SCI.StackSize:X})"); + builder.AppendLine($" Stack size: {extendedHeader.SCI.StackSize} (0x{extendedHeader.SCI.StackSize: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})"); + builder.AppendLine($" Read-only code set info:"); + if (extendedHeader.SCI.ReadOnlyCodeSetInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); + } - builder.AppendLine($" Reserved 2: {(extendedHeader.SCI.Reserved2 == null ? "[NULL]" : BitConverter.ToString(extendedHeader.SCI.Reserved2).Replace('-', ' '))}"); + builder.AppendLine($" Reserved 2: {(extendedHeader.SCI.Reserved2 == null ? "[NULL]" : BitConverter.ToString(extendedHeader.SCI.Reserved2).Replace('-', ' '))}"); - 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})"); + builder.AppendLine($" Data code set info:"); + if (extendedHeader.SCI.DataCodeSetInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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})"); + } - builder.AppendLine($" BSS size: {extendedHeader.SCI.BSSSize} (0x{extendedHeader.SCI.BSSSize:X})"); - builder.AppendLine($" Dependency module list: {(extendedHeader.SCI.DependencyModuleList == null ? "[NULL]" : string.Join(", ", extendedHeader.SCI.DependencyModuleList))}"); + builder.AppendLine($" BSS size: {extendedHeader.SCI.BSSSize} (0x{extendedHeader.SCI.BSSSize:X})"); + builder.AppendLine($" Dependency module list: {(extendedHeader.SCI.DependencyModuleList == null ? "[NULL]" : string.Join(", ", extendedHeader.SCI.DependencyModuleList))}"); - 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: {(extendedHeader.SCI.SystemInfo.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.SCI.SystemInfo.Reserved).Replace('-', ' '))}"); + builder.AppendLine($" System info:"); + if (extendedHeader.SCI.SystemInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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: {(extendedHeader.SCI.SystemInfo.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.SCI.SystemInfo.Reserved).Replace('-', ' '))}"); + } + } 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: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}"); + if (extendedHeader.ACI == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" ARM11 local system capabilities:"); + if (extendedHeader.ACI.ARM11LocalSystemCapabilities == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}"); + builder.AppendLine($" Storage info:"); + if (extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Extdata ID: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); + builder.AppendLine($" System savedata IDs: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}"); + builder.AppendLine($" Storage accessible unique IDs: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}"); + builder.AppendLine($" File system access info: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}"); + builder.AppendLine($" 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: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}"); - builder.AppendLine($" Storage accessible unique IDs: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}"); - builder.AppendLine($" File system access info: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}"); - builder.AppendLine($" Other attributes: {extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); + builder.AppendLine($" Service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl))}"); + builder.AppendLine($" Extended service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}"); + builder.AppendLine($" Reserved: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}"); + builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + } - builder.AppendLine($" Service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ServiceAccessControl))}"); - builder.AppendLine($" Extended service access control: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}"); - builder.AppendLine($" Reserved: {(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}"); - builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACI.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + builder.AppendLine($" ARM11 kernel capabilities:"); + if (extendedHeader.ACI.ARM11KernelCapabilities == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Descriptors: {(extendedHeader.ACI.ARM11KernelCapabilities.Descriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11KernelCapabilities.Descriptors))}"); + builder.AppendLine($" Reserved: {(extendedHeader.ACI.ARM11KernelCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}"); + } - builder.AppendLine($" ARM11 kernel capabilities:"); - builder.AppendLine($" Descriptors: {(extendedHeader.ACI.ARM11KernelCapabilities.Descriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACI.ARM11KernelCapabilities.Descriptors))}"); - builder.AppendLine($" Reserved: {(extendedHeader.ACI.ARM11KernelCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}"); - - builder.AppendLine($" ARM9 access control:"); - builder.AppendLine($" Descriptors: {(extendedHeader.ACI.ARM9AccessControl.Descriptors == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM9AccessControl.Descriptors).Replace('-', ' '))}"); - builder.AppendLine($" Descriptor version: {extendedHeader.ACI.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACI.ARM9AccessControl.DescriptorVersion:X})"); - - builder.AppendLine($" AccessDec signature (RSA-2048-SHA256): {(extendedHeader.AccessDescSignature == null ? "[NULL]" : BitConverter.ToString(extendedHeader.AccessDescSignature).Replace('-', ' '))}"); - builder.AppendLine($" NCCH HDR RSA-2048 public key: {(extendedHeader.NCCHHDRPublicKey == null ? "[NULL]" : BitConverter.ToString(extendedHeader.NCCHHDRPublicKey).Replace('-', ' '))}"); + builder.AppendLine($" ARM9 access control:"); + if (extendedHeader.ACI.ARM9AccessControl == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Descriptors: {(extendedHeader.ACI.ARM9AccessControl.Descriptors == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACI.ARM9AccessControl.Descriptors).Replace('-', ' '))}"); + builder.AppendLine($" Descriptor version: {extendedHeader.ACI.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACI.ARM9AccessControl.DescriptorVersion:X})"); + } + builder.AppendLine($" AccessDec signature (RSA-2048-SHA256): {(extendedHeader.AccessDescSignature == null ? "[NULL]" : BitConverter.ToString(extendedHeader.AccessDescSignature).Replace('-', ' '))}"); + builder.AppendLine($" NCCH HDR RSA-2048 public key: {(extendedHeader.NCCHHDRPublicKey == null ? "[NULL]" : BitConverter.ToString(extendedHeader.NCCHHDRPublicKey).Replace('-', ' '))}"); + } 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: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}"); + if (extendedHeader.ACIForLimitations == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" ARM11 local system capabilities:"); + if (extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + 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: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitDescriptors))}"); - 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: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}"); - builder.AppendLine($" Storage accessible unique IDs: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}"); - builder.AppendLine($" File system access info: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}"); - builder.AppendLine($" Other attributes: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); + builder.AppendLine($" Storage info:"); + if (extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Extdata ID: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.ExtdataID:X})"); + builder.AppendLine($" System savedata IDs: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.SystemSavedataIDs).Replace('-', ' '))}"); + builder.AppendLine($" Storage accessible unique IDs: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.StorageAccessibleUniqueIDs).Replace('-', ' '))}"); + builder.AppendLine($" File system access info: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.FileSystemAccessInfo).Replace('-', ' '))}"); + builder.AppendLine($" Other attributes: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.StorageInfo.OtherAttributes:X})"); + } - builder.AppendLine($" Service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl))}"); - builder.AppendLine($" Extended service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}"); - builder.AppendLine($" Reserved: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}"); - builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + builder.AppendLine($" Service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ServiceAccessControl))}"); + builder.AppendLine($" Extended service access control: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ExtendedServiceAccessControl))}"); + builder.AppendLine($" Reserved: {(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.Reserved).Replace('-', ' '))}"); + builder.AppendLine($" Resource limit cateogry: {extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory} (0x{extendedHeader.ACIForLimitations.ARM11LocalSystemCapabilities.ResourceLimitCategory:X})"); + } - builder.AppendLine($" ARM11 kernel capabilities:"); - builder.AppendLine($" Descriptors: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors))}"); - builder.AppendLine($" Reserved: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}"); + builder.AppendLine($" ARM11 kernel capabilities:"); + if (extendedHeader.ACIForLimitations.ARM11KernelCapabilities == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Descriptors: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors == null ? "[NULL]" : string.Join(", ", extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Descriptors))}"); + builder.AppendLine($" Reserved: {(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM11KernelCapabilities.Reserved).Replace('-', ' '))}"); + } - builder.AppendLine($" ARM9 access control:"); - builder.AppendLine($" Descriptors: {(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors).Replace('-', ' '))}"); - builder.AppendLine($" Descriptor version: {extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion:X})"); + builder.AppendLine($" ARM9 access control:"); + if (extendedHeader.ACIForLimitations.ARM9AccessControl == null) + { + builder.AppendLine(" [NULL]"); + } + else + { + builder.AppendLine($" Descriptors: {(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors == null ? "[NULL]" : BitConverter.ToString(extendedHeader.ACIForLimitations.ARM9AccessControl.Descriptors).Replace('-', ' '))}"); + builder.AppendLine($" Descriptor version: {extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion} (0x{extendedHeader.ACIForLimitations.ARM9AccessControl.DescriptorVersion:X})"); + } + } } } } @@ -861,23 +1052,49 @@ namespace BinaryObjectScanner.Wrappers else { builder.AppendLine($" File headers:"); - for (int j = 0; j < exeFSHeader.FileHeaders.Length; j++) + if (exeFSHeader.FileHeaders == null || exeFSHeader.FileHeaders.Length == 0) { - var fileHeader = exeFSHeader.FileHeaders[j]; - 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})"); + builder.AppendLine(" No file headers"); + } + else + { + for (int j = 0; j < exeFSHeader.FileHeaders.Length; j++) + { + var fileHeader = exeFSHeader.FileHeaders[j]; + builder.AppendLine($" File Header {j}"); + if (fileHeader == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine($" File name: {fileHeader.FileName}"); + builder.AppendLine($" File offset: {fileHeader.FileOffset} (0x{fileHeader.FileOffset:X})"); + builder.AppendLine($" File size: {fileHeader.FileSize} (0x{fileHeader.FileSize:X})"); + } } - builder.AppendLine(value: $" Reserved: {(exeFSHeader.Reserved == null ? "[NULL]" : BitConverter.ToString(exeFSHeader.Reserved).Replace('-', ' '))}"); - + builder.AppendLine($" Reserved: {(exeFSHeader.Reserved == null ? "[NULL]" : BitConverter.ToString(exeFSHeader.Reserved).Replace('-', ' '))}"); + builder.AppendLine($" File hashes:"); - for (int j = 0; j < exeFSHeader.FileHashes.Length; j++) + if (exeFSHeader.FileHashes == null || exeFSHeader.FileHashes.Length == 0) { - var fileHash = exeFSHeader.FileHashes[j]; - builder.AppendLine(value: $" File Hash {j}"); - builder.AppendLine(value: $" SHA-256: {(fileHash == null ? "[NULL]" : BitConverter.ToString(fileHash).Replace('-', ' '))}"); + builder.AppendLine(" No file hashes"); + } + else + { + for (int j = 0; j < exeFSHeader.FileHashes.Length; j++) + { + var fileHash = exeFSHeader.FileHashes[j]; + builder.AppendLine($" File Hash {j}"); + if (fileHash == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine($" SHA-256: {(fileHash == null ? "[NULL]" : BitConverter.ToString(fileHash).Replace('-', ' '))}"); + } } } } @@ -909,23 +1126,23 @@ namespace BinaryObjectScanner.Wrappers } else { - 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: {(romFSHeader.Reserved1 == null ? "[NULL]" : 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: {(romFSHeader.Reserved2 == null ? "[NULL]" : 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: {(romFSHeader.Reserved3 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' '))}"); - builder.AppendLine(value: $" Reserved 4: {(romFSHeader.Reserved4 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' '))}"); - builder.AppendLine(value: $" Optional info size: {romFSHeader.OptionalInfoSize} (0x{romFSHeader.OptionalInfoSize:X})"); + builder.AppendLine($" Magic string: {romFSHeader.MagicString}"); + builder.AppendLine($" Magic number: {romFSHeader.MagicNumber} (0x{romFSHeader.MagicNumber:X})"); + builder.AppendLine($" Master hash size: {romFSHeader.MasterHashSize} (0x{romFSHeader.MasterHashSize:X})"); + builder.AppendLine($" Level 1 logical offset: {romFSHeader.Level1LogicalOffset} (0x{romFSHeader.Level1LogicalOffset:X})"); + builder.AppendLine($" Level 1 hashdata size: {romFSHeader.Level1HashdataSize} (0x{romFSHeader.Level1HashdataSize:X})"); + builder.AppendLine($" Level 1 block size: {romFSHeader.Level1BlockSizeLog2} (0x{romFSHeader.Level1BlockSizeLog2:X})"); + builder.AppendLine($" Reserved 1: {(romFSHeader.Reserved1 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved1).Replace('-', ' '))}"); + builder.AppendLine($" Level 2 logical offset: {romFSHeader.Level2LogicalOffset} (0x{romFSHeader.Level2LogicalOffset:X})"); + builder.AppendLine($" Level 2 hashdata size: {romFSHeader.Level2HashdataSize} (0x{romFSHeader.Level2HashdataSize:X})"); + builder.AppendLine($" Level 2 block size: {romFSHeader.Level2BlockSizeLog2} (0x{romFSHeader.Level2BlockSizeLog2:X})"); + builder.AppendLine($" Reserved 2: {(romFSHeader.Reserved2 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved2).Replace('-', ' '))}"); + builder.AppendLine($" Level 3 logical offset: {romFSHeader.Level3LogicalOffset} (0x{romFSHeader.Level3LogicalOffset:X})"); + builder.AppendLine($" Level 3 hashdata size: {romFSHeader.Level3HashdataSize} (0x{romFSHeader.Level3HashdataSize:X})"); + builder.AppendLine($" Level 3 block size: {romFSHeader.Level3BlockSizeLog2} (0x{romFSHeader.Level3BlockSizeLog2:X})"); + builder.AppendLine($" Reserved 3: {(romFSHeader.Reserved3 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' '))}"); + builder.AppendLine($" Reserved 4: {(romFSHeader.Reserved4 == null ? "[NULL]" : BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' '))}"); + builder.AppendLine($" Optional info size: {romFSHeader.OptionalInfoSize} (0x{romFSHeader.OptionalInfoSize:X})"); } } } diff --git a/BinaryObjectScanner.Wrappers/NCF.cs b/BinaryObjectScanner.Wrappers/NCF.cs index f350178c..ffe3df2a 100644 --- a/BinaryObjectScanner.Wrappers/NCF.cs +++ b/BinaryObjectScanner.Wrappers/NCF.cs @@ -18,83 +18,183 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint Dummy0 => _model.Header.Dummy0; +#else + public uint? Dummy0 => _model.Header?.Dummy0; +#endif /// +#if NET48 public uint MajorVersion => _model.Header.MajorVersion; +#else + public uint? MajorVersion => _model.Header?.MajorVersion; +#endif /// +#if NET48 public uint MinorVersion => _model.Header.MinorVersion; +#else + public uint? MinorVersion => _model.Header?.MinorVersion; +#endif /// +#if NET48 public uint CacheID => _model.Header.CacheID; +#else + public uint? CacheID => _model.Header?.CacheID; +#endif /// +#if NET48 public uint LastVersionPlayed => _model.Header.LastVersionPlayed; +#else + public uint? LastVersionPlayed => _model.Header?.LastVersionPlayed; +#endif /// +#if NET48 public uint Dummy1 => _model.Header.Dummy1; +#else + public uint? Dummy1 => _model.Header?.Dummy1; +#endif /// +#if NET48 public uint Dummy2 => _model.Header.Dummy2; +#else + public uint? Dummy2 => _model.Header?.Dummy2; +#endif /// +#if NET48 public uint FileSize => _model.Header.FileSize; +#else + public uint? FileSize => _model.Header?.FileSize; +#endif /// +#if NET48 public uint BlockSize => _model.Header.BlockSize; +#else + public uint? BlockSize => _model.Header?.BlockSize; +#endif /// +#if NET48 public uint BlockCount => _model.Header.BlockCount; +#else + public uint? BlockCount => _model.Header?.BlockCount; +#endif /// +#if NET48 public uint Dummy3 => _model.Header.Dummy3; +#else + public uint? Dummy3 => _model.Header?.Dummy3; +#endif #endregion #region Directory Header /// +#if NET48 public uint DH_Dummy0 => _model.DirectoryHeader.Dummy0; +#else + public uint? DH_Dummy0 => _model.DirectoryHeader?.Dummy0; +#endif /// +#if NET48 public uint DH_CacheID => _model.DirectoryHeader.CacheID; +#else + public uint? DH_CacheID => _model.DirectoryHeader?.CacheID; +#endif /// +#if NET48 public uint DH_LastVersionPlayed => _model.DirectoryHeader.LastVersionPlayed; +#else + public uint? DH_LastVersionPlayed => _model.DirectoryHeader?.LastVersionPlayed; +#endif /// +#if NET48 public uint DH_ItemCount => _model.DirectoryHeader.ItemCount; +#else + public uint? DH_ItemCount => _model.DirectoryHeader?.ItemCount; +#endif /// +#if NET48 public uint DH_FileCount => _model.DirectoryHeader.FileCount; +#else + public uint? DH_FileCount => _model.DirectoryHeader?.FileCount; +#endif /// +#if NET48 public uint DH_ChecksumDataLength => _model.DirectoryHeader.ChecksumDataLength; +#else + public uint? DH_ChecksumDataLength => _model.DirectoryHeader?.ChecksumDataLength; +#endif /// +#if NET48 public uint DH_DirectorySize => _model.DirectoryHeader.DirectorySize; +#else + public uint? DH_DirectorySize => _model.DirectoryHeader?.DirectorySize; +#endif /// +#if NET48 public uint DH_NameSize => _model.DirectoryHeader.NameSize; +#else + public uint? DH_NameSize => _model.DirectoryHeader?.NameSize; +#endif /// +#if NET48 public uint DH_Info1Count => _model.DirectoryHeader.Info1Count; +#else + public uint? DH_Info1Count => _model.DirectoryHeader?.Info1Count; +#endif /// +#if NET48 public uint DH_CopyCount => _model.DirectoryHeader.CopyCount; +#else + public uint? DH_CopyCount => _model.DirectoryHeader?.CopyCount; +#endif /// +#if NET48 public uint DH_LocalCount => _model.DirectoryHeader.LocalCount; +#else + public uint? DH_LocalCount => _model.DirectoryHeader?.LocalCount; +#endif /// +#if NET48 public uint DH_Dummy1 => _model.DirectoryHeader.Dummy1; +#else + public uint? DH_Dummy1 => _model.DirectoryHeader?.Dummy1; +#endif /// +#if NET48 public uint DH_Dummy2 => _model.DirectoryHeader.Dummy2; +#else + public uint? DH_Dummy2 => _model.DirectoryHeader?.Dummy2; +#endif /// +#if NET48 public uint DH_Checksum => _model.DirectoryHeader.Checksum; +#else + public uint? DH_Checksum => _model.DirectoryHeader?.Checksum; +#endif #endregion @@ -167,10 +267,18 @@ namespace BinaryObjectScanner.Wrappers #region Unknown Header /// +#if NET48 public uint UH_Dummy0 => _model.UnknownHeader.Dummy0; +#else + public uint? UH_Dummy0 => _model.UnknownHeader?.Dummy0; +#endif /// +#if NET48 public uint UH_Dummy1 => _model.UnknownHeader.Dummy1; +#else + public uint? UH_Dummy1 => _model.UnknownHeader?.Dummy1; +#endif #endregion @@ -188,26 +296,50 @@ namespace BinaryObjectScanner.Wrappers #region Checksum Header /// +#if NET48 public uint CH_Dummy0 => _model.ChecksumHeader.Dummy0; +#else + public uint? CH_Dummy0 => _model.ChecksumHeader?.Dummy0; +#endif /// +#if NET48 public uint CH_ChecksumSize => _model.ChecksumHeader.ChecksumSize; +#else + public uint? CH_ChecksumSize => _model.ChecksumHeader?.ChecksumSize; +#endif #endregion #region Checksum Map Header /// +#if NET48 public uint CMH_Dummy0 => _model.ChecksumMapHeader.Dummy0; +#else + public uint? CMH_Dummy0 => _model.ChecksumMapHeader?.Dummy0; +#endif /// +#if NET48 public uint CMH_Dummy1 => _model.ChecksumMapHeader.Dummy1; +#else + public uint? CMH_Dummy1 => _model.ChecksumMapHeader?.Dummy1; +#endif /// +#if NET48 public uint CMH_ItemCount => _model.ChecksumMapHeader.ItemCount; +#else + public uint? CMH_ItemCount => _model.ChecksumMapHeader?.ItemCount; +#endif /// +#if NET48 public uint CMH_ChecksumCount => _model.ChecksumMapHeader.ChecksumCount; +#else + public uint? CMH_ChecksumCount => _model.ChecksumMapHeader?.ChecksumCount; +#endif #endregion @@ -414,6 +546,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryEntry = DirectoryEntries[i]; builder.AppendLine($" Directory Entry {i}"); + if (directoryEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -445,6 +583,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryInfoEntry = DirectoryInfo1Entries[i]; builder.AppendLine($" Directory Info 1 Entry {i}"); + if (directoryInfoEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } @@ -469,6 +613,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryInfoEntry = DirectoryInfo2Entries[i]; builder.AppendLine($" Directory Info 2 Entry {i}"); + if (directoryInfoEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Dummy 0: {directoryInfoEntry.Dummy0} (0x{directoryInfoEntry.Dummy0:X})"); } } @@ -482,7 +632,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintDirectoryCopyEntries(StringBuilder builder) { builder.AppendLine(" Directory Copy Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (DirectoryCopyEntries == null || DirectoryCopyEntries.Length == 0) { builder.AppendLine(" No directory copy entries"); @@ -493,6 +643,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryCopyEntry = DirectoryCopyEntries[i]; builder.AppendLine($" Directory Copy Entry {i}"); + if (directoryCopyEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Directory index: {directoryCopyEntry.DirectoryIndex} (0x{directoryCopyEntry.DirectoryIndex:X})"); } } @@ -506,7 +662,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintDirectoryLocalEntries(StringBuilder builder) { builder.AppendLine(" Directory Local Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (DirectoryLocalEntries == null || DirectoryLocalEntries.Length == 0) { builder.AppendLine(" No directory local entries"); @@ -517,6 +673,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryLocalEntry = DirectoryLocalEntries[i]; builder.AppendLine($" Directory Local Entry {i}"); + if (directoryLocalEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Directory index: {directoryLocalEntry.DirectoryIndex} (0x{directoryLocalEntry.DirectoryIndex:X})"); } } @@ -543,7 +705,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintUnknownEntries(StringBuilder builder) { builder.AppendLine(" Unknown Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (UnknownEntries == null || UnknownEntries.Length == 0) { builder.AppendLine(" No unknown entries"); @@ -554,6 +716,12 @@ namespace BinaryObjectScanner.Wrappers { var unknownEntry = UnknownEntries[i]; builder.AppendLine($" Unknown Entry {i}"); + if (unknownEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Dummy 0: {unknownEntry.Dummy0} (0x{unknownEntry.Dummy0:X})"); } } @@ -595,7 +763,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintChecksumMapEntries(StringBuilder builder) { builder.AppendLine(" Checksum Map Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (ChecksumMapEntries == null || ChecksumMapEntries.Length == 0) { builder.AppendLine(" No checksum map entries"); @@ -606,6 +774,12 @@ namespace BinaryObjectScanner.Wrappers { var checksumMapEntry = ChecksumMapEntries[i]; builder.AppendLine($" Checksum Map Entry {i}"); + if (checksumMapEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Checksum count: {checksumMapEntry.ChecksumCount} (0x{checksumMapEntry.ChecksumCount:X})"); builder.AppendLine($" First checksum index: {checksumMapEntry.FirstChecksumIndex} (0x{checksumMapEntry.FirstChecksumIndex:X})"); } @@ -620,7 +794,7 @@ namespace BinaryObjectScanner.Wrappers private void PrintChecksumEntries(StringBuilder builder) { builder.AppendLine(" Checksum Entries Information:"); - builder.AppendLine(value: " -------------------------"); + builder.AppendLine(" -------------------------"); if (ChecksumEntries == null || ChecksumEntries.Length == 0) { builder.AppendLine(" No checksum entries"); @@ -631,6 +805,12 @@ namespace BinaryObjectScanner.Wrappers { var checksumEntry = ChecksumEntries[i]; builder.AppendLine($" Checksum Entry {i}"); + if (checksumEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Checksum: {checksumEntry.Checksum} (0x{checksumEntry.Checksum:X})"); } } diff --git a/BinaryObjectScanner.Wrappers/NewExecutable.cs b/BinaryObjectScanner.Wrappers/NewExecutable.cs index b35c8f2f..c4154713 100644 --- a/BinaryObjectScanner.Wrappers/NewExecutable.cs +++ b/BinaryObjectScanner.Wrappers/NewExecutable.cs @@ -25,47 +25,99 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Stub_Magic => _model.Stub.Header.Magic; #else - public string? Stub_Magic => _model.Stub.Header.Magic; + public string? Stub_Magic => _model.Stub?.Header?.Magic; #endif /// +#if NET48 public ushort Stub_LastPageBytes => _model.Stub.Header.LastPageBytes; +#else + public ushort? Stub_LastPageBytes => _model.Stub?.Header?.LastPageBytes; +#endif /// +#if NET48 public ushort Stub_Pages => _model.Stub.Header.Pages; +#else + public ushort? Stub_Pages => _model.Stub?.Header?.Pages; +#endif /// +#if NET48 public ushort Stub_RelocationItems => _model.Stub.Header.RelocationItems; +#else + public ushort? Stub_RelocationItems => _model.Stub?.Header?.RelocationItems; +#endif /// +#if NET48 public ushort Stub_HeaderParagraphSize => _model.Stub.Header.HeaderParagraphSize; +#else + public ushort? Stub_HeaderParagraphSize => _model.Stub?.Header?.HeaderParagraphSize; +#endif /// +#if NET48 public ushort Stub_MinimumExtraParagraphs => _model.Stub.Header.MinimumExtraParagraphs; +#else + public ushort? Stub_MinimumExtraParagraphs => _model.Stub?.Header?.MinimumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_MaximumExtraParagraphs => _model.Stub.Header.MaximumExtraParagraphs; +#else + public ushort? Stub_MaximumExtraParagraphs => _model.Stub?.Header?.MaximumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_InitialSSValue => _model.Stub.Header.InitialSSValue; +#else + public ushort? Stub_InitialSSValue => _model.Stub?.Header?.InitialSSValue; +#endif /// +#if NET48 public ushort Stub_InitialSPValue => _model.Stub.Header.InitialSPValue; +#else + public ushort? Stub_InitialSPValue => _model.Stub?.Header?.InitialSPValue; +#endif /// +#if NET48 public ushort Stub_Checksum => _model.Stub.Header.Checksum; +#else + public ushort? Stub_Checksum => _model.Stub?.Header?.Checksum; +#endif /// +#if NET48 public ushort Stub_InitialIPValue => _model.Stub.Header.InitialIPValue; +#else + public ushort? Stub_InitialIPValue => _model.Stub?.Header?.InitialIPValue; +#endif /// +#if NET48 public ushort Stub_InitialCSValue => _model.Stub.Header.InitialCSValue; +#else + public ushort? Stub_InitialCSValue => _model.Stub?.Header?.InitialCSValue; +#endif /// +#if NET48 public ushort Stub_RelocationTableAddr => _model.Stub.Header.RelocationTableAddr; +#else + public ushort? Stub_RelocationTableAddr => _model.Stub?.Header?.RelocationTableAddr; +#endif /// +#if NET48 public ushort Stub_OverlayNumber => _model.Stub.Header.OverlayNumber; +#else + public ushort? Stub_OverlayNumber => _model.Stub?.Header?.OverlayNumber; +#endif #endregion @@ -75,24 +127,36 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public ushort[] Stub_Reserved1 => _model.Stub.Header.Reserved1; #else - public ushort[]? Stub_Reserved1 => _model.Stub.Header.Reserved1; + public ushort[]? Stub_Reserved1 => _model.Stub?.Header?.Reserved1; #endif /// +#if NET48 public ushort Stub_OEMIdentifier => _model.Stub.Header.OEMIdentifier; +#else + public ushort? Stub_OEMIdentifier => _model.Stub?.Header?.OEMIdentifier; +#endif /// +#if NET48 public ushort Stub_OEMInformation => _model.Stub.Header.OEMInformation; +#else + public ushort? Stub_OEMInformation => _model.Stub?.Header?.OEMInformation; +#endif /// #if NET48 public ushort[] Stub_Reserved2 => _model.Stub.Header.Reserved2; #else - public ushort[]? Stub_Reserved2 => _model.Stub.Header.Reserved2; + public ushort[]? Stub_Reserved2 => _model.Stub?.Header?.Reserved2; #endif /// +#if NET48 public uint Stub_NewExeHeaderAddr => _model.Stub.Header.NewExeHeaderAddr; +#else + public uint? Stub_NewExeHeaderAddr => _model.Stub?.Header?.NewExeHeaderAddr; +#endif #endregion @@ -104,98 +168,218 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Magic => _model.Header.Magic; #else - public string? Magic => _model.Header.Magic; + public string? Magic => _model.Header?.Magic; #endif /// +#if NET48 public byte LinkerVersion => _model.Header.LinkerVersion; +#else + public byte? LinkerVersion => _model.Header?.LinkerVersion; +#endif /// +#if NET48 public byte LinkerRevision => _model.Header.LinkerRevision; +#else + public byte? LinkerRevision => _model.Header?.LinkerRevision; +#endif /// +#if NET48 public ushort EntryTableOffset => _model.Header.EntryTableOffset; +#else + public ushort? EntryTableOffset => _model.Header?.EntryTableOffset; +#endif /// +#if NET48 public ushort EntryTableSize => _model.Header.EntryTableSize; +#else + public ushort? EntryTableSize => _model.Header?.EntryTableSize; +#endif /// +#if NET48 public uint CrcChecksum => _model.Header.CrcChecksum; +#else + public uint? CrcChecksum => _model.Header?.CrcChecksum; +#endif /// +#if NET48 public SabreTools.Models.NewExecutable.HeaderFlag FlagWord => _model.Header.FlagWord; +#else + public SabreTools.Models.NewExecutable.HeaderFlag? FlagWord => _model.Header?.FlagWord; +#endif /// +#if NET48 public ushort AutomaticDataSegmentNumber => _model.Header.AutomaticDataSegmentNumber; +#else + public ushort? AutomaticDataSegmentNumber => _model.Header?.AutomaticDataSegmentNumber; +#endif /// +#if NET48 public ushort InitialHeapAlloc => _model.Header.InitialHeapAlloc; +#else + public ushort? InitialHeapAlloc => _model.Header?.InitialHeapAlloc; +#endif /// +#if NET48 public ushort InitialStackAlloc => _model.Header.InitialStackAlloc; +#else + public ushort? InitialStackAlloc => _model.Header?.InitialStackAlloc; +#endif /// +#if NET48 public uint InitialCSIPSetting => _model.Header.InitialCSIPSetting; +#else + public uint? InitialCSIPSetting => _model.Header?.InitialCSIPSetting; +#endif /// +#if NET48 public uint InitialSSSPSetting => _model.Header.InitialSSSPSetting; +#else + public uint? InitialSSSPSetting => _model.Header?.InitialSSSPSetting; +#endif /// +#if NET48 public ushort FileSegmentCount => _model.Header.FileSegmentCount; +#else + public ushort? FileSegmentCount => _model.Header?.FileSegmentCount; +#endif /// +#if NET48 public ushort ModuleReferenceTableSize => _model.Header.ModuleReferenceTableSize; +#else + public ushort? ModuleReferenceTableSize => _model.Header?.ModuleReferenceTableSize; +#endif /// +#if NET48 public ushort NonResidentNameTableSize => _model.Header.NonResidentNameTableSize; +#else + public ushort? NonResidentNameTableSize => _model.Header?.NonResidentNameTableSize; +#endif /// +#if NET48 public ushort SegmentTableOffset => _model.Header.SegmentTableOffset; +#else + public ushort? SegmentTableOffset => _model.Header?.SegmentTableOffset; +#endif /// +#if NET48 public ushort ResourceTableOffset => _model.Header.ResourceTableOffset; +#else + public ushort? ResourceTableOffset => _model.Header?.ResourceTableOffset; +#endif /// +#if NET48 public ushort ResidentNameTableOffset => _model.Header.ResidentNameTableOffset; +#else + public ushort? ResidentNameTableOffset => _model.Header?.ResidentNameTableOffset; +#endif /// +#if NET48 public ushort ModuleReferenceTableOffset => _model.Header.ModuleReferenceTableOffset; +#else + public ushort? ModuleReferenceTableOffset => _model.Header?.ModuleReferenceTableOffset; +#endif /// +#if NET48 public ushort ImportedNamesTableOffset => _model.Header.ImportedNamesTableOffset; +#else + public ushort? ImportedNamesTableOffset => _model.Header?.ImportedNamesTableOffset; +#endif /// +#if NET48 public uint NonResidentNamesTableOffset => _model.Header.NonResidentNamesTableOffset; +#else + public uint? NonResidentNamesTableOffset => _model.Header?.NonResidentNamesTableOffset; +#endif /// +#if NET48 public ushort MovableEntriesCount => _model.Header.MovableEntriesCount; +#else + public ushort? MovableEntriesCount => _model.Header?.MovableEntriesCount; +#endif /// +#if NET48 public ushort SegmentAlignmentShiftCount => _model.Header.SegmentAlignmentShiftCount; +#else + public ushort? SegmentAlignmentShiftCount => _model.Header?.SegmentAlignmentShiftCount; +#endif /// +#if NET48 public ushort ResourceEntriesCount => _model.Header.ResourceEntriesCount; +#else + public ushort? ResourceEntriesCount => _model.Header?.ResourceEntriesCount; +#endif /// +#if NET48 public SabreTools.Models.NewExecutable.OperatingSystem TargetOperatingSystem => _model.Header.TargetOperatingSystem; +#else + public SabreTools.Models.NewExecutable.OperatingSystem? TargetOperatingSystem => _model.Header?.TargetOperatingSystem; +#endif /// +#if NET48 public SabreTools.Models.NewExecutable.OS2Flag AdditionalFlags => _model.Header.AdditionalFlags; +#else + public SabreTools.Models.NewExecutable.OS2Flag? AdditionalFlags => _model.Header?.AdditionalFlags; +#endif /// +#if NET48 public ushort ReturnThunkOffset => _model.Header.ReturnThunkOffset; +#else + public ushort? ReturnThunkOffset => _model.Header?.ReturnThunkOffset; +#endif /// +#if NET48 public ushort SegmentReferenceThunkOffset => _model.Header.SegmentReferenceThunkOffset; +#else + public ushort? SegmentReferenceThunkOffset => _model.Header?.SegmentReferenceThunkOffset; +#endif /// +#if NET48 public ushort MinCodeSwapAreaSize => _model.Header.MinCodeSwapAreaSize; +#else + public ushort? MinCodeSwapAreaSize => _model.Header?.MinCodeSwapAreaSize; +#endif /// +#if NET48 public byte WindowsSDKRevision => _model.Header.WindowsSDKRevision; +#else + public byte? WindowsSDKRevision => _model.Header?.WindowsSDKRevision; +#endif /// +#if NET48 public byte WindowsSDKVersion => _model.Header.WindowsSDKVersion; +#else + public byte? WindowsSDKVersion => _model.Header?.WindowsSDKVersion; +#endif #endregion @@ -461,7 +645,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Segment Table Information:"); builder.AppendLine(" -------------------------"); - if (FileSegmentCount == 0 || SegmentTable.Length == 0) + if (FileSegmentCount == 0 || SegmentTable == null || SegmentTable.Length == 0) { builder.AppendLine(" No segment table items"); } @@ -471,6 +655,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = SegmentTable[i]; builder.AppendLine($" Segment Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -488,8 +678,14 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Resource Table Information:"); builder.AppendLine(" -------------------------"); + if (ResourceTable == null) + { + builder.AppendLine(" No resource table"); + return; + } + builder.AppendLine($" Alignment shift count: {ResourceTable.AlignmentShiftCount} (0x{ResourceTable.AlignmentShiftCount:X})"); - if (ResourceEntriesCount == 0 || ResourceTable.ResourceTypes.Length == 0) + if (ResourceEntriesCount == 0 || ResourceTable.ResourceTypes == null || ResourceTable.ResourceTypes.Length == 0) { builder.AppendLine(" No resource table items"); } @@ -500,11 +696,17 @@ namespace BinaryObjectScanner.Wrappers // TODO: If not integer type, print out name var entry = ResourceTable.ResourceTypes[i]; builder.AppendLine($" Resource Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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) + if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0) { builder.AppendLine(" No resource items"); } @@ -515,6 +717,12 @@ namespace BinaryObjectScanner.Wrappers // TODO: If not integer type, print out name var resource = entry.Resources[j]; builder.AppendLine($" Resource Entry {i}"); + if (resource == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -525,7 +733,7 @@ namespace BinaryObjectScanner.Wrappers } } - if (ResourceTable.TypeAndNameStrings.Count == 0) + if (ResourceTable.TypeAndNameStrings == null || ResourceTable.TypeAndNameStrings.Count == 0) { builder.AppendLine(" No resource table type/name strings"); } @@ -534,6 +742,13 @@ namespace BinaryObjectScanner.Wrappers foreach (var typeAndNameString in ResourceTable.TypeAndNameStrings) { builder.AppendLine($" Resource Type/Name Offset {typeAndNameString.Key}"); +#if NET6_0_OR_GREATER + if (typeAndNameString.Value == null) + { + builder.AppendLine(" [NULL]"); + continue; + } +#endif 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]")}"); } @@ -549,7 +764,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Resident-Name Table Information:"); builder.AppendLine(" -------------------------"); - if (ResidentNameTableOffset == 0 || ResidentNameTable.Length == 0) + if (ResidentNameTableOffset == 0 || ResidentNameTable == null || ResidentNameTable.Length == 0) { builder.AppendLine(" No resident-name table items"); } @@ -559,6 +774,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = ResidentNameTable[i]; builder.AppendLine($" Resident-Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -575,7 +796,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Module-Reference Table Information:"); builder.AppendLine(" -------------------------"); - if (ModuleReferenceTableSize == 0 || ModuleReferenceTable.Length == 0) + if (ModuleReferenceTableSize == 0 || ModuleReferenceTable == null || ModuleReferenceTable.Length == 0) { builder.AppendLine(" No module-reference table items"); } @@ -586,6 +807,12 @@ namespace BinaryObjectScanner.Wrappers // TODO: Read the imported names table and print value here var entry = ModuleReferenceTable[i]; builder.AppendLine($" Module-Reference Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + Stub_NewExeHeaderAddr + ImportedNamesTableOffset})"); } } @@ -600,7 +827,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Imported-Name Table Information:"); builder.AppendLine(" -------------------------"); - if (ImportedNamesTableOffset == 0 || ImportedNameTable.Count == 0) + if (ImportedNamesTableOffset == 0 || ImportedNameTable == null || ImportedNameTable.Count == 0) { builder.AppendLine(" No imported-name table items"); } @@ -609,6 +836,13 @@ namespace BinaryObjectScanner.Wrappers foreach (var entry in ImportedNameTable) { builder.AppendLine($" Imported-Name Table at Offset {entry.Key}"); +#if NET6_0_OR_GREATER + if (entry.Value == null) + { + builder.AppendLine(" [NULL]"); + continue; + } +#endif 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]")}"); } @@ -624,7 +858,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Entry Table Information:"); builder.AppendLine(" -------------------------"); - if (EntryTableSize == 0 || EntryTable.Length == 0) + if (EntryTableSize == 0 || EntryTable == null || EntryTable.Length == 0) { builder.AppendLine(" No entry table items"); } @@ -634,6 +868,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = EntryTable[i]; builder.AppendLine($" Entry Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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()) @@ -662,7 +902,7 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Nonresident-Name Table Information:"); builder.AppendLine(" -------------------------"); - if (NonResidentNameTableSize == 0 || NonResidentNameTable.Length == 0) + if (NonResidentNameTableSize == 0 || NonResidentNameTable == null || NonResidentNameTable.Length == 0) { builder.AppendLine(" No nonresident-name table items"); } @@ -672,6 +912,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = NonResidentNameTable[i]; builder.AppendLine($" Nonresident-Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -714,11 +960,19 @@ namespace BinaryObjectScanner.Wrappers switch (_dataSource) { case DataSource.ByteArray: +#if NET48 length = _byteArrayData.Length - _byteArrayOffset; +#else + length = _byteArrayData!.Length - _byteArrayOffset; +#endif break; case DataSource.Stream: +#if NET48 length = (int)_streamData.Length; +#else + length = (int)_streamData!.Length; +#endif break; } } diff --git a/BinaryObjectScanner.Wrappers/Nitro.cs b/BinaryObjectScanner.Wrappers/Nitro.cs index f768c657..308b9453 100644 --- a/BinaryObjectScanner.Wrappers/Nitro.cs +++ b/BinaryObjectScanner.Wrappers/Nitro.cs @@ -21,151 +21,287 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string GameTitle => _model.CommonHeader.GameTitle; #else - public string? GameTitle => _model.CommonHeader.GameTitle; + public string? GameTitle => _model.CommonHeader?.GameTitle; #endif /// +#if NET48 public uint GameCode => _model.CommonHeader.GameCode; +#else + public uint? GameCode => _model.CommonHeader?.GameCode; +#endif /// #if NET48 public string MakerCode => _model.CommonHeader.MakerCode; #else - public string? MakerCode => _model.CommonHeader.MakerCode; + public string? MakerCode => _model.CommonHeader?.MakerCode; #endif /// +#if NET48 public SabreTools.Models.Nitro.Unitcode UnitCode => _model.CommonHeader.UnitCode; +#else + public SabreTools.Models.Nitro.Unitcode? UnitCode => _model.CommonHeader?.UnitCode; +#endif /// +#if NET48 public byte EncryptionSeedSelect => _model.CommonHeader.EncryptionSeedSelect; +#else + public byte? EncryptionSeedSelect => _model.CommonHeader?.EncryptionSeedSelect; +#endif /// +#if NET48 public byte DeviceCapacity => _model.CommonHeader.DeviceCapacity; +#else + public byte? DeviceCapacity => _model.CommonHeader?.DeviceCapacity; +#endif /// #if NET48 public byte[] Reserved1 => _model.CommonHeader.Reserved1; #else - public byte[]? Reserved1 => _model.CommonHeader.Reserved1; + public byte[]? Reserved1 => _model.CommonHeader?.Reserved1; #endif /// +#if NET48 public ushort GameRevision => _model.CommonHeader.GameRevision; +#else + public ushort? GameRevision => _model.CommonHeader?.GameRevision; +#endif /// +#if NET48 public byte RomVersion => _model.CommonHeader.RomVersion; +#else + public byte? RomVersion => _model.CommonHeader?.RomVersion; +#endif /// +#if NET48 public byte InternalFlags => _model.CommonHeader.InternalFlags; +#else + public byte? InternalFlags => _model.CommonHeader?.InternalFlags; +#endif /// +#if NET48 public uint ARM9RomOffset => _model.CommonHeader.ARM9RomOffset; +#else + public uint? ARM9RomOffset => _model.CommonHeader?.ARM9RomOffset; +#endif /// +#if NET48 public uint ARM9EntryAddress => _model.CommonHeader.ARM9EntryAddress; +#else + public uint? ARM9EntryAddress => _model.CommonHeader?.ARM9EntryAddress; +#endif /// +#if NET48 public uint ARM9LoadAddress => _model.CommonHeader.ARM9LoadAddress; +#else + public uint? ARM9LoadAddress => _model.CommonHeader?.ARM9LoadAddress; +#endif /// +#if NET48 public uint ARM9Size => _model.CommonHeader.ARM9Size; +#else + public uint? ARM9Size => _model.CommonHeader?.ARM9Size; +#endif /// +#if NET48 public uint ARM7RomOffset => _model.CommonHeader.ARM7RomOffset; +#else + public uint? ARM7RomOffset => _model.CommonHeader?.ARM7RomOffset; +#endif /// +#if NET48 public uint ARM7EntryAddress => _model.CommonHeader.ARM7EntryAddress; +#else + public uint? ARM7EntryAddress => _model.CommonHeader?.ARM7EntryAddress; +#endif /// +#if NET48 public uint ARM7LoadAddress => _model.CommonHeader.ARM7LoadAddress; +#else + public uint? ARM7LoadAddress => _model.CommonHeader?.ARM7LoadAddress; +#endif /// +#if NET48 public uint ARM7Size => _model.CommonHeader.ARM7Size; +#else + public uint? ARM7Size => _model.CommonHeader?.ARM7Size; +#endif /// +#if NET48 public uint FileNameTableOffset => _model.CommonHeader.FileNameTableOffset; +#else + public uint? FileNameTableOffset => _model.CommonHeader?.FileNameTableOffset; +#endif /// +#if NET48 public uint FileNameTableLength => _model.CommonHeader.FileNameTableLength; +#else + public uint? FileNameTableLength => _model.CommonHeader?.FileNameTableLength; +#endif /// +#if NET48 public uint FileAllocationTableOffset => _model.CommonHeader.FileAllocationTableOffset; +#else + public uint? FileAllocationTableOffset => _model.CommonHeader?.FileAllocationTableOffset; +#endif /// +#if NET48 public uint FileAllocationTableLength => _model.CommonHeader.FileAllocationTableLength; +#else + public uint? FileAllocationTableLength => _model.CommonHeader?.FileAllocationTableLength; +#endif /// +#if NET48 public uint ARM9OverlayOffset => _model.CommonHeader.ARM9OverlayOffset; +#else + public uint? ARM9OverlayOffset => _model.CommonHeader?.ARM9OverlayOffset; +#endif /// +#if NET48 public uint ARM9OverlayLength => _model.CommonHeader.ARM9OverlayLength; +#else + public uint? ARM9OverlayLength => _model.CommonHeader?.ARM9OverlayLength; +#endif /// +#if NET48 public uint ARM7OverlayOffset => _model.CommonHeader.ARM7OverlayOffset; +#else + public uint? ARM7OverlayOffset => _model.CommonHeader?.ARM7OverlayOffset; +#endif /// +#if NET48 public uint ARM7OverlayLength => _model.CommonHeader.ARM7OverlayLength; +#else + public uint? ARM7OverlayLength => _model.CommonHeader?.ARM7OverlayLength; +#endif /// +#if NET48 public uint NormalCardControlRegisterSettings => _model.CommonHeader.NormalCardControlRegisterSettings; +#else + public uint? NormalCardControlRegisterSettings => _model.CommonHeader?.NormalCardControlRegisterSettings; +#endif /// +#if NET48 public uint SecureCardControlRegisterSettings => _model.CommonHeader.SecureCardControlRegisterSettings; +#else + public uint? SecureCardControlRegisterSettings => _model.CommonHeader?.SecureCardControlRegisterSettings; +#endif /// +#if NET48 public uint IconBannerOffset => _model.CommonHeader.IconBannerOffset; +#else + public uint? IconBannerOffset => _model.CommonHeader?.IconBannerOffset; +#endif /// +#if NET48 public ushort SecureAreaCRC => _model.CommonHeader.SecureAreaCRC; +#else + public ushort? SecureAreaCRC => _model.CommonHeader?.SecureAreaCRC; +#endif /// +#if NET48 public ushort SecureTransferTimeout => _model.CommonHeader.SecureTransferTimeout; +#else + public ushort? SecureTransferTimeout => _model.CommonHeader?.SecureTransferTimeout; +#endif /// +#if NET48 public uint ARM9Autoload => _model.CommonHeader.ARM9Autoload; +#else + public uint? ARM9Autoload => _model.CommonHeader?.ARM9Autoload; +#endif /// +#if NET48 public uint ARM7Autoload => _model.CommonHeader.ARM7Autoload; +#else + public uint? ARM7Autoload => _model.CommonHeader?.ARM7Autoload; +#endif /// #if NET48 public byte[] SecureDisable => _model.CommonHeader.SecureDisable; #else - public byte[]? SecureDisable => _model.CommonHeader.SecureDisable; + public byte[]? SecureDisable => _model.CommonHeader?.SecureDisable; #endif /// +#if NET48 public uint NTRRegionRomSize => _model.CommonHeader.NTRRegionRomSize; +#else + public uint? NTRRegionRomSize => _model.CommonHeader?.NTRRegionRomSize; +#endif /// +#if NET48 public uint HeaderSize => _model.CommonHeader.HeaderSize; +#else + public uint? HeaderSize => _model.CommonHeader?.HeaderSize; +#endif /// #if NET48 public byte[] Reserved2 => _model.CommonHeader.Reserved2; #else - public byte[]? Reserved2 => _model.CommonHeader.Reserved2; + public byte[]? Reserved2 => _model.CommonHeader?.Reserved2; #endif /// #if NET48 public byte[] NintendoLogo => _model.CommonHeader.NintendoLogo; #else - public byte[]? NintendoLogo => _model.CommonHeader.NintendoLogo; + public byte[]? NintendoLogo => _model.CommonHeader?.NintendoLogo; #endif /// +#if NET48 public ushort NintendoLogoCRC => _model.CommonHeader.NintendoLogoCRC; +#else + public ushort? NintendoLogoCRC => _model.CommonHeader?.NintendoLogoCRC; +#endif /// +#if NET48 public ushort HeaderCRC => _model.CommonHeader.HeaderCRC; +#else + public ushort? HeaderCRC => _model.CommonHeader?.HeaderCRC; +#endif /// #if NET48 public byte[] DebuggerReserved => _model.CommonHeader.DebuggerReserved; #else - public byte[]? DebuggerReserved => _model.CommonHeader.DebuggerReserved; + public byte[]? DebuggerReserved => _model.CommonHeader?.DebuggerReserved; #endif #endregion @@ -403,14 +539,14 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public SabreTools.Models.Nitro.FolderAllocationTableEntry[] FolderAllocationTable => _model.NameTable.FolderAllocationTable; #else - public SabreTools.Models.Nitro.FolderAllocationTableEntry?[]? FolderAllocationTable => _model.NameTable.FolderAllocationTable; + public SabreTools.Models.Nitro.FolderAllocationTableEntry?[]? FolderAllocationTable => _model.NameTable?.FolderAllocationTable; #endif /// #if NET48 public SabreTools.Models.Nitro.NameListEntry[] NameList => _model.NameTable.NameList; #else - public SabreTools.Models.Nitro.NameListEntry?[]? NameList => _model.NameTable.NameList; + public SabreTools.Models.Nitro.NameListEntry?[]? NameList => _model.NameTable?.NameList; #endif #endregion @@ -689,6 +825,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = FolderAllocationTable[i]; builder.AppendLine($" Folder Allocation Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); builder.AppendLine($" First file index: {entry.FirstFileIndex} (0x{entry.FirstFileIndex:X})"); if (entry.Unknown == 0xF0) @@ -724,6 +866,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = NameList[i]; builder.AppendLine($" Name List Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Folder: {entry.Folder} (0x{entry.Folder:X})"); builder.AppendLine($" Name: {entry.Name ?? "[NULL]"}"); if (entry.Folder) @@ -751,6 +899,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = FileAllocationTable[i]; builder.AppendLine($" File Allocation Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Start offset: {entry.StartOffset} (0x{entry.StartOffset:X})"); builder.AppendLine($" End offset: {entry.EndOffset} (0x{entry.EndOffset:X})"); } diff --git a/BinaryObjectScanner.Wrappers/PAK.cs b/BinaryObjectScanner.Wrappers/PAK.cs index 6dad1af2..d0cf45d1 100644 --- a/BinaryObjectScanner.Wrappers/PAK.cs +++ b/BinaryObjectScanner.Wrappers/PAK.cs @@ -20,14 +20,22 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public uint DirectoryOffset => _model.Header.DirectoryOffset; +#else + public uint? DirectoryOffset => _model.Header?.DirectoryOffset; +#endif /// +#if NET48 public uint DirectoryLength => _model.Header.DirectoryLength; +#else + public uint? DirectoryLength => _model.Header?.DirectoryLength; +#endif #endregion @@ -179,6 +187,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryItem = DirectoryItems[i]; builder.AppendLine($" Directory Item {i}"); + if (directoryItem == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/PFF.cs b/BinaryObjectScanner.Wrappers/PFF.cs index af4eda5f..ce3beafd 100644 --- a/BinaryObjectScanner.Wrappers/PFF.cs +++ b/BinaryObjectScanner.Wrappers/PFF.cs @@ -17,23 +17,39 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint HeaderSize => _model.Header.HeaderSize; +#else + public uint? HeaderSize => _model.Header?.HeaderSize; +#endif /// #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public uint NumberOfFiles => _model.Header.NumberOfFiles; +#else + public uint? NumberOfFiles => _model.Header?.NumberOfFiles; +#endif /// +#if NET48 public uint FileSegmentSize => _model.Header.FileSegmentSize; +#else + public uint? FileSegmentSize => _model.Header?.FileSegmentSize; +#endif /// +#if NET48 public uint FileListOffset => _model.Header.FileListOffset; +#else + public uint? FileListOffset => _model.Header?.FileListOffset; +#endif #endregion @@ -51,16 +67,24 @@ namespace BinaryObjectScanner.Wrappers #region Footer /// +#if NET48 public uint SystemIP => _model.Footer.SystemIP; +#else + public uint? SystemIP => _model.Footer?.SystemIP; +#endif /// +#if NET48 public uint Reserved => _model.Footer.Reserved; +#else + public uint? Reserved => _model.Footer?.Reserved; +#endif /// #if NET48 public string KingTag => _model.Footer.KingTag; #else - public string? KingTag => _model.Footer.KingTag; + public string? KingTag => _model.Footer?.KingTag; #endif #endregion @@ -186,6 +210,8 @@ namespace BinaryObjectScanner.Wrappers // Get the segment information var file = Segments[index]; + if (file == null) + return false; // Get the read index and length int offset = (int)file.FileLocation; @@ -275,6 +301,12 @@ namespace BinaryObjectScanner.Wrappers { var segment = Segments[i]; builder.AppendLine($" Segment {i}"); + if (segment == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Deleted: {segment.Deleted} (0x{segment.Deleted:X})"); builder.AppendLine($" File location: {segment.FileLocation} (0x{segment.FileLocation:X})"); builder.AppendLine($" File size: {segment.FileSize} (0x{segment.FileSize:X})"); diff --git a/BinaryObjectScanner.Wrappers/PlayJAudioFile.cs b/BinaryObjectScanner.Wrappers/PlayJAudioFile.cs index 80ee916f..028a5bcc 100644 --- a/BinaryObjectScanner.Wrappers/PlayJAudioFile.cs +++ b/BinaryObjectScanner.Wrappers/PlayJAudioFile.cs @@ -18,10 +18,18 @@ namespace BinaryObjectScanner.Wrappers #region Audio Header /// +#if NET48 public uint Signature => _model.Header.Signature; +#else + public uint? Signature => _model.Header?.Signature; +#endif /// +#if NET48 public uint Version => _model.Header.Version; +#else + public uint? Version => _model.Header?.Version; +#endif #region V1 Only @@ -131,73 +139,101 @@ namespace BinaryObjectScanner.Wrappers #endregion /// +#if NET48 public ushort TrackLength => _model.Header.TrackLength; +#else + public ushort? TrackLength => _model.Header?.TrackLength; +#endif /// #if NET48 public string Track => _model.Header.Track; #else - public string? Track => _model.Header.Track; + public string? Track => _model.Header?.Track; #endif /// +#if NET48 public ushort ArtistLength => _model.Header.ArtistLength; +#else + public ushort? ArtistLength => _model.Header?.ArtistLength; +#endif /// #if NET48 public string Artist => _model.Header.Artist; #else - public string? Artist => _model.Header.Artist; + public string? Artist => _model.Header?.Artist; #endif /// +#if NET48 public ushort AlbumLength => _model.Header.AlbumLength; +#else + public ushort? AlbumLength => _model.Header?.AlbumLength; +#endif /// #if NET48 public string Album => _model.Header.Album; #else - public string? Album => _model.Header.Album; + public string? Album => _model.Header?.Album; #endif /// +#if NET48 public ushort WriterLength => _model.Header.WriterLength; +#else + public ushort? WriterLength => _model.Header?.WriterLength; +#endif /// #if NET48 public string Writer => _model.Header.Writer; #else - public string? Writer => _model.Header.Writer; + public string? Writer => _model.Header?.Writer; #endif /// +#if NET48 public ushort PublisherLength => _model.Header.PublisherLength; +#else + public ushort? PublisherLength => _model.Header?.PublisherLength; +#endif /// #if NET48 public string Publisher => _model.Header.Publisher; #else - public string? Publisher => _model.Header.Publisher; + public string? Publisher => _model.Header?.Publisher; #endif /// +#if NET48 public ushort LabelLength => _model.Header.LabelLength; +#else + public ushort? LabelLength => _model.Header?.LabelLength; +#endif /// #if NET48 public string Label => _model.Header.Label; #else - public string? Label => _model.Header.Label; + public string? Label => _model.Header?.Label; #endif /// +#if NET48 public ushort CommentsLength => _model.Header.CommentsLength; +#else + public ushort? CommentsLength => _model.Header?.CommentsLength; +#endif /// #if NET48 public string Comments => _model.Header.Comments; #else - public string? Comments => _model.Header.Comments; + public string? Comments => _model.Header?.Comments; #endif #endregion @@ -205,13 +241,17 @@ namespace BinaryObjectScanner.Wrappers #region Unknown Block 1 /// +#if NET48 public uint UB1_Length => _model.UnknownBlock1.Length; +#else + public uint? UB1_Length => _model.UnknownBlock1?.Length; +#endif /// #if NET48 public byte[] UB1_Data => _model.UnknownBlock1.Data; #else - public byte[]? UB1_Data => _model.UnknownBlock1.Data; + public byte[]? UB1_Data => _model.UnknownBlock1?.Data; #endif #endregion @@ -231,7 +271,7 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public byte[] UB3_Data => _model.UnknownBlock3.Data; #else - public byte[]? UB3_Data => _model.UnknownBlock3.Data; + public byte[]? UB3_Data => _model.UnknownBlock3?.Data; #endif #endregion @@ -491,6 +531,12 @@ namespace BinaryObjectScanner.Wrappers { var dataFile = DataFiles[i]; builder.AppendLine($" Data File {i}:"); + if (dataFile == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" File name length: {dataFile.FileNameLength} (0x{dataFile.FileNameLength:X})"); builder.AppendLine($" File name: {dataFile.FileName ?? "[NULL]"}"); builder.AppendLine($" Data length: {dataFile.DataLength} (0x{dataFile.DataLength:X})"); diff --git a/BinaryObjectScanner.Wrappers/PortableExecutable.cs b/BinaryObjectScanner.Wrappers/PortableExecutable.cs index c104821f..926c640c 100644 --- a/BinaryObjectScanner.Wrappers/PortableExecutable.cs +++ b/BinaryObjectScanner.Wrappers/PortableExecutable.cs @@ -29,47 +29,99 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Stub_Magic => _model.Stub.Header.Magic; #else - public string? Stub_Magic => _model.Stub.Header.Magic; + public string? Stub_Magic => _model.Stub?.Header?.Magic; #endif /// +#if NET48 public ushort Stub_LastPageBytes => _model.Stub.Header.LastPageBytes; +#else + public ushort? Stub_LastPageBytes => _model.Stub?.Header?.LastPageBytes; +#endif /// +#if NET48 public ushort Stub_Pages => _model.Stub.Header.Pages; +#else + public ushort? Stub_Pages => _model.Stub?.Header?.Pages; +#endif /// +#if NET48 public ushort Stub_RelocationItems => _model.Stub.Header.RelocationItems; +#else + public ushort? Stub_RelocationItems => _model.Stub?.Header?.RelocationItems; +#endif /// +#if NET48 public ushort Stub_HeaderParagraphSize => _model.Stub.Header.HeaderParagraphSize; +#else + public ushort? Stub_HeaderParagraphSize => _model.Stub?.Header?.HeaderParagraphSize; +#endif /// +#if NET48 public ushort Stub_MinimumExtraParagraphs => _model.Stub.Header.MinimumExtraParagraphs; +#else + public ushort? Stub_MinimumExtraParagraphs => _model.Stub?.Header?.MinimumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_MaximumExtraParagraphs => _model.Stub.Header.MaximumExtraParagraphs; +#else + public ushort? Stub_MaximumExtraParagraphs => _model.Stub?.Header?.MaximumExtraParagraphs; +#endif /// +#if NET48 public ushort Stub_InitialSSValue => _model.Stub.Header.InitialSSValue; +#else + public ushort? Stub_InitialSSValue => _model.Stub?.Header?.InitialSSValue; +#endif /// +#if NET48 public ushort Stub_InitialSPValue => _model.Stub.Header.InitialSPValue; +#else + public ushort? Stub_InitialSPValue => _model.Stub?.Header?.InitialSPValue; +#endif /// +#if NET48 public ushort Stub_Checksum => _model.Stub.Header.Checksum; +#else + public ushort? Stub_Checksum => _model.Stub?.Header?.Checksum; +#endif /// +#if NET48 public ushort Stub_InitialIPValue => _model.Stub.Header.InitialIPValue; +#else + public ushort? Stub_InitialIPValue => _model.Stub?.Header?.InitialIPValue; +#endif /// +#if NET48 public ushort Stub_InitialCSValue => _model.Stub.Header.InitialCSValue; +#else + public ushort? Stub_InitialCSValue => _model.Stub?.Header?.InitialCSValue; +#endif /// +#if NET48 public ushort Stub_RelocationTableAddr => _model.Stub.Header.RelocationTableAddr; +#else + public ushort? Stub_RelocationTableAddr => _model.Stub?.Header?.RelocationTableAddr; +#endif /// +#if NET48 public ushort Stub_OverlayNumber => _model.Stub.Header.OverlayNumber; +#else + public ushort? Stub_OverlayNumber => _model.Stub?.Header?.OverlayNumber; +#endif #endregion @@ -79,24 +131,36 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public ushort[] Stub_Reserved1 => _model.Stub.Header.Reserved1; #else - public ushort[]? Stub_Reserved1 => _model.Stub.Header.Reserved1; + public ushort[]? Stub_Reserved1 => _model.Stub?.Header?.Reserved1; #endif /// +#if NET48 public ushort Stub_OEMIdentifier => _model.Stub.Header.OEMIdentifier; +#else + public ushort? Stub_OEMIdentifier => _model.Stub?.Header?.OEMIdentifier; +#endif /// +#if NET48 public ushort Stub_OEMInformation => _model.Stub.Header.OEMInformation; +#else + public ushort? Stub_OEMInformation => _model.Stub?.Header?.OEMInformation; +#endif /// #if NET48 public ushort[] Stub_Reserved2 => _model.Stub.Header.Reserved2; #else - public ushort[]? Stub_Reserved2 => _model.Stub.Header.Reserved2; + public ushort[]? Stub_Reserved2 => _model.Stub?.Header?.Reserved2; #endif /// +#if NET48 public uint Stub_NewExeHeaderAddr => _model.Stub.Header.NewExeHeaderAddr; +#else + public uint? Stub_NewExeHeaderAddr => _model.Stub?.Header?.NewExeHeaderAddr; +#endif #endregion @@ -112,25 +176,53 @@ namespace BinaryObjectScanner.Wrappers #region COFF File Header /// +#if NET48 public SabreTools.Models.PortableExecutable.MachineType Machine => _model.COFFFileHeader.Machine; +#else + public SabreTools.Models.PortableExecutable.MachineType? Machine => _model.COFFFileHeader?.Machine; +#endif /// +#if NET48 public ushort NumberOfSections => _model.COFFFileHeader.NumberOfSections; +#else + public ushort? NumberOfSections => _model.COFFFileHeader?.NumberOfSections; +#endif /// +#if NET48 public uint TimeDateStamp => _model.COFFFileHeader.TimeDateStamp; +#else + public uint? TimeDateStamp => _model.COFFFileHeader?.TimeDateStamp; +#endif /// +#if NET48 public uint PointerToSymbolTable => _model.COFFFileHeader.PointerToSymbolTable; +#else + public uint? PointerToSymbolTable => _model.COFFFileHeader?.PointerToSymbolTable; +#endif /// +#if NET48 public uint NumberOfSymbols => _model.COFFFileHeader.NumberOfSymbols; +#else + public uint? NumberOfSymbols => _model.COFFFileHeader?.NumberOfSymbols; +#endif /// +#if NET48 public uint SizeOfOptionalHeader => _model.COFFFileHeader.SizeOfOptionalHeader; +#else + public uint? SizeOfOptionalHeader => _model.COFFFileHeader?.SizeOfOptionalHeader; +#endif /// +#if NET48 public SabreTools.Models.PortableExecutable.Characteristics Characteristics => _model.COFFFileHeader.Characteristics; +#else + public SabreTools.Models.PortableExecutable.Characteristics? Characteristics => _model.COFFFileHeader?.Characteristics; +#endif #endregion @@ -139,31 +231,63 @@ namespace BinaryObjectScanner.Wrappers #region Standard Fields /// +#if NET48 public SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber OH_Magic => _model.OptionalHeader.Magic; +#else + public SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber? OH_Magic => _model.OptionalHeader?.Magic; +#endif /// +#if NET48 public byte OH_MajorLinkerVersion => _model.OptionalHeader.MajorLinkerVersion; +#else + public byte? OH_MajorLinkerVersion => _model.OptionalHeader?.MajorLinkerVersion; +#endif /// +#if NET48 public byte OH_MinorLinkerVersion => _model.OptionalHeader.MinorLinkerVersion; +#else + public byte? OH_MinorLinkerVersion => _model.OptionalHeader?.MinorLinkerVersion; +#endif /// +#if NET48 public uint OH_SizeOfCode => _model.OptionalHeader.SizeOfCode; +#else + public uint? OH_SizeOfCode => _model.OptionalHeader?.SizeOfCode; +#endif /// +#if NET48 public uint OH_SizeOfInitializedData => _model.OptionalHeader.SizeOfInitializedData; +#else + public uint? OH_SizeOfInitializedData => _model.OptionalHeader?.SizeOfInitializedData; +#endif /// +#if NET48 public uint OH_SizeOfUninitializedData => _model.OptionalHeader.SizeOfUninitializedData; +#else + public uint? OH_SizeOfUninitializedData => _model.OptionalHeader?.SizeOfUninitializedData; +#endif /// +#if NET48 public uint OH_AddressOfEntryPoint => _model.OptionalHeader.AddressOfEntryPoint; +#else + public uint? OH_AddressOfEntryPoint => _model.OptionalHeader?.AddressOfEntryPoint; +#endif /// +#if NET48 public uint OH_BaseOfCode => _model.OptionalHeader.BaseOfCode; +#else + public uint? OH_BaseOfCode => _model.OptionalHeader?.BaseOfCode; +#endif /// - public uint? OH_BaseOfData => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public uint? OH_BaseOfData => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? (uint?)_model.OptionalHeader.BaseOfData : null; @@ -172,77 +296,141 @@ namespace BinaryObjectScanner.Wrappers #region Windows-Specific Fields /// - public ulong OH_ImageBase => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public ulong OH_ImageBase => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _model.OptionalHeader.ImageBase_PE32 - : _model.OptionalHeader.ImageBase_PE32Plus; + : _model.OptionalHeader?.ImageBase_PE32Plus ?? 0; /// +#if NET48 public uint OH_SectionAlignment => _model.OptionalHeader.SectionAlignment; +#else + public uint? OH_SectionAlignment => _model.OptionalHeader?.SectionAlignment; +#endif /// +#if NET48 public uint OH_FileAlignment => _model.OptionalHeader.FileAlignment; +#else + public uint? OH_FileAlignment => _model.OptionalHeader?.FileAlignment; +#endif /// +#if NET48 public ushort OH_MajorOperatingSystemVersion => _model.OptionalHeader.MajorOperatingSystemVersion; +#else + public ushort? OH_MajorOperatingSystemVersion => _model.OptionalHeader?.MajorOperatingSystemVersion; +#endif /// +#if NET48 public ushort OH_MinorOperatingSystemVersion => _model.OptionalHeader.MinorOperatingSystemVersion; +#else + public ushort? OH_MinorOperatingSystemVersion => _model.OptionalHeader?.MinorOperatingSystemVersion; +#endif /// +#if NET48 public ushort OH_MajorImageVersion => _model.OptionalHeader.MajorImageVersion; +#else + public ushort? OH_MajorImageVersion => _model.OptionalHeader?.MajorImageVersion; +#endif /// +#if NET48 public ushort OH_MinorImageVersion => _model.OptionalHeader.MinorImageVersion; +#else + public ushort? OH_MinorImageVersion => _model.OptionalHeader?.MinorImageVersion; +#endif /// +#if NET48 public ushort OH_MajorSubsystemVersion => _model.OptionalHeader.MajorSubsystemVersion; +#else + public ushort? OH_MajorSubsystemVersion => _model.OptionalHeader?.MajorSubsystemVersion; +#endif /// +#if NET48 public ushort OH_MinorSubsystemVersion => _model.OptionalHeader.MinorSubsystemVersion; +#else + public ushort? OH_MinorSubsystemVersion => _model.OptionalHeader?.MinorSubsystemVersion; +#endif /// +#if NET48 public uint OH_Win32VersionValue => _model.OptionalHeader.Win32VersionValue; +#else + public uint? OH_Win32VersionValue => _model.OptionalHeader?.Win32VersionValue; +#endif /// +#if NET48 public uint OH_SizeOfImage => _model.OptionalHeader.SizeOfImage; +#else + public uint? OH_SizeOfImage => _model.OptionalHeader?.SizeOfImage; +#endif /// +#if NET48 public uint OH_SizeOfHeaders => _model.OptionalHeader.SizeOfHeaders; +#else + public uint? OH_SizeOfHeaders => _model.OptionalHeader?.SizeOfHeaders; +#endif /// +#if NET48 public uint OH_CheckSum => _model.OptionalHeader.CheckSum; +#else + public uint? OH_CheckSum => _model.OptionalHeader?.CheckSum; +#endif /// +#if NET48 public SabreTools.Models.PortableExecutable.WindowsSubsystem OH_Subsystem => _model.OptionalHeader.Subsystem; +#else + public SabreTools.Models.PortableExecutable.WindowsSubsystem? OH_Subsystem => _model.OptionalHeader?.Subsystem; +#endif /// +#if NET48 public SabreTools.Models.PortableExecutable.DllCharacteristics OH_DllCharacteristics => _model.OptionalHeader.DllCharacteristics; +#else + public SabreTools.Models.PortableExecutable.DllCharacteristics? OH_DllCharacteristics => _model.OptionalHeader?.DllCharacteristics; +#endif /// - public ulong OH_SizeOfStackReserve => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public ulong OH_SizeOfStackReserve => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _model.OptionalHeader.SizeOfStackReserve_PE32 - : _model.OptionalHeader.SizeOfStackReserve_PE32Plus; + : _model.OptionalHeader?.SizeOfStackReserve_PE32Plus ?? 0; /// - public ulong OH_SizeOfStackCommit => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public ulong OH_SizeOfStackCommit => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _model.OptionalHeader.SizeOfStackCommit_PE32 - : _model.OptionalHeader.SizeOfStackCommit_PE32Plus; + : _model.OptionalHeader?.SizeOfStackCommit_PE32Plus ?? 0; /// - public ulong OH_SizeOfHeapReserve => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public ulong OH_SizeOfHeapReserve => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _model.OptionalHeader.SizeOfHeapReserve_PE32 - : _model.OptionalHeader.SizeOfHeapReserve_PE32Plus; + : _model.OptionalHeader?.SizeOfHeapReserve_PE32Plus ?? 0; /// - public ulong OH_SizeOfHeapCommit => _model.OptionalHeader.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + public ulong OH_SizeOfHeapCommit => _model.OptionalHeader?.Magic == SabreTools.Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 ? _model.OptionalHeader.SizeOfHeapCommit_PE32 - : _model.OptionalHeader.SizeOfHeapCommit_PE32Plus; + : _model.OptionalHeader?.SizeOfHeapCommit_PE32Plus ?? 0; /// +#if NET48 public uint OH_LoaderFlags => _model.OptionalHeader.LoaderFlags; +#else + public uint? OH_LoaderFlags => _model.OptionalHeader?.LoaderFlags; +#endif /// +#if NET48 public uint OH_NumberOfRvaAndSizes => _model.OptionalHeader.NumberOfRvaAndSizes; +#else + public uint? OH_NumberOfRvaAndSizes => _model.OptionalHeader?.NumberOfRvaAndSizes; +#endif #endregion @@ -252,105 +440,113 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ExportTable => _model.OptionalHeader.ExportTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ExportTable => _model.OptionalHeader.ExportTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ExportTable => _model.OptionalHeader?.ExportTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ImportTable => _model.OptionalHeader.ImportTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ImportTable => _model.OptionalHeader.ImportTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ImportTable => _model.OptionalHeader?.ImportTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ResourceTable => _model.OptionalHeader.ResourceTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ResourceTable => _model.OptionalHeader.ResourceTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ResourceTable => _model.OptionalHeader?.ResourceTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ExceptionTable => _model.OptionalHeader.ExceptionTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ExceptionTable => _model.OptionalHeader.ExceptionTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ExceptionTable => _model.OptionalHeader?.ExceptionTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_CertificateTable => _model.OptionalHeader.CertificateTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_CertificateTable => _model.OptionalHeader.CertificateTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_CertificateTable => _model.OptionalHeader?.CertificateTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_BaseRelocationTable => _model.OptionalHeader.BaseRelocationTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_BaseRelocationTable => _model.OptionalHeader.BaseRelocationTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_BaseRelocationTable => _model.OptionalHeader?.BaseRelocationTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_Debug => _model.OptionalHeader.Debug; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_Debug => _model.OptionalHeader.Debug; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_Debug => _model.OptionalHeader?.Debug; #endif /// +#if NET48 public ulong OH_Architecture => _model.OptionalHeader.Architecture; +#else + public ulong? OH_Architecture => _model.OptionalHeader?.Architecture; +#endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_GlobalPtr => _model.OptionalHeader.GlobalPtr; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_GlobalPtr => _model.OptionalHeader.GlobalPtr; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_GlobalPtr => _model.OptionalHeader?.GlobalPtr; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ThreadLocalStorageTable => _model.OptionalHeader.ThreadLocalStorageTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ThreadLocalStorageTable => _model.OptionalHeader.ThreadLocalStorageTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ThreadLocalStorageTable => _model.OptionalHeader?.ThreadLocalStorageTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_LoadConfigTable => _model.OptionalHeader.LoadConfigTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_LoadConfigTable => _model.OptionalHeader.LoadConfigTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_LoadConfigTable => _model.OptionalHeader?.LoadConfigTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_BoundImport => _model.OptionalHeader.BoundImport; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_BoundImport => _model.OptionalHeader.BoundImport; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_BoundImport => _model.OptionalHeader?.BoundImport; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_ImportAddressTable => _model.OptionalHeader.ImportAddressTable; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_ImportAddressTable => _model.OptionalHeader.ImportAddressTable; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_ImportAddressTable => _model.OptionalHeader?.ImportAddressTable; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_DelayImportDescriptor => _model.OptionalHeader.DelayImportDescriptor; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_DelayImportDescriptor => _model.OptionalHeader.DelayImportDescriptor; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_DelayImportDescriptor => _model.OptionalHeader?.DelayImportDescriptor; #endif /// #if NET48 public SabreTools.Models.PortableExecutable.DataDirectory OH_CLRRuntimeHeader => _model.OptionalHeader.CLRRuntimeHeader; #else - public SabreTools.Models.PortableExecutable.DataDirectory? OH_CLRRuntimeHeader => _model.OptionalHeader.CLRRuntimeHeader; + public SabreTools.Models.PortableExecutable.DataDirectory? OH_CLRRuntimeHeader => _model.OptionalHeader?.CLRRuntimeHeader; #endif /// +#if NET48 public ulong OH_Reserved => _model.OptionalHeader.Reserved; +#else + public ulong? OH_Reserved => _model.OptionalHeader?.Reserved; +#endif #endregion @@ -438,7 +634,7 @@ namespace BinaryObjectScanner.Wrappers #else public string?[]? ImportHintNameTable => _model.ImportTable?.HintNameTable != null #endif - ? _model.ImportTable.HintNameTable.Select(entry => entry.Name).ToArray() + ? _model.ImportTable.HintNameTable.Select(entry => entry?.Name).ToArray() : null; /// @@ -478,8 +674,16 @@ namespace BinaryObjectScanner.Wrappers return null; // Populate the raw header padding data based on the source +#if NET48 uint headerStartAddress = Stub_NewExeHeaderAddr; - uint firstSectionAddress = SectionTable.Select(s => s.PointerToRawData).Where(s => s != 0).OrderBy(s => s).First(); +#else + uint headerStartAddress = Stub_NewExeHeaderAddr ?? 0; +#endif + uint firstSectionAddress = SectionTable + .Select(s => s?.PointerToRawData ?? 0) + .Where(s => s != 0) + .OrderBy(s => s) + .First(); int headerLength = (int)(firstSectionAddress - headerStartAddress); _headerPaddingData = ReadFromDataSource((int)headerStartAddress, headerLength); @@ -513,8 +717,16 @@ namespace BinaryObjectScanner.Wrappers return null; // Populate the raw header padding data based on the source +#if NET48 uint headerStartAddress = Stub_NewExeHeaderAddr; - uint firstSectionAddress = SectionTable.Select(s => s.PointerToRawData).Where(s => s != 0).OrderBy(s => s).First(); +#else + uint headerStartAddress = Stub_NewExeHeaderAddr ?? 0; +#endif + uint firstSectionAddress = SectionTable + .Select(s => s?.PointerToRawData ?? 0) + .Where(s => s != 0) + .OrderBy(s => s) + .First(); int headerLength = (int)(firstSectionAddress - headerStartAddress); _headerPaddingStrings = ReadStringsFromDataSource((int)headerStartAddress, headerLength, charLimit: 3); @@ -541,14 +753,24 @@ namespace BinaryObjectScanner.Wrappers if (SectionTable == null) return null; +#if NET6_0_OR_GREATER + // If the address is missing + if (OH_AddressOfEntryPoint == null) + return null; +#endif + // If we have no entry point +#if NET48 int entryPointAddress = (int)OH_AddressOfEntryPoint.ConvertVirtualAddress(SectionTable); +#else + int entryPointAddress = (int)OH_AddressOfEntryPoint.Value.ConvertVirtualAddress(SectionTable); +#endif if (entryPointAddress == 0) return null; // If the entry point matches with the start of a section, use that int entryPointSection = FindEntryPointSectionIndex(); - if (entryPointSection >= 0 && OH_AddressOfEntryPoint == SectionTable[entryPointSection].VirtualAddress) + if (entryPointSection >= 0 && OH_AddressOfEntryPoint == SectionTable[entryPointSection]?.VirtualAddress) return GetSectionData(entryPointSection); // If we already have cached data, just use that immediately @@ -590,18 +812,21 @@ namespace BinaryObjectScanner.Wrappers // If we have certificate data, use that as the end if (OH_CertificateTable != null) { - var certificateTable = _model.OptionalHeader.CertificateTable; - int certificateTableAddress = (int)certificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable); + int certificateTableAddress = (int)OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable); if (certificateTableAddress != 0 && certificateTableAddress < endOfFile) endOfFile = certificateTableAddress; } // Search through all sections and find the furthest a section goes int endOfSectionData = -1; - foreach (var section in _model.SectionTable) + foreach (var section in SectionTable) { + // If we have an invalid section + if (section == null) + continue; + // If we have an invalid section address - int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(_model.SectionTable); + int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (sectionAddress == 0) continue; @@ -662,18 +887,21 @@ namespace BinaryObjectScanner.Wrappers // If we have certificate data, use that as the end if (OH_CertificateTable != null) { - var certificateTable = _model.OptionalHeader.CertificateTable; - int certificateTableAddress = (int)certificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable); + int certificateTableAddress = (int)OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable); if (certificateTableAddress != 0 && certificateTableAddress < endOfFile) endOfFile = certificateTableAddress; } // Search through all sections and find the furthest a section goes int endOfSectionData = -1; - foreach (var section in _model.SectionTable) + foreach (var section in SectionTable) { + // If we have an invalid section + if (section == null) + continue; + // If we have an invalid section address - int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(_model.SectionTable); + int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (sectionAddress == 0) continue; @@ -741,7 +969,7 @@ namespace BinaryObjectScanner.Wrappers // If we have certificate data, use that as the end if (OH_CertificateTable != null) { - var certificateTable = _model.OptionalHeader.CertificateTable; + var certificateTable = OH_CertificateTable; int certificateTableAddress = (int)certificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable); if (certificateTableAddress != 0 && certificateTableAddress < endOfFile) endOfFile = certificateTableAddress; @@ -749,10 +977,14 @@ namespace BinaryObjectScanner.Wrappers // Search through all sections and find the furthest a section goes int endOfSectionData = -1; - foreach (var section in _model.SectionTable) + foreach (var section in SectionTable) { + // If we have an invalid section + if (section == null) + continue; + // If we have an invalid section address - int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(_model.SectionTable); + int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (sectionAddress == 0) continue; @@ -808,11 +1040,17 @@ namespace BinaryObjectScanner.Wrappers if (_sectionNames != null) return _sectionNames; + // If there are no sections + if (SectionTable == null) + return null; + // Otherwise, build and return the cached array - _sectionNames = new string[_model.SectionTable.Length]; + _sectionNames = new string[SectionTable.Length]; for (int i = 0; i < _sectionNames.Length; i++) { - var section = _model.SectionTable[i]; + var section = SectionTable[i]; + if (section == null) + continue; // TODO: Handle long section names with leading `/` #if NET48 @@ -851,7 +1089,7 @@ namespace BinaryObjectScanner.Wrappers // Populate the raw stub executable data based on the source int endOfStubHeader = 0x40; - int lengthOfStubExecutableData = (int)_model.Stub.Header.NewExeHeaderAddr - endOfStubHeader; + int lengthOfStubExecutableData = (int)Stub_NewExeHeaderAddr - endOfStubHeader; _stubExecutableData = ReadFromDataSource(endOfStubHeader, lengthOfStubExecutableData); // Cache and return the stub executable data, even if null @@ -1163,7 +1401,7 @@ namespace BinaryObjectScanner.Wrappers var manifest = GetAssemblyManifest(); return manifest? .AssemblyIdentities? - .FirstOrDefault(ai => !string.IsNullOrWhiteSpace(ai.Version))? + .FirstOrDefault(ai => !string.IsNullOrWhiteSpace(ai?.Version))? .Version; } } @@ -1729,16 +1967,26 @@ namespace BinaryObjectScanner.Wrappers { builder.AppendLine(" Section Table Information:"); builder.AppendLine(" -------------------------"); - if (NumberOfSections == 0 || SectionTable.Length == 0) + if (NumberOfSections == 0 || SectionTable == null || SectionTable.Length == 0) { builder.AppendLine(" No section table items"); } else { +#if NET48 for (int i = 0; i < SectionTable.Length; i++) +#else + for (int i = 0; i < SectionTable!.Length; i++) +#endif { var entry = SectionTable[i]; builder.AppendLine($" Section Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Name: {(entry.Name == null ? "[NULL]" : 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})"); @@ -1781,6 +2029,12 @@ namespace BinaryObjectScanner.Wrappers { var entry = COFFSymbolTable[i]; builder.AppendLine($" COFF Symbol Table Entry {i} (Subtype {currentSymbolType})"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + if (currentSymbolType == 0) { if (entry.ShortName != null) @@ -2039,6 +2293,12 @@ namespace BinaryObjectScanner.Wrappers { var baseRelocationTableEntry = BaseRelocationTable[i]; builder.AppendLine($" Base Relocation Table Entry {i}"); + if (baseRelocationTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Page RVA: {baseRelocationTableEntry.PageRVA} (0x{baseRelocationTableEntry.PageRVA:X})"); builder.AppendLine($" Page physical address: {baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable ?? Array.Empty())} (0x{baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable ?? Array.Empty()):X})"); builder.AppendLine($" Block size: {baseRelocationTableEntry.BlockSize} (0x{baseRelocationTableEntry.BlockSize:X})"); @@ -2055,6 +2315,13 @@ namespace BinaryObjectScanner.Wrappers { var typeOffsetFieldEntry = baseRelocationTableEntry.TypeOffsetFieldEntries[j]; builder.AppendLine($" Type and Offset Entry {j}"); +#if NET6_0_OR_GREATER + if (typeOffsetFieldEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } +#endif builder.AppendLine($" Type: {typeOffsetFieldEntry.BaseRelocationType} (0x{typeOffsetFieldEntry.BaseRelocationType:X})"); builder.AppendLine($" Offset: {typeOffsetFieldEntry.Offset} (0x{typeOffsetFieldEntry.Offset:X})"); } @@ -2074,7 +2341,7 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine(" -------------------------"); if (OH_Debug == null || OH_Debug.VirtualAddress == 0 - || DebugTable == null) + || DebugTable?.DebugDirectoryTable == null) { builder.AppendLine(" No debug table items"); } @@ -2085,6 +2352,12 @@ namespace BinaryObjectScanner.Wrappers { var debugDirectoryEntry = DebugTable.DebugDirectoryTable[i]; builder.AppendLine($" Debug Directory Table Entry {i}"); + if (debugDirectoryEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -2108,7 +2381,7 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine(" -------------------------"); if (OH_ExportTable == null || OH_ExportTable.VirtualAddress == 0 - || ExportTable == null) + || ExportTable?.ExportDirectoryTable == null) { builder.AppendLine(" No export table items"); } @@ -2143,6 +2416,12 @@ namespace BinaryObjectScanner.Wrappers { var exportAddressTableEntry = ExportTable.ExportAddressTable[i]; builder.AppendLine($" Export Address Table Entry {i}"); + if (exportAddressTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Export RVA / Forwarder RVA: {exportAddressTableEntry.ExportRVA} (0x{exportAddressTableEntry.ExportRVA:X})"); } } @@ -2230,6 +2509,12 @@ namespace BinaryObjectScanner.Wrappers { var importDirectoryTableEntry = ImportTable.ImportDirectoryTable[i]; builder.AppendLine($" Import Directory Table Entry {i}"); + if (importDirectoryTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Import lookup table RVA: {importDirectoryTableEntry.ImportLookupTableRVA} (0x{importDirectoryTableEntry.ImportLookupTableRVA:X})"); builder.AppendLine($" Import lookup table Physical Address: {importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable ?? Array.Empty())} (0x{importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(SectionTable ?? Array.Empty()):X})"); builder.AppendLine($" Time/Date stamp: {importDirectoryTableEntry.TimeDateStamp} (0x{importDirectoryTableEntry.TimeDateStamp:X})"); @@ -2268,6 +2553,12 @@ namespace BinaryObjectScanner.Wrappers { var importLookupTableEntry = importLookupTable[i]; builder.AppendLine($" Import Lookup Table {index} Entry {i}"); + if (importLookupTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Ordinal/Name flag: {importLookupTableEntry.OrdinalNameFlag} (0x{importLookupTableEntry.OrdinalNameFlag:X})"); if (importLookupTableEntry.OrdinalNameFlag) { @@ -2310,6 +2601,12 @@ namespace BinaryObjectScanner.Wrappers { var importAddressTableEntry = importAddressTable[i]; builder.AppendLine($" Import Address Table {index} Entry {i}"); + if (importAddressTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Ordinal/Name flag: {importAddressTableEntry.OrdinalNameFlag} (0x{importAddressTableEntry.OrdinalNameFlag:X})"); if (importAddressTableEntry.OrdinalNameFlag) { @@ -2338,6 +2635,12 @@ namespace BinaryObjectScanner.Wrappers { var hintNameTableEntry = ImportTable.HintNameTable[i]; builder.AppendLine($" Hint/Name Table Entry {i}"); + if (hintNameTableEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Hint: {hintNameTableEntry.Hint} (0x{hintNameTableEntry.Hint:X})"); builder.AppendLine($" Name: {hintNameTableEntry.Name}"); } @@ -2393,6 +2696,9 @@ namespace BinaryObjectScanner.Wrappers } else { + if (table.Entries == null) + return; + for (int i = 0; i < table.Entries.Length; i++) { var entry = table.Entries[i]; @@ -2422,7 +2728,7 @@ namespace BinaryObjectScanner.Wrappers if (entry.NameOffset != default) { builder.AppendLine($"{padding}Name offset: {entry.NameOffset} (0x{entry.NameOffset:X})"); - builder.AppendLine($"{padding}Name ({entry.Name?.Length ?? 0}): {(entry.Name.UnicodeString == null ? "[NULL]" : Encoding.UTF8.GetString(entry.Name.UnicodeString))}"); + builder.AppendLine($"{padding}Name ({entry.Name?.Length ?? 0}): {(entry.Name?.UnicodeString == null ? "[NULL]" : Encoding.UTF8.GetString(entry.Name.UnicodeString))}"); } else { @@ -2599,8 +2905,13 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < menu.MenuItems.Length; i++) { var menuItem = menu.MenuItems[i]; - builder.AppendLine($"{padding}Menu item {i}"); + if (menuItem == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + if (menuItem.NormalMenuText != null) { builder.AppendLine($"{padding} Resource info: {menuItem.NormalResInfo} (0x{menuItem.NormalResInfo:X})"); @@ -2636,7 +2947,13 @@ namespace BinaryObjectScanner.Wrappers { var menuItem = menu.ExtendedMenuItems[i]; - builder.AppendLine($"{padding}Dialog item template {i}"); + builder.AppendLine($"{padding}Menu item {i}"); + if (menuItem == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + 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})"); @@ -2700,8 +3017,13 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < dialogBox.DialogItemTemplates.Length; i++) { var dialogItemTemplate = dialogBox.DialogItemTemplates[i]; - builder.AppendLine($"{padding}Dialog item template {i}"); + if (dialogItemTemplate == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + 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})"); @@ -2756,8 +3078,13 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < dialogBox.ExtendedDialogItemTemplates.Length; i++) { var dialogItemTemplate = dialogBox.ExtendedDialogItemTemplates[i]; - builder.AppendLine($"{padding}Dialog item template {i}"); + if (dialogItemTemplate == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + 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})"); @@ -2940,8 +3267,13 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < messageTable.Blocks.Length; i++) { var messageResourceBlock = messageTable.Blocks[i]; - builder.AppendLine($"{padding}Message resource block {i}"); + if (messageResourceBlock == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + 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})"); @@ -2951,8 +3283,7 @@ namespace BinaryObjectScanner.Wrappers builder.AppendLine($"{padding}Message resource entries"); builder.AppendLine($"{padding}-------------------------"); - if (messageTable.Entries == null - || messageTable.Entries.Count == 0) + if (messageTable.Entries == null || messageTable.Entries.Count == 0) { builder.AppendLine($"{padding}No message resource entries"); } @@ -2962,8 +3293,13 @@ namespace BinaryObjectScanner.Wrappers { uint index = kvp.Key; var messageResourceEntry = kvp.Value; - builder.AppendLine($"{padding}Message resource entry {index}"); + if (messageResourceEntry == null) + { + builder.AppendLine($"{padding} [NULL]"); + continue; + } + 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}"); @@ -3049,6 +3385,11 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < versionInfo.StringFileInfo.Children.Length; i++) { var stringFileInfoChildEntry = versionInfo.StringFileInfo.Children[i]; + if (stringFileInfoChildEntry == null) + { + builder.AppendLine($"{padding} [String Table {i}] [NULL]"); + continue; + } 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})"); @@ -3065,6 +3406,11 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < stringFileInfoChildEntry.Children.Length; j++) { var stringDataEntry = stringFileInfoChildEntry.Children[j]; + if (stringDataEntry == null) + { + builder.AppendLine($"{padding} [String Data {j}] [NULL]"); + continue; + } 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})"); @@ -3094,6 +3440,11 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < versionInfo.VarFileInfo.Children.Length; i++) { var varFileInfoChildEntry = versionInfo.VarFileInfo.Children[i]; + if (varFileInfoChildEntry == null) + { + builder.AppendLine($"{padding} [String Table {i}] [NULL]"); + continue; + } 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})"); @@ -3198,6 +3549,12 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < assemblyManifest.AssemblyIdentities.Length; i++) { var assemblyIdentity = assemblyManifest.AssemblyIdentities[i]; + if (assemblyIdentity == null) + { + builder.AppendLine($"{padding} [Assembly Identity {i}] [NULL]"); + continue; + } + 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}"); @@ -3215,6 +3572,12 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < assemblyManifest.COMInterfaceExternalProxyStub.Length; i++) { var comInterfaceExternalProxyStub = assemblyManifest.COMInterfaceExternalProxyStub[i]; + if (comInterfaceExternalProxyStub == null) + { + builder.AppendLine($"{padding} [COM Interface External Proxy Stub {i}] [NULL]"); + continue; + } + 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}"); @@ -3229,7 +3592,7 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < assemblyManifest.Dependency.Length; i++) { var dependency = assemblyManifest.Dependency[i]; - if (dependency.DependentAssembly != null) + if (dependency?.DependentAssembly != null) { if (dependency.DependentAssembly.AssemblyIdentity != null) { @@ -3245,13 +3608,20 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < dependency.DependentAssembly.BindingRedirect.Length; j++) { var bindingRedirect = dependency.DependentAssembly.BindingRedirect[j]; + if (bindingRedirect == null) + { + builder.AppendLine($"{padding}[Dependency {i} Binding Redirect {j}] [NULL]"); + continue; + } + builder.AppendLine($"{padding}[Dependency {i} Binding Redirect {j}] Old version: {bindingRedirect.OldVersion}"); builder.AppendLine($"{padding}[Dependency {i} Binding Redirect {j}] New version: {bindingRedirect.NewVersion}"); } } } - builder.AppendLine($"{padding}[Dependency {i}] Optional: {dependency.Optional}"); + if (dependency != null) + builder.AppendLine($"{padding}[Dependency {i}] Optional: {dependency.Optional}"); } } @@ -3260,6 +3630,12 @@ namespace BinaryObjectScanner.Wrappers for (int i = 0; i < assemblyManifest.File.Length; i++) { var file = assemblyManifest.File[i]; + if (file == null) + { + builder.AppendLine($"{padding}[File {i}] [NULL]"); + continue; + } + 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}"); @@ -3270,6 +3646,12 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < file.COMClass.Length; j++) { var comClass = file.COMClass[j]; + if (comClass == null) + { + builder.AppendLine($"{padding}[File {i} COM Class {j}] [NULL]"); + continue; + } + 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}"); @@ -3281,6 +3663,12 @@ namespace BinaryObjectScanner.Wrappers for (int k = 0; k < comClass.ProgIDs.Length; k++) { var progId = comClass.ProgIDs[k]; + if (progId == null) + { + builder.AppendLine($"{padding}[File {i} COM Class {j} Prog ID {k}] [NULL]"); + continue; + } + builder.AppendLine($"{padding}[File {i} COM Class {j} Prog ID {k}] Value: {progId.Value}"); } } @@ -3292,6 +3680,12 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < file.COMInterfaceProxyStub.Length; j++) { var comInterfaceProxyStub = file.COMInterfaceProxyStub[j]; + if (comInterfaceProxyStub == null) + { + builder.AppendLine($"{padding}[File {i} COM Interface Proxy Stub {j}] [NULL]"); + continue; + } + 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}"); @@ -3306,6 +3700,12 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < file.Typelib.Length; j++) { var typeLib = file.Typelib[j]; + if (typeLib == null) + { + builder.AppendLine($"{padding}[File {i} Type Lib {j}] [NULL]"); + continue; + } + 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}"); @@ -3319,6 +3719,12 @@ namespace BinaryObjectScanner.Wrappers for (int j = 0; j < file.WindowClass.Length; j++) { var windowClass = file.WindowClass[j]; + if (windowClass == null) + { + builder.AppendLine($"{padding}[File {i} Window Class {j}] [NULL]"); + continue; + } + builder.AppendLine($"{padding}[File {i} Window Class {j}] Versioned: {windowClass.Versioned}"); builder.AppendLine($"{padding}[File {i} Window Class {j}] Value: {windowClass.Value}"); } @@ -3426,14 +3832,14 @@ namespace BinaryObjectScanner.Wrappers var nb10Found = DebugData.Select(r => r.Value) .Select(r => r as SabreTools.Models.PortableExecutable.NB10ProgramDatabase) .Where(n => n != null) - .Where(n => n.PdbFileName.Contains(path)) - .Select(n => (object)n); + .Where(n => n?.PdbFileName?.Contains(path) == true) + .Select(n => n as object); var rsdsFound = DebugData.Select(r => r.Value) .Select(r => r as SabreTools.Models.PortableExecutable.RSDSProgramDatabase) .Where(r => r != null) - .Where(r => r.PathAndFileName.Contains(path)) - .Select(r => (object)r); + .Where(r => r?.PathAndFileName?.Contains(path) == true) + .Select(r => r as object); return nb10Found.Concat(rsdsFound); } @@ -3511,15 +3917,25 @@ namespace BinaryObjectScanner.Wrappers /// private void ParseDebugTable() { + // If there is no debug table + if (DebugTable?.DebugDirectoryTable == null) + return; + // Loop through all debug table entries for (int i = 0; i < DebugTable.DebugDirectoryTable.Length; i++) { var entry = DebugTable.DebugDirectoryTable[i]; + if (entry == null) + continue; uint address = entry.PointerToRawData; uint size = entry.SizeOfData; +#if NET48 byte[] entryData = ReadFromDataSource((int)address, (int)size); +#else + byte[]? entryData = ReadFromDataSource((int)address, (int)size); +#endif if (entryData == null) continue; @@ -3590,8 +4006,8 @@ namespace BinaryObjectScanner.Wrappers .Where(d => d != null) .Where(d => { - return (d.DialogTemplate?.TitleResource?.Contains(title) ?? false) - || (d.ExtendedDialogTemplate?.TitleResource?.Contains(title) ?? false); + return (d?.DialogTemplate?.TitleResource?.Contains(title) ?? false) + || (d?.ExtendedDialogTemplate?.TitleResource?.Contains(title) ?? false); }); } @@ -3619,17 +4035,17 @@ namespace BinaryObjectScanner.Wrappers .Where(d => d != null) .Where(d => { - if (d.DialogItemTemplates != null) + if (d?.DialogItemTemplates != null) { return d.DialogItemTemplates .Where(dit => dit?.TitleResource != null) - .Any(dit => dit.TitleResource.Contains(title)); + .Any(dit => dit?.TitleResource?.Contains(title) == true); } - else if (d.ExtendedDialogItemTemplates != null) + else if (d?.ExtendedDialogItemTemplates != null) { return d.ExtendedDialogItemTemplates .Where(edit => edit?.TitleResource != null) - .Any(edit => edit.TitleResource.Contains(title)); + .Any(edit => edit?.TitleResource?.Contains(title) == true); } return false; @@ -3763,10 +4179,15 @@ namespace BinaryObjectScanner.Wrappers /// private void ParseResourceDirectoryTable(SabreTools.Models.PortableExecutable.ResourceDirectoryTable table, List types) { - int totalEntries = table?.Entries?.Length ?? 0; - for (int i = 0; i < totalEntries; i++) + if (table?.Entries == null) + return; + + for (int i = 0; i < table.Entries.Length; i++) { var entry = table.Entries[i]; + if (entry == null) + continue; + var newTypes = new List(types ?? new List()); if (entry.Name?.UnicodeString != null) @@ -3801,7 +4222,11 @@ namespace BinaryObjectScanner.Wrappers { // Create the key and value objects string key = types == null ? $"UNKNOWN_{Guid.NewGuid()}" : string.Join(", ", types); +#if NET48 object value = entry.Data; +#else + object? value = entry.Data; +#endif // If we have a known resource type if (types != null && types.Count > 0 && types[0] is uint resourceType) @@ -3940,12 +4365,26 @@ namespace BinaryObjectScanner.Wrappers if (SectionTable == null) return -1; +#if NET6_0_OR_GREATER + // If the address is missing + if (OH_AddressOfEntryPoint == null) + return -1; +#endif + // If we don't have an entry point +#if NET48 if (OH_AddressOfEntryPoint.ConvertVirtualAddress(SectionTable) == 0) return -1; // Otherwise, find the section it exists within return OH_AddressOfEntryPoint.ContainingSectionIndex(SectionTable); +#else + if (OH_AddressOfEntryPoint.Value.ConvertVirtualAddress(SectionTable) == 0) + return -1; + + // Otherwise, find the section it exists within + return OH_AddressOfEntryPoint.Value.ContainingSectionIndex(SectionTable); +#endif } /// @@ -4203,6 +4642,9 @@ namespace BinaryObjectScanner.Wrappers // Get the section data from the table var section = SectionTable[index]; + if (section == null) + return null; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (address == 0) return null; @@ -4256,64 +4698,64 @@ namespace BinaryObjectScanner.Wrappers switch (index) { case 1: - virtualAddress = OH_ExportTable.VirtualAddress; - size = OH_ExportTable.Size; + virtualAddress = OH_ExportTable?.VirtualAddress ?? 0; + size = OH_ExportTable?.Size ?? 0; break; case 2: - virtualAddress = OH_ImportTable.VirtualAddress; - size = OH_ImportTable.Size; + virtualAddress = OH_ImportTable?.VirtualAddress ?? 0; + size = OH_ImportTable?.Size ?? 0; break; case 3: - virtualAddress = OH_ResourceTable.VirtualAddress; - size = OH_ResourceTable.Size; + virtualAddress = OH_ResourceTable?.VirtualAddress ?? 0; + size = OH_ResourceTable?.Size ?? 0; break; case 4: - virtualAddress = OH_ExceptionTable.VirtualAddress; - size = OH_ExceptionTable.Size; + virtualAddress = OH_ExceptionTable?.VirtualAddress ?? 0; + size = OH_ExceptionTable?.Size ?? 0; break; case 5: - virtualAddress = OH_CertificateTable.VirtualAddress; - size = OH_CertificateTable.Size; + virtualAddress = OH_CertificateTable?.VirtualAddress ?? 0; + size = OH_CertificateTable?.Size ?? 0; break; case 6: - virtualAddress = OH_BaseRelocationTable.VirtualAddress; - size = OH_BaseRelocationTable.Size; + virtualAddress = OH_BaseRelocationTable?.VirtualAddress ?? 0; + size = OH_BaseRelocationTable?.Size ?? 0; break; case 7: - virtualAddress = OH_Debug.VirtualAddress; - size = OH_Debug.Size; + virtualAddress = OH_Debug?.VirtualAddress ?? 0; + size = OH_Debug?.Size ?? 0; break; case 8: // Architecture Table virtualAddress = 0; size = 0; break; case 9: - virtualAddress = OH_GlobalPtr.VirtualAddress; - size = OH_GlobalPtr.Size; + virtualAddress = OH_GlobalPtr?.VirtualAddress ?? 0; + size = OH_GlobalPtr?.Size ?? 0; break; case 10: - virtualAddress = OH_ThreadLocalStorageTable.VirtualAddress; - size = OH_ThreadLocalStorageTable.Size; + virtualAddress = OH_ThreadLocalStorageTable?.VirtualAddress ?? 0; + size = OH_ThreadLocalStorageTable?.Size ?? 0; break; case 11: - virtualAddress = OH_LoadConfigTable.VirtualAddress; - size = OH_LoadConfigTable.Size; + virtualAddress = OH_LoadConfigTable?.VirtualAddress ?? 0; + size = OH_LoadConfigTable?.Size ?? 0; break; case 12: - virtualAddress = OH_BoundImport.VirtualAddress; - size = OH_BoundImport.Size; + virtualAddress = OH_BoundImport?.VirtualAddress ?? 0; + size = OH_BoundImport?.Size ?? 0; break; case 13: - virtualAddress = OH_ImportAddressTable.VirtualAddress; - size = OH_ImportAddressTable.Size; + virtualAddress = OH_ImportAddressTable?.VirtualAddress ?? 0; + size = OH_ImportAddressTable?.Size ?? 0; break; case 14: - virtualAddress = OH_DelayImportDescriptor.VirtualAddress; - size = OH_DelayImportDescriptor.Size; + virtualAddress = OH_DelayImportDescriptor?.VirtualAddress ?? 0; + size = OH_DelayImportDescriptor?.Size ?? 0; break; case 15: - virtualAddress = OH_CLRRuntimeHeader.VirtualAddress; - size = OH_CLRRuntimeHeader.Size; + virtualAddress = OH_CLRRuntimeHeader?.VirtualAddress ?? 0; + size = OH_CLRRuntimeHeader?.Size ?? 0; break; case 16: // Reserved virtualAddress = 0; @@ -4373,64 +4815,64 @@ namespace BinaryObjectScanner.Wrappers switch (index) { case 1: - virtualAddress = OH_ExportTable.VirtualAddress; - size = OH_ExportTable.Size; + virtualAddress = OH_ExportTable?.VirtualAddress ?? 0; + size = OH_ExportTable?.Size ?? 0; break; case 2: - virtualAddress = OH_ImportTable.VirtualAddress; - size = OH_ImportTable.Size; + virtualAddress = OH_ImportTable?.VirtualAddress ?? 0; + size = OH_ImportTable?.Size ?? 0; break; case 3: - virtualAddress = OH_ResourceTable.VirtualAddress; - size = OH_ResourceTable.Size; + virtualAddress = OH_ResourceTable?.VirtualAddress ?? 0; + size = OH_ResourceTable?.Size ?? 0; break; case 4: - virtualAddress = OH_ExceptionTable.VirtualAddress; - size = OH_ExceptionTable.Size; + virtualAddress = OH_ExceptionTable?.VirtualAddress ?? 0; + size = OH_ExceptionTable?.Size ?? 0; break; case 5: - virtualAddress = OH_CertificateTable.VirtualAddress; - size = OH_CertificateTable.Size; + virtualAddress = OH_CertificateTable?.VirtualAddress ?? 0; + size = OH_CertificateTable?.Size ?? 0; break; case 6: - virtualAddress = OH_BaseRelocationTable.VirtualAddress; - size = OH_BaseRelocationTable.Size; + virtualAddress = OH_BaseRelocationTable?.VirtualAddress ?? 0; + size = OH_BaseRelocationTable?.Size ?? 0; break; case 7: - virtualAddress = OH_Debug.VirtualAddress; - size = OH_Debug.Size; + virtualAddress = OH_Debug?.VirtualAddress ?? 0; + size = OH_Debug?.Size ?? 0; break; case 8: // Architecture Table virtualAddress = 0; size = 0; break; case 9: - virtualAddress = OH_GlobalPtr.VirtualAddress; - size = OH_GlobalPtr.Size; + virtualAddress = OH_GlobalPtr?.VirtualAddress ?? 0; + size = OH_GlobalPtr?.Size ?? 0; break; case 10: - virtualAddress = OH_ThreadLocalStorageTable.VirtualAddress; - size = OH_ThreadLocalStorageTable.Size; + virtualAddress = OH_ThreadLocalStorageTable?.VirtualAddress ?? 0; + size = OH_ThreadLocalStorageTable?.Size ?? 0; break; case 11: - virtualAddress = OH_LoadConfigTable.VirtualAddress; - size = OH_LoadConfigTable.Size; + virtualAddress = OH_LoadConfigTable?.VirtualAddress ?? 0; + size = OH_LoadConfigTable?.Size ?? 0; break; case 12: - virtualAddress = OH_BoundImport.VirtualAddress; - size = OH_BoundImport.Size; + virtualAddress = OH_BoundImport?.VirtualAddress ?? 0; + size = OH_BoundImport?.Size ?? 0; break; case 13: - virtualAddress = OH_ImportAddressTable.VirtualAddress; - size = OH_ImportAddressTable.Size; + virtualAddress = OH_ImportAddressTable?.VirtualAddress ?? 0; + size = OH_ImportAddressTable?.Size ?? 0; break; case 14: - virtualAddress = OH_DelayImportDescriptor.VirtualAddress; - size = OH_DelayImportDescriptor.Size; + virtualAddress = OH_DelayImportDescriptor?.VirtualAddress ?? 0; + size = OH_DelayImportDescriptor?.Size ?? 0; break; case 15: - virtualAddress = OH_CLRRuntimeHeader.VirtualAddress; - size = OH_CLRRuntimeHeader.Size; + virtualAddress = OH_CLRRuntimeHeader?.VirtualAddress ?? 0; + size = OH_CLRRuntimeHeader?.Size ?? 0; break; case 16: // Reserved virtualAddress = 0; diff --git a/BinaryObjectScanner.Wrappers/Quantum.cs b/BinaryObjectScanner.Wrappers/Quantum.cs index 09e7043c..75ee01d8 100644 --- a/BinaryObjectScanner.Wrappers/Quantum.cs +++ b/BinaryObjectScanner.Wrappers/Quantum.cs @@ -20,23 +20,43 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public byte MajorVersion => _model.Header.MajorVersion; +#else + public byte? MajorVersion => _model.Header?.MajorVersion; +#endif /// +#if NET48 public byte MinorVersion => _model.Header.MinorVersion; +#else + public byte? MinorVersion => _model.Header?.MinorVersion; +#endif /// +#if NET48 public ushort FileCount => _model.Header.FileCount; +#else + public ushort? FileCount => _model.Header?.FileCount; +#endif /// +#if NET48 public byte TableSize => _model.Header.TableSize; +#else + public byte? TableSize => _model.Header?.TableSize; +#endif /// +#if NET48 public byte CompressionFlags => _model.Header.CompressionFlags; +#else + public byte? CompressionFlags => _model.Header?.CompressionFlags; +#endif #endregion @@ -302,6 +322,12 @@ namespace BinaryObjectScanner.Wrappers { var fileDescriptor = FileList[i]; builder.AppendLine($" File Descriptor {i}"); + if (fileDescriptor == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/SGA.cs b/BinaryObjectScanner.Wrappers/SGA.cs index d1e81de7..8f9dac85 100644 --- a/BinaryObjectScanner.Wrappers/SGA.cs +++ b/BinaryObjectScanner.Wrappers/SGA.cs @@ -24,14 +24,22 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public ushort MajorVersion => _model.Header.MajorVersion; +#else + public ushort? MajorVersion => _model.Header?.MajorVersion; +#endif /// +#if NET48 public ushort MinorVersion => _model.Header.MinorVersion; +#else + public ushort? MinorVersion => _model.Header?.MinorVersion; +#endif /// #if NET48 @@ -44,8 +52,8 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).FileMD5; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).FileMD5; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.FileMD5; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.FileMD5; default: return null; }; } @@ -62,10 +70,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).Name; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).Name; - case 6: return (_model.Header as SabreTools.Models.SGA.Header6).Name; - case 7: return (_model.Header as SabreTools.Models.SGA.Header6).Name; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.Name; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.Name; + case 6: return (_model.Header as SabreTools.Models.SGA.Header6)?.Name; + case 7: return (_model.Header as SabreTools.Models.SGA.Header6)?.Name; default: return null; }; } @@ -82,8 +90,8 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).HeaderMD5; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).HeaderMD5; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.HeaderMD5; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.HeaderMD5; default: return null; }; } @@ -96,10 +104,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).HeaderLength; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).HeaderLength; - case 6: return (_model.Header as SabreTools.Models.SGA.Header6).HeaderLength; - case 7: return (_model.Header as SabreTools.Models.SGA.Header6).HeaderLength; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.HeaderLength; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.HeaderLength; + case 6: return (_model.Header as SabreTools.Models.SGA.Header6)?.HeaderLength; + case 7: return (_model.Header as SabreTools.Models.SGA.Header6)?.HeaderLength; default: return null; }; } @@ -112,10 +120,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).FileDataOffset; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).FileDataOffset; - case 6: return (_model.Header as SabreTools.Models.SGA.Header6).FileDataOffset; - case 7: return (_model.Header as SabreTools.Models.SGA.Header6).FileDataOffset; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.FileDataOffset; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.FileDataOffset; + case 6: return (_model.Header as SabreTools.Models.SGA.Header6)?.FileDataOffset; + case 7: return (_model.Header as SabreTools.Models.SGA.Header6)?.FileDataOffset; default: return null; }; } @@ -128,10 +136,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Header as SabreTools.Models.SGA.Header4).Dummy0; - case 5: return (_model.Header as SabreTools.Models.SGA.Header4).Dummy0; - case 6: return (_model.Header as SabreTools.Models.SGA.Header6).Dummy0; - case 7: return (_model.Header as SabreTools.Models.SGA.Header6).Dummy0; + case 4: return (_model.Header as SabreTools.Models.SGA.Header4)?.Dummy0; + case 5: return (_model.Header as SabreTools.Models.SGA.Header4)?.Dummy0; + case 6: return (_model.Header as SabreTools.Models.SGA.Header6)?.Dummy0; + case 7: return (_model.Header as SabreTools.Models.SGA.Header6)?.Dummy0; default: return null; }; } @@ -150,10 +158,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.SectionOffset; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.SectionOffset; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.SectionOffset; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.SectionOffset; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.SectionOffset; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.SectionOffset; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.SectionOffset; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.SectionOffset; default: return null; }; } @@ -166,10 +174,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.SectionCount; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.SectionCount; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.SectionCount; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.SectionCount; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.SectionCount; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.SectionCount; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.SectionCount; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.SectionCount; default: return null; }; } @@ -182,10 +190,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.FolderOffset; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.FolderOffset; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.FolderOffset; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.FolderOffset; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.FolderOffset; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.FolderOffset; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.FolderOffset; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.FolderOffset; default: return null; }; } @@ -198,10 +206,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.FolderCount; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.FolderCount; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.FolderCount; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.FolderCount; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.FolderCount; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.FolderCount; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.FolderCount; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.FolderCount; default: return null; }; } @@ -214,10 +222,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.FileOffset; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.FileOffset; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.FileOffset; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.FileOffset; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.FileOffset; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.FileOffset; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.FileOffset; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.FileOffset; default: return null; }; } @@ -230,10 +238,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.FileCount; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.FileCount; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.FileCount; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.FileCount; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.FileCount; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.FileCount; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.FileCount; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.FileCount; default: return null; }; } @@ -246,10 +254,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.StringTableOffset; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.StringTableOffset; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.StringTableOffset; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.StringTableOffset; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.StringTableOffset; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.StringTableOffset; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.StringTableOffset; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.StringTableOffset; default: return null; }; } @@ -262,10 +270,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).DirectoryHeader.StringTableCount; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).DirectoryHeader.StringTableCount; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).DirectoryHeader.StringTableCount; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.StringTableCount; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.DirectoryHeader?.StringTableCount; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.DirectoryHeader?.StringTableCount; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.DirectoryHeader?.StringTableCount; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.StringTableCount; default: return null; }; } @@ -278,7 +286,7 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.HashTableOffset; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.HashTableOffset; default: return null; }; } @@ -291,7 +299,7 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).DirectoryHeader.BlockSize; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.DirectoryHeader?.BlockSize; default: return null; }; } @@ -312,10 +320,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).Sections; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).Sections; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).Sections; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).Sections; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.Sections; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.Sections; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.Sections; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.Sections; default: return null; }; } @@ -336,10 +344,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).Folders; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).Folders; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).Folders; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).Folders; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.Folders; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.Folders; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.Folders; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.Folders; default: return null; }; } @@ -360,10 +368,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4).Files; - case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5).Files; - case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6).Files; - case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7).Files; + case 4: return (_model.Directory as SabreTools.Models.SGA.Directory4)?.Files; + case 5: return (_model.Directory as SabreTools.Models.SGA.Directory5)?.Files; + case 6: return (_model.Directory as SabreTools.Models.SGA.Directory6)?.Files; + case 7: return (_model.Directory as SabreTools.Models.SGA.Directory7)?.Files; default: return null; }; } @@ -550,6 +558,12 @@ namespace BinaryObjectScanner.Wrappers { case 4: var section4 = Sections[i] as SabreTools.Models.SGA.Section4; + if (section4 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Alias: {section4.Alias ?? "[NULL]"}"); builder.AppendLine($" Name: {section4.Name ?? "[NULL]"}"); builder.AppendLine($" Folder start index: {section4.FolderStartIndex} (0x{section4.FolderStartIndex:X})"); @@ -563,6 +577,12 @@ namespace BinaryObjectScanner.Wrappers case 6: case 7: var section5 = Sections[i] as SabreTools.Models.SGA.Section5; + if (section5 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Alias: {section5.Alias ?? "[NULL]"}"); builder.AppendLine($" Name: {section5.Name ?? "[NULL]"}"); builder.AppendLine($" Folder start index: {section5.FolderStartIndex} (0x{section5.FolderStartIndex:X})"); @@ -601,6 +621,12 @@ namespace BinaryObjectScanner.Wrappers { case 4: var folder4 = Folders[i] as SabreTools.Models.SGA.Folder4; + if (folder4 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -613,6 +639,12 @@ namespace BinaryObjectScanner.Wrappers case 6: case 7: var folder5 = Folders[i] as SabreTools.Models.SGA.Folder5; + if (folder5 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -651,6 +683,12 @@ namespace BinaryObjectScanner.Wrappers case 4: case 5: var file4 = Files[i] as SabreTools.Models.SGA.File4; + if (file4 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -663,6 +701,12 @@ namespace BinaryObjectScanner.Wrappers case 6: var file6 = Files[i] as SabreTools.Models.SGA.File6; + if (file6 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -675,6 +719,12 @@ namespace BinaryObjectScanner.Wrappers break; case 7: var file7 = Files[i] as SabreTools.Models.SGA.File7; + if (file7 == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -757,9 +807,9 @@ namespace BinaryObjectScanner.Wrappers switch (MajorVersion) { case 4: - case 5: filename = (file as SabreTools.Models.SGA.File4).Name; break; - case 6: filename = (file as SabreTools.Models.SGA.File6).Name; break; - case 7: filename = (file as SabreTools.Models.SGA.File7).Name; break; + case 5: filename = (file as SabreTools.Models.SGA.File4)?.Name; break; + case 6: filename = (file as SabreTools.Models.SGA.File6)?.Name; break; + case 7: filename = (file as SabreTools.Models.SGA.File7)?.Name; break; default: return false; } @@ -790,10 +840,10 @@ namespace BinaryObjectScanner.Wrappers { switch (MajorVersion) { - case 4: parentNames.Add((folder as SabreTools.Models.SGA.Folder4).Name); break; + case 4: parentNames.Add((folder as SabreTools.Models.SGA.Folder4)?.Name); break; case 5: case 6: - case 7: parentNames.Add((folder as SabreTools.Models.SGA.Folder5).Name); break; + case 7: parentNames.Add((folder as SabreTools.Models.SGA.Folder5)?.Name); break; default: return false; } } @@ -809,9 +859,9 @@ namespace BinaryObjectScanner.Wrappers switch (MajorVersion) { case 4: - case 5: fileOffset = (file as SabreTools.Models.SGA.File4).Offset; break; - case 6: fileOffset = (file as SabreTools.Models.SGA.File6).Offset; break; - case 7: fileOffset = (file as SabreTools.Models.SGA.File7).Offset; break; + case 5: fileOffset = (file as SabreTools.Models.SGA.File4)?.Offset ?? 0; break; + case 6: fileOffset = (file as SabreTools.Models.SGA.File6)?.Offset ?? 0; break; + case 7: fileOffset = (file as SabreTools.Models.SGA.File7)?.Offset ?? 0; break; default: return false; } @@ -824,16 +874,16 @@ namespace BinaryObjectScanner.Wrappers { case 4: case 5: - fileSize = (file as SabreTools.Models.SGA.File4).SizeOnDisk; - outputFileSize = (file as SabreTools.Models.SGA.File4).Size; + fileSize = (file as SabreTools.Models.SGA.File4)?.SizeOnDisk ?? 0; + outputFileSize = (file as SabreTools.Models.SGA.File4)?.Size ?? 0; break; case 6: - fileSize = (file as SabreTools.Models.SGA.File6).SizeOnDisk; - outputFileSize = (file as SabreTools.Models.SGA.File6).Size; + fileSize = (file as SabreTools.Models.SGA.File6)?.SizeOnDisk ?? 0; + outputFileSize = (file as SabreTools.Models.SGA.File6)?.Size ?? 0; break; case 7: - fileSize = (file as SabreTools.Models.SGA.File7).SizeOnDisk; - outputFileSize = (file as SabreTools.Models.SGA.File7).Size; + fileSize = (file as SabreTools.Models.SGA.File7)?.SizeOnDisk ?? 0; + outputFileSize = (file as SabreTools.Models.SGA.File7)?.Size ?? 0; break; default: return false; } diff --git a/BinaryObjectScanner.Wrappers/VBSP.cs b/BinaryObjectScanner.Wrappers/VBSP.cs index bdafba87..1c46d1c6 100644 --- a/BinaryObjectScanner.Wrappers/VBSP.cs +++ b/BinaryObjectScanner.Wrappers/VBSP.cs @@ -19,21 +19,29 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public int Version => _model.Header.Version; +#else + public int? Version => _model.Header?.Version; +#endif /// #if NET48 public SabreTools.Models.VBSP.Lump[] Lumps => _model.Header.Lumps; #else - public SabreTools.Models.VBSP.Lump?[]? Lumps => _model.Header.Lumps; + public SabreTools.Models.VBSP.Lump?[]? Lumps => _model.Header?.Lumps; #endif /// +#if NET48 public int MapRevision => _model.Header.MapRevision; +#else + public int? MapRevision => _model.Header?.MapRevision; +#endif #endregion @@ -185,6 +193,12 @@ namespace BinaryObjectScanner.Wrappers } builder.AppendLine($" Lump {i}{specialLumpName}"); + if (lump == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/VPK.cs b/BinaryObjectScanner.Wrappers/VPK.cs index 87591267..f1e02344 100644 --- a/BinaryObjectScanner.Wrappers/VPK.cs +++ b/BinaryObjectScanner.Wrappers/VPK.cs @@ -21,13 +21,25 @@ namespace BinaryObjectScanner.Wrappers #region Header /// +#if NET48 public uint Signature => _model.Header.Signature; +#else + public uint? Signature => _model.Header?.Signature; +#endif /// +#if NET48 public uint Version => _model.Header.Version; +#else + public uint? Version => _model.Header?.Version; +#endif /// +#if NET48 public uint DirectoryLength => _model.Header.DirectoryLength; +#else + public uint? DirectoryLength => _model.Header?.DirectoryLength; +#endif #endregion @@ -112,8 +124,8 @@ namespace BinaryObjectScanner.Wrappers int archiveCount = DirectoryItems == null ? 0 : DirectoryItems - .Select(di => di.DirectoryEntry) - .Select(de => de.ArchiveIndex) + .Select(di => di?.DirectoryEntry) + .Select(de => de?.ArchiveIndex ?? 0) .Where(ai => ai != HL_VPK_NO_ARCHIVE) .Max(); @@ -297,6 +309,12 @@ namespace BinaryObjectScanner.Wrappers { var archiveHash = ArchiveHashes[i]; builder.AppendLine($" Archive Hash {i}"); + if (archiveHash == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/WAD.cs b/BinaryObjectScanner.Wrappers/WAD.cs index 5ce143d7..328637d1 100644 --- a/BinaryObjectScanner.Wrappers/WAD.cs +++ b/BinaryObjectScanner.Wrappers/WAD.cs @@ -20,14 +20,22 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public uint LumpCount => _model.Header.LumpCount; +#else + public uint? LumpCount => _model.Header?.LumpCount; +#endif /// +#if NET48 public uint LumpOffset => _model.Header.LumpOffset; +#else + public uint? LumpOffset => _model.Header?.LumpOffset; +#endif #endregion @@ -191,6 +199,12 @@ namespace BinaryObjectScanner.Wrappers { var lump = Lumps[i]; builder.AppendLine($" Lump {i}"); + if (lump == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); diff --git a/BinaryObjectScanner.Wrappers/WrapperBase.cs b/BinaryObjectScanner.Wrappers/WrapperBase.cs index 3b56844c..936f2167 100644 --- a/BinaryObjectScanner.Wrappers/WrapperBase.cs +++ b/BinaryObjectScanner.Wrappers/WrapperBase.cs @@ -172,10 +172,18 @@ namespace BinaryObjectScanner.Wrappers switch (_dataSource) { case DataSource.ByteArray: +#if NET48 return _byteArrayOffset + position + length <= _byteArrayData.Length; +#else + return _byteArrayOffset + position + length <= _byteArrayData!.Length; +#endif case DataSource.Stream: +#if NET48 return position + length <= _streamData.Length; +#else + return position + length <= _streamData!.Length; +#endif // Everything else is invalid case DataSource.UNKNOWN: @@ -222,7 +230,11 @@ namespace BinaryObjectScanner.Wrappers break; case DataSource.Stream: +#if NET48 long currentLocation = _streamData.Position; +#else + long currentLocation = _streamData!.Position; +#endif _streamData.Seek(position, SeekOrigin.Begin); sectionData = _streamData.ReadBytes(length); _streamData.Seek(currentLocation, SeekOrigin.Begin); @@ -356,10 +368,18 @@ namespace BinaryObjectScanner.Wrappers switch (_dataSource) { case DataSource.ByteArray: +#if NET48 return _byteArrayData.Length - _byteArrayOffset; +#else + return _byteArrayData!.Length - _byteArrayOffset; +#endif case DataSource.Stream: +#if NET48 return (int)_streamData.Length; +#else + return (int)_streamData!.Length; +#endif case DataSource.UNKNOWN: default: @@ -377,12 +397,10 @@ namespace BinaryObjectScanner.Wrappers public abstract StringBuilder PrettyPrint(); #if NET6_0_OR_GREATER - /// /// Export the item information as JSON /// public abstract string ExportJSON(); - #endif #endregion diff --git a/BinaryObjectScanner.Wrappers/WrapperFactory.cs b/BinaryObjectScanner.Wrappers/WrapperFactory.cs index 77fe0925..dd2e0982 100644 --- a/BinaryObjectScanner.Wrappers/WrapperFactory.cs +++ b/BinaryObjectScanner.Wrappers/WrapperFactory.cs @@ -70,21 +70,44 @@ namespace BinaryObjectScanner.Wrappers public static IWrapper? CreateExecutableWrapper(Stream? stream) #endif { + // If we have no stream + if (stream == null) + return null; + // Try to get an MS-DOS wrapper first +#if NET48 IWrapper wrapper = MSDOS.Create(stream); - if (wrapper == null) +#else + IWrapper? wrapper = MSDOS.Create(stream); +#endif + if (wrapper == null || !(wrapper is MSDOS msdos)) return null; // Check for a valid new executable address - if ((wrapper as MSDOS).NewExeHeaderAddr >= stream.Length) +#if NET48 + if (msdos.NewExeHeaderAddr >= stream.Length) +#else + if (msdos.NewExeHeaderAddr == null || msdos.NewExeHeaderAddr >= stream.Length) +#endif return wrapper; // Try to read the executable info - stream.Seek((wrapper as MSDOS).NewExeHeaderAddr, SeekOrigin.Begin); +#if NET48 + stream.Seek(msdos.NewExeHeaderAddr, SeekOrigin.Begin); byte[] magic = stream.ReadBytes(4); +#else + stream.Seek(msdos.NewExeHeaderAddr.Value, SeekOrigin.Begin); + byte[]? magic = stream.ReadBytes(4); +#endif + + // If we didn't get valid data at the offset + if (magic == null) + { + return wrapper; + } // New Executable - if (magic.StartsWith(SabreTools.Models.NewExecutable.Constants.SignatureBytes)) + else if (magic.StartsWith(SabreTools.Models.NewExecutable.Constants.SignatureBytes)) { stream.Seek(0, SeekOrigin.Begin); return NewExecutable.Create(stream); diff --git a/BinaryObjectScanner.Wrappers/XZP.cs b/BinaryObjectScanner.Wrappers/XZP.cs index 85bcee26..7b278259 100644 --- a/BinaryObjectScanner.Wrappers/XZP.cs +++ b/BinaryObjectScanner.Wrappers/XZP.cs @@ -21,32 +21,64 @@ namespace BinaryObjectScanner.Wrappers #if NET48 public string Signature => _model.Header.Signature; #else - public string? Signature => _model.Header.Signature; + public string? Signature => _model.Header?.Signature; #endif /// +#if NET48 public uint Version => _model.Header.Version; +#else + public uint? Version => _model.Header?.Version; +#endif /// +#if NET48 public uint PreloadDirectoryEntryCount => _model.Header.PreloadDirectoryEntryCount; +#else + public uint? PreloadDirectoryEntryCount => _model.Header?.PreloadDirectoryEntryCount; +#endif /// +#if NET48 public uint DirectoryEntryCount => _model.Header.DirectoryEntryCount; +#else + public uint? DirectoryEntryCount => _model.Header?.DirectoryEntryCount; +#endif /// +#if NET48 public uint PreloadBytes => _model.Header.PreloadBytes; +#else + public uint? PreloadBytes => _model.Header?.PreloadBytes; +#endif /// +#if NET48 public uint HeaderLength => _model.Header.HeaderLength; +#else + public uint? HeaderLength => _model.Header?.HeaderLength; +#endif /// +#if NET48 public uint DirectoryItemCount => _model.Header.DirectoryItemCount; +#else + public uint? DirectoryItemCount => _model.Header?.DirectoryItemCount; +#endif /// +#if NET48 public uint DirectoryItemOffset => _model.Header.DirectoryItemOffset; +#else + public uint? DirectoryItemOffset => _model.Header?.DirectoryItemOffset; +#endif /// +#if NET48 public uint DirectoryItemLength => _model.Header.DirectoryItemLength; +#else + public uint? DirectoryItemLength => _model.Header?.DirectoryItemLength; +#endif #endregion @@ -97,13 +129,17 @@ namespace BinaryObjectScanner.Wrappers #region Footer /// +#if NET48 public uint F_FileLength => _model.Footer.FileLength; +#else + public uint? F_FileLength => _model.Footer?.FileLength; +#endif /// #if NET48 public string F_Signature => _model.Footer.Signature; #else - public string? F_Signature => _model.Footer.Signature; + public string? F_Signature => _model.Footer?.Signature; #endif #endregion @@ -255,6 +291,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryEntry = DirectoryEntries[i]; builder.AppendLine($" Directory Entry {i}"); + if (directoryEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -281,6 +323,12 @@ namespace BinaryObjectScanner.Wrappers { var preloadDirectoryEntry = PreloadDirectoryEntries[i]; builder.AppendLine($" Directory Entry {i}"); + if (preloadDirectoryEntry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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})"); @@ -307,6 +355,12 @@ namespace BinaryObjectScanner.Wrappers { var preloadDirectoryMapping = PreloadDirectoryMappings[i]; builder.AppendLine($" Directory Mapping {i}"); + if (preloadDirectoryMapping == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + builder.AppendLine($" Preload directory entry index: {preloadDirectoryMapping.PreloadDirectoryEntryIndex} (0x{preloadDirectoryMapping.PreloadDirectoryEntryIndex:X})"); } } @@ -331,6 +385,12 @@ namespace BinaryObjectScanner.Wrappers { var directoryItem = DirectoryItems[i]; builder.AppendLine($" Directory Item {i}"); + if (directoryItem == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + 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]"}"); @@ -411,7 +471,7 @@ namespace BinaryObjectScanner.Wrappers return false; // Get the associated directory item - var directoryItem = DirectoryItems.Where(di => di.FileNameCRC == directoryEntry.FileNameCRC).FirstOrDefault(); + var directoryItem = DirectoryItems.Where(di => di?.FileNameCRC == directoryEntry.FileNameCRC).FirstOrDefault(); if (directoryItem == null) return false;