diff --git a/BurnOutSharp.Builders/LinearExecutable.cs b/BurnOutSharp.Builders/LinearExecutable.cs index e2ee9796..625063b3 100644 --- a/BurnOutSharp.Builders/LinearExecutable.cs +++ b/BurnOutSharp.Builders/LinearExecutable.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using BurnOutSharp.Models.LinearExecutable; using BurnOutSharp.Utilities; @@ -725,105 +724,104 @@ namespace BurnOutSharp.Builders else entry.SourceOffset = data.ReadUInt16(); - switch (entry.TargetFlags & FixupRecordTargetFlags.FixupTargetTypeMask) + // OBJECT / TRGOFF + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.InternalReference)) { - // OBJECT / TRGOFF - case FixupRecordTargetFlags.InternalReference: - - // 16-bit Object Number/Module Ordinal Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - entry.TargetObjectNumberWORD = data.ReadUInt16(); - else - entry.TargetObjectNumberByte = data.ReadByteValue(); - - // 16-bit Selector fixup - if (!entry.SourceType.HasFlag(FixupRecordSourceType.SixteenBitSelectorFixup)) - { - // 32-bit Target Offset Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - entry.TargetOffsetDWORD = data.ReadUInt32(); - else - entry.TargetOffsetWORD = data.ReadUInt16(); - } - - break; - - // MOD ORD# / IMPORT ORD / ADDITIVE - case FixupRecordTargetFlags.ImportedReferenceByOrdinal: - - // 16-bit Object Number/Module Ordinal Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); - else - entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); - - // 8-bit Ordinal Flag & 32-bit Target Offset Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.EightBitOrdinalFlag)) - entry.ImportedOrdinalNumberByte = data.ReadByteValue(); - else if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - entry.ImportedOrdinalNumberDWORD = data.ReadUInt32(); - else - entry.ImportedOrdinalNumberWORD = data.ReadUInt16(); - - // Additive Fixup Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) - { - // 32-bit Additive Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - entry.AdditiveFixupValueDWORD = data.ReadUInt32(); - else - entry.AdditiveFixupValueWORD = data.ReadUInt16(); - } - - break; - - // MOD ORD# / PROCEDURE NAME OFFSET / ADDITIVE - case FixupRecordTargetFlags.ImportedReferenceByName: - - // 16-bit Object Number/Module Ordinal Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); - else - entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + entry.TargetObjectNumberWORD = data.ReadUInt16(); + else + entry.TargetObjectNumberByte = data.ReadByteValue(); + // 16-bit Selector fixup + if (!entry.SourceType.HasFlag(FixupRecordSourceType.SixteenBitSelectorFixup)) + { // 32-bit Target Offset Flag if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) - entry.OffsetImportProcedureNameTableDWORD = data.ReadUInt32(); + entry.TargetOffsetDWORD = data.ReadUInt32(); else - entry.OffsetImportProcedureNameTableWORD = data.ReadUInt16(); + entry.TargetOffsetWORD = data.ReadUInt16(); + } + } - // Additive Fixup Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) - { - // 32-bit Additive Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - entry.AdditiveFixupValueDWORD = data.ReadUInt32(); - else - entry.AdditiveFixupValueWORD = data.ReadUInt16(); - } + // MOD ORD# / IMPORT ORD / ADDITIVE + else if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ImportedReferenceByOrdinal)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); + else + entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); - break; + // 8-bit Ordinal Flag & 32-bit Target Offset Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.EightBitOrdinalFlag)) + entry.ImportedOrdinalNumberByte = data.ReadByteValue(); + else if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) + entry.ImportedOrdinalNumberDWORD = data.ReadUInt32(); + else + entry.ImportedOrdinalNumberWORD = data.ReadUInt16(); - // ORD # / ADDITIVE - case FixupRecordTargetFlags.InternalReferenceViaEntryTable: - - // 16-bit Object Number/Module Ordinal Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) - entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + entry.AdditiveFixupValueDWORD = data.ReadUInt32(); else - entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); + entry.AdditiveFixupValueWORD = data.ReadUInt16(); + } + } - // Additive Fixup Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) - { - // 32-bit Additive Flag - if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) - entry.AdditiveFixupValueDWORD = data.ReadUInt32(); - else - entry.AdditiveFixupValueWORD = data.ReadUInt16(); - } + // MOD ORD# / PROCEDURE NAME OFFSET / ADDITIVE + else if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ImportedReferenceByName)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); + else + entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); - break; + // 32-bit Target Offset Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) + entry.OffsetImportProcedureNameTableDWORD = data.ReadUInt32(); + else + entry.OffsetImportProcedureNameTableWORD = data.ReadUInt16(); + + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + entry.AdditiveFixupValueDWORD = data.ReadUInt32(); + else + entry.AdditiveFixupValueWORD = data.ReadUInt16(); + } + } + + // ORD # / ADDITIVE + else if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.InternalReferenceViaEntryTable)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + entry.OrdinalIndexImportModuleNameTableWORD = data.ReadUInt16(); + else + entry.OrdinalIndexImportModuleNameTableByte = data.ReadByteValue(); + + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + entry.AdditiveFixupValueDWORD = data.ReadUInt32(); + else + entry.AdditiveFixupValueWORD = data.ReadUInt16(); + } + } + + // No other top-level flags recognized + else + { + return null; } #region SCROFFn diff --git a/BurnOutSharp.Wrappers/LinearExecutable.cs b/BurnOutSharp.Wrappers/LinearExecutable.cs index 112ceb66..94694918 100644 --- a/BurnOutSharp.Wrappers/LinearExecutable.cs +++ b/BurnOutSharp.Wrappers/LinearExecutable.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; namespace BurnOutSharp.Wrappers { @@ -222,16 +223,14 @@ namespace BurnOutSharp.Wrappers /// public Models.LinearExecutable.ObjectTableEntry[] ObjectTable => _executable.ObjectTable; - /// - public Models.LinearExecutable.ObjectPageMapEntry[] ObjectPageTable => _executable.ObjectPageMap; - - // TODO: Object iterate data map table [Does this exist?] + /// + public Models.LinearExecutable.ObjectPageMapEntry[] ObjectPageMap => _executable.ObjectPageMap; /// public Models.LinearExecutable.ResourceTableEntry[] ResourceTable => _executable.ResourceTable; - /// - public Models.LinearExecutable.ResidentNamesTableEntry[] ResidentNameTable => _executable.ResidentNamesTable; + /// + public Models.LinearExecutable.ResidentNamesTableEntry[] ResidentNamesTable => _executable.ResidentNamesTable; /// public Models.LinearExecutable.EntryTableBundle[] EntryTable => _executable.EntryTable; @@ -257,15 +256,21 @@ namespace BurnOutSharp.Wrappers /// public Models.LinearExecutable.ImportModuleProcedureNameTableEntry[] ImportModuleProcedureNameTable => _executable.ImportModuleProcedureNameTable; - // TODO: Preload Pages - // TODO: Demand Load Pages - // TODO: Iterated Pages + /// + public Models.LinearExecutable.NonResidentNamesTableEntry[] NonResidentNamesTable => _executable.NonResidentNamesTable; - /// - public Models.LinearExecutable.NonResidentNamesTableEntry[] NonResidentNameTable => _executable.NonResidentNamesTable; + #endregion - /// - public Models.LinearExecutable.DebugInformation DebugInformation => _executable.DebugInformation; + #region Debug Information + + /// + public string DI_Signature => _executable.DebugInformation?.Signature; + + /// + public Models.LinearExecutable.DebugFormatType? DI_FormatType => _executable.DebugInformation?.FormatType; + + /// + public byte[] DebuggerData => _executable.DebugInformation?.DebuggerData; #endregion @@ -345,7 +350,680 @@ namespace BurnOutSharp.Wrappers /// public override void Print() { - // TODO: Implement printing + Console.WriteLine("New Executable Information:"); + Console.WriteLine("-------------------------"); + Console.WriteLine(); + + // Stub + PrintStubHeader(); + PrintStubExtendedHeader(); + + // Information Block + PrintInformationBlock(); + + // Tables + PrintObjectTable(); + PrintObjectPageMap(); + PrintResourceTable(); + PrintResidentNamesTable(); + PrintEntryTable(); + PrintModuleFormatDirectivesTable(); + PrintVerifyRecordDirectiveTable(); + PrintFixupPageTable(); + PrintFixupRecordTable(); + PrintImportModuleNameTable(); + PrintImportModuleProcedureNameTable(); + PrintPerPageChecksumTable(); + PrintNonResidentNamesTable(); + + // Debug + PrintDebugInformation(); + } + + /// + /// Print stub header information + /// + private void PrintStubHeader() + { + Console.WriteLine(" MS-DOS Stub Header Information:"); + Console.WriteLine(" -------------------------"); + Console.WriteLine($" Magic number: {Stub_Magic}"); + Console.WriteLine($" Last page bytes: {Stub_LastPageBytes} (0x{Stub_LastPageBytes:X})"); + Console.WriteLine($" Pages: {Stub_Pages} (0x{Stub_Pages:X})"); + Console.WriteLine($" Relocation items: {Stub_RelocationItems} (0x{Stub_RelocationItems:X})"); + Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize} (0x{Stub_HeaderParagraphSize:X})"); + Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs} (0x{Stub_MinimumExtraParagraphs:X})"); + Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs} (0x{Stub_MaximumExtraParagraphs:X})"); + Console.WriteLine($" Initial SS value: {Stub_InitialSSValue} (0x{Stub_InitialSSValue:X})"); + Console.WriteLine($" Initial SP value: {Stub_InitialSPValue} (0x{Stub_InitialSPValue:X})"); + Console.WriteLine($" Checksum: {Stub_Checksum} (0x{Stub_Checksum:X})"); + Console.WriteLine($" Initial IP value: {Stub_InitialIPValue} (0x{Stub_InitialIPValue:X})"); + Console.WriteLine($" Initial CS value: {Stub_InitialCSValue} (0x{Stub_InitialCSValue:X})"); + Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr} (0x{Stub_RelocationTableAddr:X})"); + Console.WriteLine($" Overlay number: {Stub_OverlayNumber} (0x{Stub_OverlayNumber:X})"); + Console.WriteLine(); + } + + /// + /// Print stub extended header information + /// + private void PrintStubExtendedHeader() + { + Console.WriteLine(" MS-DOS Stub Extended Header Information:"); + Console.WriteLine(" -------------------------"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier} (0x{Stub_OEMIdentifier:X})"); + Console.WriteLine($" OEM information: {Stub_OEMInformation} (0x{Stub_OEMInformation:X})"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr} (0x{Stub_NewExeHeaderAddr:X})"); + Console.WriteLine(); + } + + /// + /// Print information block information + /// + private void PrintInformationBlock() + { + Console.WriteLine(" Information Block Information:"); + Console.WriteLine(" -------------------------"); + Console.WriteLine($" Signature: {Signature}"); + Console.WriteLine($" Byte order: {ByteOrder} (0x{ByteOrder:X})"); + Console.WriteLine($" Word order: {WordOrder} (0x{WordOrder:X})"); + Console.WriteLine($" Executable format level: {ExecutableFormatLevel} (0x{ExecutableFormatLevel:X})"); + Console.WriteLine($" CPU type: {CPUType} (0x{CPUType:X})"); + Console.WriteLine($" Module OS: {ModuleOS} (0x{ModuleOS:X})"); + Console.WriteLine($" Module version: {ModuleVersion} (0x{ModuleVersion:X})"); + Console.WriteLine($" Module type flags: {ModuleTypeFlags} (0x{ModuleTypeFlags:X})"); + Console.WriteLine($" Module number pages: {ModuleNumberPages} (0x{ModuleNumberPages:X})"); + Console.WriteLine($" Initial object CS: {InitialObjectCS} (0x{InitialObjectCS:X})"); + Console.WriteLine($" Initial EIP: {InitialEIP} (0x{InitialEIP:X})"); + Console.WriteLine($" Initial object SS: {InitialObjectSS} (0x{InitialObjectSS:X})"); + Console.WriteLine($" Initial ESP: {InitialESP} (0x{InitialESP:X})"); + Console.WriteLine($" Memory page size: {MemoryPageSize} (0x{MemoryPageSize:X})"); + Console.WriteLine($" Bytes on last page: {BytesOnLastPage} (0x{BytesOnLastPage:X})"); + Console.WriteLine($" Fix-up section size: {FixupSectionSize} (0x{FixupSectionSize:X})"); + Console.WriteLine($" Fix-up section checksum: {FixupSectionChecksum} (0x{FixupSectionChecksum:X})"); + Console.WriteLine($" Loader section size: {LoaderSectionSize} (0x{LoaderSectionSize:X})"); + Console.WriteLine($" Loader section checksum: {LoaderSectionChecksum} (0x{LoaderSectionChecksum:X})"); + Console.WriteLine($" Object table offset: {ObjectTableOffset} (0x{ObjectTableOffset:X})"); + Console.WriteLine($" Object table count: {ObjectTableCount} (0x{ObjectTableCount:X})"); + Console.WriteLine($" Object page map offset: {ObjectPageMapOffset} (0x{ObjectPageMapOffset:X})"); + Console.WriteLine($" Object iterate data map offset: {ObjectIterateDataMapOffset} (0x{ObjectIterateDataMapOffset:X})"); + Console.WriteLine($" Resource table offset: {ResourceTableOffset} (0x{ResourceTableOffset:X})"); + Console.WriteLine($" Resource table count: {ResourceTableCount} (0x{ResourceTableCount:X})"); + Console.WriteLine($" Resident names table offset: {ResidentNamesTableOffset} (0x{ResidentNamesTableOffset:X})"); + Console.WriteLine($" Entry table offset: {EntryTableOffset} (0x{EntryTableOffset:X})"); + Console.WriteLine($" Module directives table offset: {ModuleDirectivesTableOffset} (0x{ModuleDirectivesTableOffset:X})"); + Console.WriteLine($" Module directives table count: {ModuleDirectivesCount} (0x{ModuleDirectivesCount:X})"); + Console.WriteLine($" Fix-up page table offset: {FixupPageTableOffset} (0x{FixupPageTableOffset:X})"); + Console.WriteLine($" Fix-up record table offset: {FixupRecordTableOffset} (0x{FixupRecordTableOffset:X})"); + Console.WriteLine($" Imported modules name table offset: {ImportedModulesNameTableOffset} (0x{ImportedModulesNameTableOffset:X})"); + Console.WriteLine($" Imported modules count: {ImportedModulesCount} (0x{ImportedModulesCount:X})"); + Console.WriteLine($" Imported procedure name table count: {ImportProcedureNameTableOffset} (0x{ImportProcedureNameTableOffset:X})"); + Console.WriteLine($" Per-page checksum table offset: {PerPageChecksumTableOffset} (0x{PerPageChecksumTableOffset:X})"); + Console.WriteLine($" Data pages offset: {DataPagesOffset} (0x{DataPagesOffset:X})"); + Console.WriteLine($" Preload page count: {PreloadPageCount} (0x{PreloadPageCount:X})"); + Console.WriteLine($" Non-resident names table offset: {NonResidentNamesTableOffset} (0x{NonResidentNamesTableOffset:X})"); + Console.WriteLine($" Non-resident names table length: {NonResidentNamesTableLength} (0x{NonResidentNamesTableLength:X})"); + Console.WriteLine($" Non-resident names table checksum: {NonResidentNamesTableChecksum} (0x{NonResidentNamesTableChecksum:X})"); + Console.WriteLine($" Automatic data object: {AutomaticDataObject} (0x{AutomaticDataObject:X})"); + Console.WriteLine($" Debug information offset: {DebugInformationOffset} (0x{DebugInformationOffset:X})"); + Console.WriteLine($" Debug information length: {DebugInformationLength} (0x{DebugInformationLength:X})"); + Console.WriteLine($" Preload instance pages number: {PreloadInstancePagesNumber} (0x{PreloadInstancePagesNumber:X})"); + Console.WriteLine($" Demand instance pages number: {DemandInstancePagesNumber} (0x{DemandInstancePagesNumber:X})"); + Console.WriteLine($" Extra heap allocation: {ExtraHeapAllocation} (0x{ExtraHeapAllocation:X})"); + Console.WriteLine(); + } + + /// + /// Print object table information + /// + private void PrintObjectTable() + { + Console.WriteLine(" Object Table Information:"); + Console.WriteLine(" -------------------------"); + if (ObjectTable == null || ObjectTable.Length == 0) + { + Console.WriteLine(" No object table entries"); + } + else + { + for (int i = 0; i < ObjectTable.Length; i++) + { + var entry = ObjectTable[i]; + Console.WriteLine($" Object Table Entry {i}"); + Console.WriteLine($" Virtual segment size: {entry.VirtualSegmentSize} (0x{entry.VirtualSegmentSize:X})"); + Console.WriteLine($" Relocation base address: {entry.RelocationBaseAddress} (0x{entry.RelocationBaseAddress:X})"); + Console.WriteLine($" Object flags: {entry.ObjectFlags} (0x{entry.ObjectFlags:X})"); + Console.WriteLine($" Page table index: {entry.PageTableIndex} (0x{entry.PageTableIndex:X})"); + Console.WriteLine($" Page table entries: {entry.PageTableEntries} (0x{entry.PageTableEntries:X})"); + Console.WriteLine($" Reserved: {entry.Reserved} (0x{entry.Reserved:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print object page map information + /// + private void PrintObjectPageMap() + { + Console.WriteLine(" Object Page Map Information:"); + Console.WriteLine(" -------------------------"); + if (ObjectPageMap == null || ObjectPageMap.Length == 0) + { + Console.WriteLine(" No object page map entries"); + } + else + { + for (int i = 0; i < ObjectPageMap.Length; i++) + { + var entry = ObjectPageMap[i]; + Console.WriteLine($" Object Page Map Entry {i}"); + Console.WriteLine($" Page data offset: {entry.PageDataOffset} (0x{entry.PageDataOffset:X})"); + Console.WriteLine($" Data size: {entry.DataSize} (0x{entry.DataSize:X})"); + Console.WriteLine($" Flags: {entry.Flags} (0x{entry.Flags:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print resource table information + /// + private void PrintResourceTable() + { + Console.WriteLine(" Resource Table Information:"); + Console.WriteLine(" -------------------------"); + if (ResourceTable == null || ResourceTable.Length == 0) + { + Console.WriteLine(" No resource table entries"); + } + else + { + for (int i = 0; i < ResourceTable.Length; i++) + { + var entry = ResourceTable[i]; + Console.WriteLine($" Resource Table Entry {i}"); + Console.WriteLine($" Type ID: {entry.TypeID} (0x{entry.TypeID:X})"); + Console.WriteLine($" Name ID: {entry.NameID} (0x{entry.NameID:X})"); + Console.WriteLine($" Resource size: {entry.ResourceSize} (0x{entry.ResourceSize:X})"); + Console.WriteLine($" Object number: {entry.ObjectNumber} (0x{entry.ObjectNumber:X})"); + Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print resident names table information + /// + private void PrintResidentNamesTable() + { + Console.WriteLine(" Resident Names Table Information:"); + Console.WriteLine(" -------------------------"); + if (ResidentNamesTable == null || ResidentNamesTable.Length == 0) + { + Console.WriteLine(" No resident names table entries"); + } + else + { + for (int i = 0; i < ResidentNamesTable.Length; i++) + { + var entry = ResidentNamesTable[i]; + Console.WriteLine($" Resident Names Table Entry {i}"); + Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); + Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print entry table information + /// + private void PrintEntryTable() + { + Console.WriteLine(" Entry Table Information:"); + Console.WriteLine(" -------------------------"); + if (EntryTable == null || EntryTable.Length == 0) + { + Console.WriteLine(" No entry table bundles"); + } + else + { + for (int i = 0; i < EntryTable.Length; i++) + { + var bundle = EntryTable[i]; + Console.WriteLine($" Entry Table Bundle {i}"); + Console.WriteLine($" Entries: {bundle.Entries} (0x{bundle.Entries:X})"); + Console.WriteLine($" Bundle type: {bundle.BundleType} (0x{bundle.BundleType:X})"); + if (bundle.TableEntries != null && bundle.TableEntries.Length != 0) + { + Console.WriteLine(); + Console.WriteLine($" Entry Table Entries:"); + Console.WriteLine(" -------------------------"); + for (int j = 0; j < bundle.TableEntries.Length; j++) + { + var entry = bundle.TableEntries[j]; + Console.WriteLine($" Entry Table Entry {j}"); + switch (bundle.BundleType & ~Models.LinearExecutable.BundleType.ParameterTypingInformationPresent) + { + case Models.LinearExecutable.BundleType.UnusedEntry: + Console.WriteLine($" Unused, empty entry"); + break; + + case Models.LinearExecutable.BundleType.SixteenBitEntry: + Console.WriteLine($" Object number: {entry.SixteenBitObjectNumber} (0x{entry.SixteenBitObjectNumber:X})"); + Console.WriteLine($" Entry flags: {entry.SixteenBitEntryFlags} (0x{entry.SixteenBitEntryFlags:X})"); + Console.WriteLine($" Offset: {entry.SixteenBitOffset} (0x{entry.SixteenBitOffset:X})"); + break; + + case Models.LinearExecutable.BundleType.TwoEightySixCallGateEntry: + Console.WriteLine($" Object number: {entry.TwoEightySixObjectNumber} (0x{entry.TwoEightySixObjectNumber:X})"); + Console.WriteLine($" Entry flags: {entry.TwoEightySixEntryFlags} (0x{entry.TwoEightySixEntryFlags:X})"); + Console.WriteLine($" Offset: {entry.TwoEightySixOffset} (0x{entry.TwoEightySixOffset:X})"); + Console.WriteLine($" Callgate: {entry.TwoEightySixCallgate} (0x{entry.TwoEightySixCallgate:X})"); + break; + + case Models.LinearExecutable.BundleType.ThirtyTwoBitEntry: + Console.WriteLine($" Object number: {entry.ThirtyTwoBitObjectNumber} (0x{entry.ThirtyTwoBitObjectNumber:X})"); + Console.WriteLine($" Entry flags: {entry.ThirtyTwoBitEntryFlags} (0x{entry.ThirtyTwoBitEntryFlags:X})"); + Console.WriteLine($" Offset: {entry.ThirtyTwoBitOffset} (0x{entry.ThirtyTwoBitOffset:X})"); + break; + + case Models.LinearExecutable.BundleType.ForwarderEntry: + Console.WriteLine($" Reserved: {entry.ForwarderReserved} (0x{entry.ForwarderReserved:X})"); + Console.WriteLine($" Forwarder flags: {entry.ForwarderFlags} (0x{entry.ForwarderFlags:X})"); + Console.WriteLine($" Module ordinal number: {entry.ForwarderModuleOrdinalNumber} (0x{entry.ForwarderModuleOrdinalNumber:X})"); + Console.WriteLine($" Procedure name offset: {entry.ProcedureNameOffset} (0x{entry.ProcedureNameOffset:X})"); + Console.WriteLine($" Import ordinal number: {entry.ImportOrdinalNumber} (0x{entry.ImportOrdinalNumber:X})"); + break; + + default: + Console.WriteLine($" Unknown entry type {bundle.BundleType}"); + break; + } + } + } + } + } + Console.WriteLine(); + } + + /// + /// Print module format directives table information + /// + private void PrintModuleFormatDirectivesTable() + { + Console.WriteLine(" Module Format Directives Table Information:"); + Console.WriteLine(" -------------------------"); + if (ModuleFormatDirectivesTable == null || ModuleFormatDirectivesTable.Length == 0) + { + Console.WriteLine(" No module format directives table entries"); + } + else + { + for (int i = 0; i < ModuleFormatDirectivesTable.Length; i++) + { + var entry = ModuleFormatDirectivesTable[i]; + Console.WriteLine($" Moduile Format Directives Table Entry {i}"); + Console.WriteLine($" Directive number: {entry.DirectiveNumber} (0x{entry.DirectiveNumber:X})"); + Console.WriteLine($" Directive data length: {entry.DirectiveDataLength} (0x{entry.DirectiveDataLength:X})"); + Console.WriteLine($" Directive data offset: {entry.DirectiveDataOffset} (0x{entry.DirectiveDataOffset:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print verify record directive table information + /// + private void PrintVerifyRecordDirectiveTable() + { + Console.WriteLine(" Verify Record Directive Table Information:"); + Console.WriteLine(" -------------------------"); + if (VerifyRecordDirectiveTable == null || VerifyRecordDirectiveTable.Length == 0) + { + Console.WriteLine(" No verify record directive table entries"); + } + else + { + for (int i = 0; i < VerifyRecordDirectiveTable.Length; i++) + { + var entry = VerifyRecordDirectiveTable[i]; + Console.WriteLine($" Verify Record Directive Table Entry {i}"); + Console.WriteLine($" Entry count: {entry.EntryCount} (0x{entry.EntryCount:X})"); + Console.WriteLine($" Ordinal index: {entry.OrdinalIndex} (0x{entry.OrdinalIndex:X})"); + Console.WriteLine($" Version: {entry.Version} (0x{entry.Version:X})"); + Console.WriteLine($" Object entries count: {entry.ObjectEntriesCount} (0x{entry.ObjectEntriesCount:X})"); + Console.WriteLine($" Object number in module: {entry.ObjectNumberInModule} (0x{entry.ObjectNumberInModule:X})"); + Console.WriteLine($" Object load base address: {entry.ObjectLoadBaseAddress} (0x{entry.ObjectLoadBaseAddress:X})"); + Console.WriteLine($" Object virtual address size: {entry.ObjectVirtualAddressSize} (0x{entry.ObjectVirtualAddressSize:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print fix-up page table information + /// + private void PrintFixupPageTable() + { + Console.WriteLine(" Fix-up Page Table Information:"); + Console.WriteLine(" -------------------------"); + if (FixupPageTable == null || FixupPageTable.Length == 0) + { + Console.WriteLine(" No fix-up page table entries"); + } + else + { + for (int i = 0; i < FixupPageTable.Length; i++) + { + var entry = FixupPageTable[i]; + Console.WriteLine($" Fix-up Page Table Entry {i}"); + Console.WriteLine($" Offset: {entry.Offset} (0x{entry.Offset:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print fix-up record table information + /// + private void PrintFixupRecordTable() + { + Console.WriteLine(" Fix-up Record Table Information:"); + Console.WriteLine(" -------------------------"); + if (FixupRecordTable == null || FixupRecordTable.Length == 0) + { + Console.WriteLine(" No fix-up record table entries"); + Console.WriteLine(); + } + else + { + for (int i = 0; i < FixupRecordTable.Length; i++) + { + var entry = FixupRecordTable[i]; + Console.WriteLine($" Fix-up Record Table Entry {i}"); + Console.WriteLine($" Source type: {entry.SourceType} (0x{entry.SourceType:X})"); + Console.WriteLine($" Target flags: {entry.TargetFlags} (0x{entry.TargetFlags:X})"); + + // Source list flag + if (entry.SourceType.HasFlag(Models.LinearExecutable.FixupRecordSourceType.SourceListFlag)) + Console.WriteLine($" Source offset list count: {entry.SourceOffsetListCount} (0x{entry.SourceOffsetListCount:X})"); + else + Console.WriteLine($" Source offset: {entry.SourceOffset} (0x{entry.SourceOffset:X})"); + + // OBJECT / TRGOFF + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.InternalReference)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + Console.WriteLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); + else + Console.WriteLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); + + // 16-bit Selector fixup + if (!entry.SourceType.HasFlag(Models.LinearExecutable.FixupRecordSourceType.SixteenBitSelectorFixup)) + { + // 32-bit Target Offset Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) + Console.WriteLine($" Target offset: {entry.TargetOffsetDWORD} (0x{entry.TargetOffsetDWORD:X})"); + else + Console.WriteLine($" Target offset: {entry.TargetOffsetWORD} (0x{entry.TargetOffsetWORD:X})"); + } + } + + // MOD ORD# / IMPORT ORD / ADDITIVE + else if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ImportedReferenceByOrdinal)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + else + Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + + // 8-bit Ordinal Flag & 32-bit Target Offset Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.EightBitOrdinalFlag)) + Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberByte} (0x{entry.ImportedOrdinalNumberByte:X})"); + else if (entry.TargetFlags.HasFlag(flag: Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) + Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberDWORD} (0x{entry.ImportedOrdinalNumberDWORD:X})"); + else + Console.WriteLine(value: $" Imported ordinal number: {entry.ImportedOrdinalNumberWORD} (0x{entry.ImportedOrdinalNumberWORD:X})"); + + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + else + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + } + } + + // MOD ORD# / PROCEDURE NAME OFFSET / ADDITIVE + else if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ImportedReferenceByName)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableWORD} (0x{entry.OrdinalIndexImportModuleNameTableWORD:X})"); + else + Console.WriteLine(value: $" Ordinal index import module name table: {entry.OrdinalIndexImportModuleNameTableByte} (0x{entry.OrdinalIndexImportModuleNameTableByte:X})"); + + // 32-bit Target Offset Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitTargetOffsetFlag)) + Console.WriteLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableDWORD} (0x{entry.OffsetImportProcedureNameTableDWORD:X})"); + else + Console.WriteLine(value: $" Offset import procedure name table: {entry.OffsetImportProcedureNameTableWORD} (0x{entry.OffsetImportProcedureNameTableWORD:X})"); + + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + else + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + } + } + + // ORD # / ADDITIVE + else if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.InternalReferenceViaEntryTable)) + { + // 16-bit Object Number/Module Ordinal Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.SixteenBitObjectNumberModuleOrdinalFlag)) + Console.WriteLine($" Target object number: {entry.TargetObjectNumberWORD} (0x{entry.TargetObjectNumberWORD:X})"); + else + Console.WriteLine($" Target object number: {entry.TargetObjectNumberByte} (0x{entry.TargetObjectNumberByte:X})"); + + // Additive Fixup Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.AdditiveFixupFlag)) + { + // 32-bit Additive Flag + if (entry.TargetFlags.HasFlag(Models.LinearExecutable.FixupRecordTargetFlags.ThirtyTwoBitAdditiveFixupFlag)) + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueDWORD} (0x{entry.AdditiveFixupValueDWORD:X})"); + else + Console.WriteLine(value: $" Additive fixup value: {entry.AdditiveFixupValueWORD} (0x{entry.AdditiveFixupValueWORD:X})"); + } + } + + // No other top-level flags recognized + else + { + Console.WriteLine($" Unknown entry format"); + } + + Console.WriteLine(); + Console.WriteLine($" Source Offset List:"); + Console.WriteLine(" -------------------------"); + if (entry.SourceOffsetList == null || entry.SourceOffsetList.Length == 0) + { + Console.WriteLine($" No source offset list entries"); + } + else + { + for (int j = 0; j < entry.SourceOffsetList.Length; j++) + { + Console.WriteLine($" Source Offset List Entry {j}: {entry.SourceOffsetList[j]} (0x{entry.SourceOffsetList[j]:X})"); + } + } + Console.WriteLine(); + } + } + } + + /// + /// Print import module name table information + /// + private void PrintImportModuleNameTable() + { + Console.WriteLine(" Import Module Name Table Information:"); + Console.WriteLine(" -------------------------"); + if (ImportModuleNameTable == null || ImportModuleNameTable.Length == 0) + { + Console.WriteLine(" No import module name table entries"); + } + else + { + for (int i = 0; i < ImportModuleNameTable.Length; i++) + { + var entry = ImportModuleNameTable[i]; + Console.WriteLine($" Import Module Name Table Entry {i}"); + Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); + Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + } + } + Console.WriteLine(); + } + + /// + /// Print import module procedure name table information + /// + private void PrintImportModuleProcedureNameTable() + { + Console.WriteLine(" Import Module Procedure Name Table Information:"); + Console.WriteLine(" -------------------------"); + if (ImportModuleProcedureNameTable == null || ImportModuleProcedureNameTable.Length == 0) + { + Console.WriteLine(" No import module procedure name table entries"); + } + else + { + for (int i = 0; i < ImportModuleProcedureNameTable.Length; i++) + { + var entry = ImportModuleProcedureNameTable[i]; + Console.WriteLine($" Import Module Procedure Name Table Entry {i}"); + Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); + Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + } + } + Console.WriteLine(); + } + + /// + /// Print per-page checksum table information + /// + private void PrintPerPageChecksumTable() + { + Console.WriteLine(" Per-Page Checksum Table Information:"); + Console.WriteLine(" -------------------------"); + if (PerPageChecksumTable == null || PerPageChecksumTable.Length == 0) + { + Console.WriteLine(" No per-page checksum table entries"); + } + else + { + for (int i = 0; i < PerPageChecksumTable.Length; i++) + { + var entry = PerPageChecksumTable[i]; + Console.WriteLine($" Per-Page Checksum Table Entry {i}"); + Console.WriteLine($" Checksum: {entry.Checksum} (0x{entry.Checksum:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print non-resident names table information + /// + private void PrintNonResidentNamesTable() + { + Console.WriteLine(" Non-Resident Names Table Information:"); + Console.WriteLine(" -------------------------"); + if (NonResidentNamesTable == null || NonResidentNamesTable.Length == 0) + { + Console.WriteLine(" No non-resident names table entries"); + } + else + { + for (int i = 0; i < NonResidentNamesTable.Length; i++) + { + var entry = NonResidentNamesTable[i]; + Console.WriteLine($" Non-Resident Names Table Entry {i}"); + Console.WriteLine($" Length: {entry.Length} (0x{entry.Length:X})"); + Console.WriteLine($" Name: {entry.Name ?? "[NULL]"}"); + Console.WriteLine($" Ordinal number: {entry.OrdinalNumber} (0x{entry.OrdinalNumber:X})"); + } + } + Console.WriteLine(); + } + + /// + /// Print debug information + /// + private void PrintDebugInformation() + { + Console.WriteLine(" Debug Information:"); + Console.WriteLine(" -------------------------"); + if (_executable.DebugInformation == null) + { + Console.WriteLine(" No debug information"); + } + else + { + Console.WriteLine($" Signature: {DI_Signature ?? "[NULL]"}"); + Console.WriteLine($" Format type: {DI_FormatType} (0x{DI_FormatType:X})"); + // Debugger data + } + Console.WriteLine(); + } + + #endregion + + #region REMOVE -- DO NOT USE + + /// + /// Read an arbitrary range from the source + /// + /// The start of where to read data from, -1 means start of source + /// How many bytes to read, -1 means read until end + /// Byte array representing the range, null on error + [Obsolete] + public byte[] ReadArbitraryRange(int rangeStart = -1, int length = -1) + { + // If we have an unset range start, read from the start of the source + if (rangeStart == -1) + rangeStart = 0; + + // If we have an unset length, read the whole source + if (length == -1) + { + switch (_dataSource) + { + case DataSource.ByteArray: + length = _byteArrayData.Length - _byteArrayOffset; + break; + + case DataSource.Stream: + length = (int)_streamData.Length; + break; + } + } + + return ReadFromDataSource(rangeStart, length); } #endregion