From 9a93c7b15d1e8fd68edf755b767b4028531fe6e2 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 15 Sep 2023 00:21:12 -0400 Subject: [PATCH] Port NE to new printing --- .../BinaryObjectScanner.Printing.csproj | 1 + BinaryObjectScanner.Printing/NewExecutable.cs | 408 ++++++++++++++++++ BinaryObjectScanner.Wrappers/NewExecutable.cs | 395 +---------------- 3 files changed, 410 insertions(+), 394 deletions(-) create mode 100644 BinaryObjectScanner.Printing/NewExecutable.cs diff --git a/BinaryObjectScanner.Printing/BinaryObjectScanner.Printing.csproj b/BinaryObjectScanner.Printing/BinaryObjectScanner.Printing.csproj index 25eb3782..7373f86d 100644 --- a/BinaryObjectScanner.Printing/BinaryObjectScanner.Printing.csproj +++ b/BinaryObjectScanner.Printing/BinaryObjectScanner.Printing.csproj @@ -25,6 +25,7 @@ + diff --git a/BinaryObjectScanner.Printing/NewExecutable.cs b/BinaryObjectScanner.Printing/NewExecutable.cs new file mode 100644 index 00000000..b83f6ae8 --- /dev/null +++ b/BinaryObjectScanner.Printing/NewExecutable.cs @@ -0,0 +1,408 @@ +using System.Collections.Generic; +using System.Text; +using SabreTools.Models.NewExecutable; +using static SabreTools.Serialization.Extensions; + +namespace BinaryObjectScanner.Printing +{ + public static class NewExecutable + { + public static void Print(StringBuilder builder, Executable executable) + { + builder.AppendLine("New Executable Information:"); + builder.AppendLine("-------------------------"); + builder.AppendLine(); + + // Stub + Print(builder, executable.Stub?.Header); + + // Header + Print(builder, executable.Header); + + // Tables + Print(builder, executable.SegmentTable); + Print(builder, executable.ResourceTable); + Print(builder, executable.ResidentNameTable); + Print(builder, executable.ModuleReferenceTable, executable.Stub?.Header, executable.Header); + Print(builder, executable.ImportedNameTable); + Print(builder, executable.EntryTable); + Print(builder, executable.NonResidentNameTable); + } + +#if NET48 + private static void Print(StringBuilder builder, SabreTools.Models.MSDOS.ExecutableHeader header) +#else + private static void Print(StringBuilder builder, SabreTools.Models.MSDOS.ExecutableHeader? header) +#endif + { + builder.AppendLine(" MS-DOS Stub Header Information:"); + builder.AppendLine(" -------------------------"); + if (header == null) + { + builder.AppendLine(" No MS-DOS stub header"); + builder.AppendLine(); + } + + builder.AppendLine(header.Magic, " Magic number"); + builder.AppendLine(header.LastPageBytes, " Last page bytes"); + builder.AppendLine(header.Pages, " Pages"); + builder.AppendLine(header.RelocationItems, " Relocation items"); + builder.AppendLine(header.HeaderParagraphSize, " Header paragraph size"); + builder.AppendLine(header.MinimumExtraParagraphs, " Minimum extra paragraphs"); + builder.AppendLine(header.MaximumExtraParagraphs, " Maximum extra paragraphs"); + builder.AppendLine(header.InitialSSValue, " Initial SS value"); + builder.AppendLine(header.InitialSPValue, " Initial SP value"); + builder.AppendLine(header.Checksum, " Checksum"); + builder.AppendLine(header.InitialIPValue, " Initial IP value"); + builder.AppendLine(header.InitialCSValue, " Initial CS value"); + builder.AppendLine(header.RelocationTableAddr, " Relocation table address"); + builder.AppendLine(header.OverlayNumber, " Overlay number"); + builder.AppendLine(); + + builder.AppendLine(" MS-DOS Stub Extended Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine(header.Reserved1, " Reserved words"); + builder.AppendLine(header.OEMIdentifier, " OEM identifier"); + builder.AppendLine(header.OEMInformation, " OEM information"); + builder.AppendLine(header.Reserved2, " Reserved words"); + builder.AppendLine(header.NewExeHeaderAddr, " New EXE header address"); + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, ExecutableHeader header) +#else + private static void Print(StringBuilder builder, ExecutableHeader? header) +#endif + { + builder.AppendLine(" Header Information:"); + builder.AppendLine(" -------------------------"); + builder.AppendLine(header.Magic, " Magic number"); + builder.AppendLine(header.LinkerVersion, " Linker version"); + builder.AppendLine(header.LinkerRevision, " Linker revision"); + builder.AppendLine(header.EntryTableOffset, " Entry table offset"); + builder.AppendLine(header.EntryTableSize, " Entry table size"); + builder.AppendLine(header.CrcChecksum, " CRC checksum"); + builder.AppendLine($" Flag word: {header.FlagWord} (0x{header.FlagWord:X})"); + builder.AppendLine(header.AutomaticDataSegmentNumber, " Automatic data segment number"); + builder.AppendLine(header.InitialHeapAlloc, " Initial heap allocation"); + builder.AppendLine(header.InitialStackAlloc, " Initial stack allocation"); + builder.AppendLine(header.InitialCSIPSetting, " Initial CS:IP setting"); + builder.AppendLine(header.InitialSSSPSetting, " Initial SS:SP setting"); + builder.AppendLine(header.FileSegmentCount, " File segment count"); + builder.AppendLine(header.ModuleReferenceTableSize, " Module reference table size"); + builder.AppendLine(header.NonResidentNameTableSize, " Non-resident name table size"); + builder.AppendLine(header.SegmentTableOffset, " Segment table offset"); + builder.AppendLine(header.ResourceTableOffset, " Resource table offset"); + builder.AppendLine(header.ResidentNameTableOffset, " Resident name table offset"); + builder.AppendLine(header.ModuleReferenceTableOffset, " Module reference table offset"); + builder.AppendLine(header.ImportedNamesTableOffset, " Imported names table offset"); + builder.AppendLine(header.NonResidentNamesTableOffset, " Non-resident name table offset"); + builder.AppendLine(header.MovableEntriesCount, " Moveable entries count"); + builder.AppendLine(header.SegmentAlignmentShiftCount, " Segment alignment shift count"); + builder.AppendLine(header.ResourceEntriesCount, " Resource entries count"); + builder.AppendLine($" Target operating system: {header.TargetOperatingSystem} (0x{header.TargetOperatingSystem:X})"); + builder.AppendLine($" Additional flags: {header.AdditionalFlags} (0x{header.AdditionalFlags:X})"); + builder.AppendLine(header.ReturnThunkOffset, " Return thunk offset"); + builder.AppendLine(header.SegmentReferenceThunkOffset, " Segment reference thunk offset"); + builder.AppendLine(header.MinCodeSwapAreaSize, " Minimum code swap area size"); + builder.AppendLine(header.WindowsSDKRevision, " Windows SDK revision"); + builder.AppendLine(header.WindowsSDKVersion, " Windows SDK version"); + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, SegmentTableEntry[] entries) +#else + private static void Print(StringBuilder builder, SegmentTableEntry?[]? entries) +#endif + { + builder.AppendLine(" Segment Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No segment table items"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Segment Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.Offset, " Offset"); + builder.AppendLine(entry.Length, " Length"); + builder.AppendLine($" Flag word: {entry.FlagWord} (0x{entry.FlagWord:X})"); + builder.AppendLine(entry.MinimumAllocationSize, " Minimum allocation size"); + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, ResourceTable table) +#else + private static void Print(StringBuilder builder, ResourceTable? table) +#endif + { + builder.AppendLine(" Resource Table Information:"); + builder.AppendLine(" -------------------------"); + if (table == null) + { + builder.AppendLine(" No resource table"); + builder.AppendLine(); + return; + } + + builder.AppendLine(table.AlignmentShiftCount, " Alignment shift count"); + if (table.ResourceTypes == null || table.ResourceTypes.Length == 0) + { + builder.AppendLine(" No resource table items"); + } + else + { + for (int i = 0; i < table.ResourceTypes.Length; i++) + { + // TODO: If not integer type, print out name + var entry = table.ResourceTypes[i]; + builder.AppendLine($" Resource Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.TypeID, " Type ID"); + builder.AppendLine(entry.ResourceCount, " Resource count"); + builder.AppendLine(entry.Reserved, " Reserved"); + builder.AppendLine(" Resources = "); + if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0) + { + builder.AppendLine(" No resource items"); + } + else + { + for (int j = 0; j < entry.Resources.Length; j++) + { + // 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(resource.Offset, " Offset"); + builder.AppendLine(resource.Length, " Length"); + builder.AppendLine($" Flag word: {resource.FlagWord} (0x{resource.FlagWord:X})"); + builder.AppendLine(resource.ResourceID, " Resource ID"); + builder.AppendLine(resource.Reserved, " Reserved"); + } + } + } + } + + if (table.TypeAndNameStrings == null || table.TypeAndNameStrings.Count == 0) + { + builder.AppendLine(" No resource table type/name strings"); + } + else + { + foreach (var typeAndNameString in table.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(typeAndNameString.Value.Length, " Length"); + builder.AppendLine($" Text: {(typeAndNameString.Value.Text != null ? Encoding.ASCII.GetString(typeAndNameString.Value.Text).TrimEnd('\0') : "[EMPTY]")}"); + } + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, ResidentNameTableEntry[] entries) +#else + private static void Print(StringBuilder builder, ResidentNameTableEntry?[]? entries) +#endif + { + builder.AppendLine(" Resident-Name Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No resident-name table items"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Resident-Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.Length, " Length"); + builder.AppendLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString).TrimEnd('\0') : "[EMPTY]")}"); + builder.AppendLine(entry.OrdinalNumber, " Ordinal number"); + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, ModuleReferenceTableEntry[] entries, SabreTools.Models.MSDOS.ExecutableHeader stub, ExecutableHeader header) +#else + private static void Print(StringBuilder builder, ModuleReferenceTableEntry?[]? entries, SabreTools.Models.MSDOS.ExecutableHeader? stub, ExecutableHeader? header) +#endif + { + builder.AppendLine(" Module-Reference Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No module-reference table items"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + // TODO: Read the imported names table and print value here + var entry = entries[i]; + builder.AppendLine($" Module-Reference Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + +#if NET48 + builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + stub.NewExeHeaderAddr + header.ImportedNamesTableOffset})"); +#else + builder.AppendLine($" Offset: {entry.Offset} (adjusted to be {entry.Offset + (stub?.NewExeHeaderAddr ?? 0) + (header?.ImportedNamesTableOffset ?? 0)})"); +#endif + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, Dictionary entries) +#else + private static void Print(StringBuilder builder, Dictionary? entries) +#endif + { + builder.AppendLine(" Imported-Name Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Count == 0) + { + builder.AppendLine(" No imported-name table items"); + builder.AppendLine(); + return; + } + + foreach (var entry in entries) + { + 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(entry.Value.Length, " Length"); + builder.AppendLine($" Name string: {(entry.Value.NameString != null ? Encoding.ASCII.GetString(entry.Value.NameString) : "[EMPTY]")}"); + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, EntryTableBundle[] entries) +#else + private static void Print(StringBuilder builder, EntryTableBundle?[]? entries) +#endif + { + builder.AppendLine(" Entry Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No entry table items"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Entry Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.EntryCount, " Entry count"); + builder.AppendLine(entry.SegmentIndicator, " Segment indicator"); + switch (entry.GetEntryType()) + { + case SegmentEntryType.FixedSegment: + builder.AppendLine($" Flag word: {entry.FixedFlagWord} (0x{entry.FixedFlagWord:X})"); + builder.AppendLine(entry.FixedOffset, " Offset"); + break; + case SegmentEntryType.MoveableSegment: + builder.AppendLine($" Flag word: {entry.MoveableFlagWord} (0x{entry.MoveableFlagWord:X})"); + builder.AppendLine(entry.MoveableReserved, " Reserved"); + builder.AppendLine(entry.MoveableSegmentNumber, " Segment number"); + builder.AppendLine(entry.MoveableOffset, " Offset"); + break; + } + } + builder.AppendLine(); + } + +#if NET48 + private static void Print(StringBuilder builder, NonResidentNameTableEntry[] entries) +#else + private static void Print(StringBuilder builder, NonResidentNameTableEntry?[]? entries) +#endif + { + builder.AppendLine(" Nonresident-Name Table Information:"); + builder.AppendLine(" -------------------------"); + if (entries == null || entries.Length == 0) + { + builder.AppendLine(" No nonresident-name table items"); + builder.AppendLine(); + return; + } + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + builder.AppendLine($" Nonresident-Name Table Entry {i}"); + if (entry == null) + { + builder.AppendLine(" [NULL]"); + continue; + } + + builder.AppendLine(entry.Length, " Length"); + builder.AppendLine($" Name string: {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString) : "[EMPTY]")}"); + builder.AppendLine(entry.OrdinalNumber, " Ordinal number"); + } + builder.AppendLine(); + } + } +} \ No newline at end of file diff --git a/BinaryObjectScanner.Wrappers/NewExecutable.cs b/BinaryObjectScanner.Wrappers/NewExecutable.cs index c4154713..6cd93b85 100644 --- a/BinaryObjectScanner.Wrappers/NewExecutable.cs +++ b/BinaryObjectScanner.Wrappers/NewExecutable.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Text; -using static SabreTools.Serialization.Extensions; namespace BinaryObjectScanner.Wrappers { @@ -530,402 +529,10 @@ namespace BinaryObjectScanner.Wrappers public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); - - builder.AppendLine("New Executable Information:"); - builder.AppendLine("-------------------------"); - builder.AppendLine(); - - // Stub - PrintStubHeader(builder); - PrintStubExtendedHeader(builder); - - // Header - PrintHeader(builder); - - // Tables - PrintSegmentTable(builder); - PrintResourceTable(builder); - PrintResidentNameTable(builder); - PrintModuleReferenceTable(builder); - PrintImportedNameTable(builder); - PrintEntryTable(builder); - PrintNonresidentNameTable(builder); - + Printing.NewExecutable.Print(builder, _model); return builder; } - /// - /// Print stub header information - /// - /// StringBuilder to append information to - private void PrintStubHeader(StringBuilder builder) - { - builder.AppendLine(" MS-DOS Stub Header Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine($" Magic number: {Stub_Magic}"); - builder.AppendLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); - builder.AppendLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); - builder.AppendLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); - builder.AppendLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); - builder.AppendLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); - builder.AppendLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); - builder.AppendLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); - builder.AppendLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); - builder.AppendLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); - builder.AppendLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); - builder.AppendLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); - builder.AppendLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); - builder.AppendLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); - builder.AppendLine(); - } - - /// - /// Print stub extended header information - /// - /// StringBuilder to append information to - private void PrintStubExtendedHeader(StringBuilder builder) - { - builder.AppendLine(" MS-DOS Stub Extended Header Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine($" Reserved words: {(Stub_Reserved1 == null ? "[NULL]" : string.Join(", ", Stub_Reserved1))}"); - builder.AppendLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); - builder.AppendLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); - builder.AppendLine($" Reserved words: {(Stub_Reserved2 == null ? "[NULL]" : string.Join(", ", Stub_Reserved2))}"); - builder.AppendLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); - builder.AppendLine(); - } - - /// - /// Print header information - /// - /// StringBuilder to append information to - private void PrintHeader(StringBuilder builder) - { - builder.AppendLine(" Header Information:"); - builder.AppendLine(" -------------------------"); - builder.AppendLine($" Magic number: {Magic}"); - builder.AppendLine($" Linker version: {LinkerVersion} (0x{LinkerVersion:X})"); - builder.AppendLine($" Linker revision: {LinkerRevision} (0x{LinkerRevision:X})"); - builder.AppendLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); - builder.AppendLine($" Entry table size: {EntryTableSize} (0x{EntryTableSize:X})"); - builder.AppendLine($" CRC checksum: {CrcChecksum} (0x{CrcChecksum:X})"); - builder.AppendLine($" Flag word: {FlagWord} (0x{FlagWord:X})"); - builder.AppendLine($" Automatic data segment number: {AutomaticDataSegmentNumber} (0x{AutomaticDataSegmentNumber:X})"); - builder.AppendLine($" Initial heap allocation: {InitialHeapAlloc} (0x{InitialHeapAlloc:X})"); - builder.AppendLine($" Initial stack allocation: {InitialStackAlloc} (0x{InitialStackAlloc:X})"); - builder.AppendLine($" Initial CS:IP setting: {InitialCSIPSetting} (0x{InitialCSIPSetting:X})"); - builder.AppendLine($" Initial SS:SP setting: {InitialSSSPSetting} (0x{InitialSSSPSetting:X})"); - builder.AppendLine($" File segment count: {FileSegmentCount} (0x{FileSegmentCount:X})"); - builder.AppendLine($" Module reference table size: {ModuleReferenceTableSize} (0x{ModuleReferenceTableSize:X})"); - builder.AppendLine($" Non-resident name table size: {NonResidentNameTableSize} (0x{NonResidentNameTableSize:X})"); - builder.AppendLine($" Segment table offset: {SegmentTableOffset} (0x{SegmentTableOffset:X})"); - builder.AppendLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); - builder.AppendLine($" Resident name table offset: {ResidentNameTableOffset} (0x{ResidentNameTableOffset:X})"); - builder.AppendLine($" Module reference table offset: {ModuleReferenceTableOffset} (0x{ModuleReferenceTableOffset:X})"); - builder.AppendLine($" Imported names table offset: {ImportedNamesTableOffset} (0x{ImportedNamesTableOffset:X})"); - builder.AppendLine($" Non-resident name table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); - builder.AppendLine($" Moveable entries count: {MovableEntriesCount} (0x{MovableEntriesCount:X})"); - builder.AppendLine($" Segment alignment shift count: {SegmentAlignmentShiftCount} (0x{SegmentAlignmentShiftCount:X})"); - builder.AppendLine($" Resource entries count: {ResourceEntriesCount} (0x{ResourceEntriesCount:X})"); - builder.AppendLine($" Target operating system: {TargetOperatingSystem} (0x{TargetOperatingSystem:X})"); - builder.AppendLine($" Additional flags: {AdditionalFlags} (0x{AdditionalFlags:X})"); - builder.AppendLine($" Return thunk offset: {ReturnThunkOffset} (0x{ReturnThunkOffset:X})"); - builder.AppendLine($" Segment reference thunk offset: {SegmentReferenceThunkOffset} (0x{SegmentReferenceThunkOffset:X})"); - builder.AppendLine($" Minimum code swap area size: {MinCodeSwapAreaSize} (0x{MinCodeSwapAreaSize:X})"); - builder.AppendLine($" Windows SDK revision: {WindowsSDKRevision} (0x{WindowsSDKRevision:X})"); - builder.AppendLine($" Windows SDK version: {WindowsSDKVersion} (0x{WindowsSDKVersion:X})"); - builder.AppendLine(); - } - - /// - /// Print segment table information - /// - /// StringBuilder to append information to - private void PrintSegmentTable(StringBuilder builder) - { - builder.AppendLine(" Segment Table Information:"); - builder.AppendLine(" -------------------------"); - if (FileSegmentCount == 0 || SegmentTable == null || SegmentTable.Length == 0) - { - builder.AppendLine(" No segment table items"); - } - else - { - for (int i = 0; i < SegmentTable.Length; i++) - { - 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})"); - builder.AppendLine($" Minimum allocation size: {entry.MinimumAllocationSize} (0x{entry.MinimumAllocationSize:X})"); - } - } - builder.AppendLine(); - } - - /// - /// Print resource table information - /// - /// StringBuilder to append information to - private void PrintResourceTable(StringBuilder builder) - { - 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 == null || ResourceTable.ResourceTypes.Length == 0) - { - builder.AppendLine(" No resource table items"); - } - else - { - for (int i = 0; i < ResourceTable.ResourceTypes.Length; i++) - { - // 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 == null || entry.Resources.Length == 0) - { - builder.AppendLine(" No resource items"); - } - else - { - for (int j = 0; j < entry.Resources.Length; j++) - { - // 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})"); - builder.AppendLine($" Resource ID: {resource.ResourceID} (0x{resource.ResourceID:X}) (Is Integer Type: {resource.IsIntegerType()})"); - builder.AppendLine($" Reserved: {resource.Reserved} (0x{resource.Reserved:X})"); - } - } - } - } - - if (ResourceTable.TypeAndNameStrings == null || ResourceTable.TypeAndNameStrings.Count == 0) - { - builder.AppendLine(" No resource table type/name strings"); - } - else - { - 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]")}"); - } - } - builder.AppendLine(); - } - - /// - /// Print resident-name table information - /// - /// StringBuilder to append information to - private void PrintResidentNameTable(StringBuilder builder) - { - builder.AppendLine(" Resident-Name Table Information:"); - builder.AppendLine(" -------------------------"); - if (ResidentNameTableOffset == 0 || ResidentNameTable == null || ResidentNameTable.Length == 0) - { - builder.AppendLine(" No resident-name table items"); - } - else - { - for (int i = 0; i < ResidentNameTable.Length; i++) - { - 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})"); - } - } - builder.AppendLine(); - } - - /// - /// Print module-reference table information - /// - /// StringBuilder to append information to - private void PrintModuleReferenceTable(StringBuilder builder) - { - builder.AppendLine(" Module-Reference Table Information:"); - builder.AppendLine(" -------------------------"); - if (ModuleReferenceTableSize == 0 || ModuleReferenceTable == null || ModuleReferenceTable.Length == 0) - { - builder.AppendLine(" No module-reference table items"); - } - else - { - for (int i = 0; i < ModuleReferenceTable.Length; i++) - { - // 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})"); - } - } - builder.AppendLine(); - } - - /// - /// Print imported-name table information - /// - /// StringBuilder to append information to - private void PrintImportedNameTable(StringBuilder builder) - { - builder.AppendLine(" Imported-Name Table Information:"); - builder.AppendLine(" -------------------------"); - if (ImportedNamesTableOffset == 0 || ImportedNameTable == null || ImportedNameTable.Count == 0) - { - builder.AppendLine(" No imported-name table items"); - } - else - { - 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]")}"); - } - } - builder.AppendLine(); - } - - /// - /// Print entry table information - /// - /// StringBuilder to append information to - private void PrintEntryTable(StringBuilder builder) - { - builder.AppendLine(" Entry Table Information:"); - builder.AppendLine(" -------------------------"); - if (EntryTableSize == 0 || EntryTable == null || EntryTable.Length == 0) - { - builder.AppendLine(" No entry table items"); - } - else - { - for (int i = 0; i < EntryTable.Length; i++) - { - 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()) - { - case SabreTools.Models.NewExecutable.SegmentEntryType.FixedSegment: - builder.AppendLine($" Flag word: {entry.FixedFlagWord} (0x{entry.FixedFlagWord:X})"); - builder.AppendLine($" Offset: {entry.FixedOffset} (0x{entry.FixedOffset:X})"); - break; - case SabreTools.Models.NewExecutable.SegmentEntryType.MoveableSegment: - builder.AppendLine($" Flag word: {entry.MoveableFlagWord} (0x{entry.MoveableFlagWord:X})"); - builder.AppendLine($" Reserved: {entry.MoveableReserved} (0x{entry.MoveableReserved:X})"); - builder.AppendLine($" Segment number: {entry.MoveableSegmentNumber} (0x{entry.MoveableSegmentNumber:X})"); - builder.AppendLine($" Offset: {entry.MoveableOffset} (0x{entry.MoveableOffset:X})"); - break; - } - } - } - builder.AppendLine(); - } - - /// - /// Print nonresident-name table information - /// - /// StringBuilder to append information to - private void PrintNonresidentNameTable(StringBuilder builder) - { - builder.AppendLine(" Nonresident-Name Table Information:"); - builder.AppendLine(" -------------------------"); - if (NonResidentNameTableSize == 0 || NonResidentNameTable == null || NonResidentNameTable.Length == 0) - { - builder.AppendLine(" No nonresident-name table items"); - } - else - { - for (int i = 0; i < NonResidentNameTable.Length; i++) - { - 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})"); - } - } - builder.AppendLine(); - } - #if NET6_0_OR_GREATER ///