Port NE to new printing

This commit is contained in:
Matt Nadareski
2023-09-15 00:21:12 -04:00
parent 43eed75635
commit 9a93c7b15d
3 changed files with 410 additions and 394 deletions

View File

@@ -25,6 +25,7 @@
<ItemGroup>
<PackageReference Include="SabreTools.Models" Version="1.1.1" />
<PackageReference Include="SabreTools.Serialization" Version="1.1.1" />
</ItemGroup>
</Project>

View File

@@ -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<ushort, ImportedNameTableEntry> entries)
#else
private static void Print(StringBuilder builder, Dictionary<ushort, ImportedNameTableEntry?>? 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();
}
}
}

View File

@@ -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;
}
/// <summary>
/// Print stub header information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print stub extended header information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print header information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print segment table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print resource table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print resident-name table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print module-reference table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print imported-name table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print entry table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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();
}
/// <summary>
/// Print nonresident-name table information
/// </summary>
/// <param name="builder">StringBuilder to append information to</param>
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
/// <inheritdoc/>