diff --git a/.vscode/launch.json b/.vscode/launch.json index c01089cb..0537e888 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/Test/bin/Debug/netcoreapp3.1/Test.dll", + "program": "${workspaceFolder}/Test/bin/Debug/net6.0/Test.dll", "args": [], "cwd": "${workspaceFolder}/Test", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console diff --git a/BurnOutSharp.Builder/Extensions.cs b/BurnOutSharp.Builder/Extensions.cs index b1436181..7c467283 100644 --- a/BurnOutSharp.Builder/Extensions.cs +++ b/BurnOutSharp.Builder/Extensions.cs @@ -25,7 +25,7 @@ namespace BurnOutSharp.Builder public static byte[] ReadBytes(this byte[] content, ref int offset, int count) { // If there's an invalid byte count, don't do anything - if (count == 0) + if (count <= 0) return null; byte[] buffer = new byte[count]; @@ -163,7 +163,7 @@ namespace BurnOutSharp.Builder public static byte[] ReadBytes(this Stream stream, int count) { // If there's an invalid byte count, don't do anything - if (count == 0) + if (count <= 0) return null; byte[] buffer = new byte[count]; @@ -1220,9 +1220,6 @@ namespace BurnOutSharp.Builder // Create the output table var stringTable = new Dictionary(); - // Create the string encoding - Encoding stringEncoding = (entry.Codepage != 0 ? Encoding.GetEncoding((int)entry.Codepage) : Encoding.Unicode); - // Loop through and add while (offset < entry.Data.Length) { @@ -1233,17 +1230,9 @@ namespace BurnOutSharp.Builder } else { - string fullEncodedString = stringEncoding.GetString(entry.Data, offset, entry.Data.Length - offset); - if (stringLength > fullEncodedString.Length) - { - // TODO: Do something better than print to console - Console.WriteLine($"Requested {stringLength} but only have {fullEncodedString.Length} remaining, truncating..."); - stringLength = (ushort)fullEncodedString.Length; - } - - string stringValue = fullEncodedString.Substring(0, stringLength); - offset += stringEncoding.GetByteCount(stringValue); - stringValue = stringValue.Replace("\n", "\\n").Replace("\r", "\\r"); + string stringValue = Encoding.Unicode.GetString(entry.Data, offset, stringLength * 2); + offset += stringLength * 2; + stringValue = stringValue.Replace("\n", "\\n").Replace("\r", newValue: "\\r"); stringTable[stringIndex++] = stringValue; } } diff --git a/BurnOutSharp.Builder/PortableExecutable.cs b/BurnOutSharp.Builder/PortableExecutable.cs index 5c6383fa..b8b28179 100644 --- a/BurnOutSharp.Builder/PortableExecutable.cs +++ b/BurnOutSharp.Builder/PortableExecutable.cs @@ -175,6 +175,29 @@ namespace BurnOutSharp.Builder #endregion + #region Base Relocation Table + + // Should also be in a '.reloc' section + if (optionalHeader.BaseRelocationTable != null && optionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable) != 0) + { + // If the offset for the base relocation table doesn't exist + int baseRelocationTableAddress = initialOffset + + (int)optionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable); + if (baseRelocationTableAddress >= data.Length) + return executable; + + // Try to parse the base relocation table + int endOffset = (int)(baseRelocationTableAddress + optionalHeader.BaseRelocationTable.Size); + var baseRelocationTable = ParseBaseRelocationTable(data, baseRelocationTableAddress, endOffset, executable.SectionTable); + if (baseRelocationTable == null) + return null; + + // Set the base relocation table + executable.BaseRelocationTable = baseRelocationTable; + } + + #endregion + #region Debug Table // Should also be in a '.debug' section @@ -700,20 +723,22 @@ namespace BurnOutSharp.Builder { var attributeCertificateTable = new List(); - while (offset < endOffset) + while (offset < endOffset && offset != data.Length) { var entry = new AttributeCertificateTableEntry(); entry.Length = data.ReadUInt32(ref offset); entry.Revision = (WindowsCertificateRevision)data.ReadUInt16(ref offset); entry.CertificateType = (WindowsCertificateType)data.ReadUInt16(ref offset); - if (entry.Length > 0) - entry.Certificate = data.ReadBytes(ref offset, (int)entry.Length - 8); + + int certificateDataLength = (int)(entry.Length - 8); + if (certificateDataLength > 0) + entry.Certificate = data.ReadBytes(ref offset, certificateDataLength); attributeCertificateTable.Add(entry); // Align to the 8-byte boundary - while ((offset % 8) != 0) + while ((offset % 8) != 0 && offset < endOffset - 1 && offset != data.Length) _ = data.ReadByte(ref offset); } @@ -744,7 +769,49 @@ namespace BurnOutSharp.Builder } /// - /// Parse a Stream into a debug table + /// Parse a byte array into a base relocation table + /// + /// Byte array to parse + /// Offset into the byte array + /// First address not part of the base relocation table + /// Section table to use for virtual address translation + /// Filled base relocation table on success, null on error + private static BaseRelocationBlock[] ParseBaseRelocationTable(byte[] data, int offset, int endOffset, SectionHeader[] sections) + { + // TODO: Use marshalling here instead of building + var baseRelocationTable = new List(); + + while (offset < endOffset) + { + var baseRelocationBlock = new BaseRelocationBlock(); + + baseRelocationBlock.PageRVA = data.ReadUInt32(ref offset); + baseRelocationBlock.BlockSize = data.ReadUInt32(ref offset); + + var typeOffsetFieldEntries = new List(); + int totalSize = 8; + while (totalSize < baseRelocationBlock.BlockSize) + { + var baseRelocationTypeOffsetFieldEntry = new BaseRelocationTypeOffsetFieldEntry(); + + ushort typeAndOffsetField = data.ReadUInt16(ref offset); + baseRelocationTypeOffsetFieldEntry.BaseRelocationType = (BaseRelocationTypes)(typeAndOffsetField >> 12); + baseRelocationTypeOffsetFieldEntry.Offset = (ushort)(typeAndOffsetField & 0x0FFF); + + typeOffsetFieldEntries.Add(baseRelocationTypeOffsetFieldEntry); + totalSize += 2; + } + + baseRelocationBlock.TypeOffsetFieldEntries = typeOffsetFieldEntries.ToArray(); + + baseRelocationTable.Add(baseRelocationBlock); + } + + return baseRelocationTable.ToArray(); + } + + /// + /// Parse a byte array into a debug table /// /// Byte array to parse /// Offset into the byte array @@ -1327,6 +1394,30 @@ namespace BurnOutSharp.Builder #endregion + #region Base Relocation Table + + // Should also be in a '.reloc' section + if (optionalHeader.BaseRelocationTable != null && optionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable) != 0) + { + // If the offset for the base relocation table doesn't exist + int baseRelocationTableAddress = initialOffset + + (int)optionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable); + if (baseRelocationTableAddress >= data.Length) + return executable; + + // Try to parse the base relocation table + data.Seek(baseRelocationTableAddress, SeekOrigin.Begin); + int endOffset = (int)(baseRelocationTableAddress + optionalHeader.BaseRelocationTable.Size); + var baseRelocationTable = ParseBaseRelocationTable(data, endOffset, executable.SectionTable); + if (baseRelocationTable == null) + return null; + + // Set the base relocation table + executable.BaseRelocationTable = baseRelocationTable; + } + + #endregion + #region Debug Table // Should also be in a '.debug' section @@ -1849,20 +1940,22 @@ namespace BurnOutSharp.Builder { var attributeCertificateTable = new List(); - while (data.Position < endOffset) + while (data.Position < endOffset && data.Position != data.Length) { var entry = new AttributeCertificateTableEntry(); entry.Length = data.ReadUInt32(); entry.Revision = (WindowsCertificateRevision)data.ReadUInt16(); entry.CertificateType = (WindowsCertificateType)data.ReadUInt16(); - if (entry.Length > 0) - entry.Certificate = data.ReadBytes((int)entry.Length - 8); + + int certificateDataLength = (int)(entry.Length - 8); + if (certificateDataLength > 0) + entry.Certificate = data.ReadBytes(certificateDataLength); attributeCertificateTable.Add(entry); // Align to the 8-byte boundary - while ((data.Position % 8) != 0) + while ((data.Position % 8) != 0 && data.Position < endOffset && data.Position != data.Length) _ = data.ReadByteValue(); } @@ -1891,6 +1984,47 @@ namespace BurnOutSharp.Builder return delayLoadDirectoryTable; } + /// + /// Parse a Stream into a base relocation table + /// + /// Stream to parse + /// First address not part of the base relocation table + /// Section table to use for virtual address translation + /// Filled base relocation table on success, null on error + private static BaseRelocationBlock[] ParseBaseRelocationTable(Stream data, int endOffset, SectionHeader[] sections) + { + // TODO: Use marshalling here instead of building + var baseRelocationTable = new List(); + + while (data.Position < endOffset) + { + var baseRelocationBlock = new BaseRelocationBlock(); + + baseRelocationBlock.PageRVA = data.ReadUInt32(); + baseRelocationBlock.BlockSize = data.ReadUInt32(); + + var typeOffsetFieldEntries = new List(); + int totalSize = 8; + while (totalSize < baseRelocationBlock.BlockSize) + { + var baseRelocationTypeOffsetFieldEntry = new BaseRelocationTypeOffsetFieldEntry(); + + ushort typeAndOffsetField = data.ReadUInt16(); + baseRelocationTypeOffsetFieldEntry.BaseRelocationType = (BaseRelocationTypes)(typeAndOffsetField >> 12); + baseRelocationTypeOffsetFieldEntry.Offset = (ushort)(typeAndOffsetField & 0x0FFF); + + typeOffsetFieldEntries.Add(baseRelocationTypeOffsetFieldEntry); + totalSize += 2; + } + + baseRelocationBlock.TypeOffsetFieldEntries = typeOffsetFieldEntries.ToArray(); + + baseRelocationTable.Add(baseRelocationBlock); + } + + return baseRelocationTable.ToArray(); + } + /// /// Parse a Stream into a debug table /// @@ -2250,51 +2384,49 @@ namespace BurnOutSharp.Builder resourceDirectoryTable.NumberOfNameEntries = data.ReadUInt16(); resourceDirectoryTable.NumberOfIDEntries = data.ReadUInt16(); - // Perform top-level pass of data + // If we have no entries int totalEntryCount = resourceDirectoryTable.NumberOfNameEntries + resourceDirectoryTable.NumberOfIDEntries; - if (totalEntryCount > 0) + if (totalEntryCount == 0) + return resourceDirectoryTable; + + // Perform top-level pass of data + resourceDirectoryTable.Entries = new ResourceDirectoryEntry[totalEntryCount]; + for (int i = 0; i < totalEntryCount; i++) { - resourceDirectoryTable.Entries = new ResourceDirectoryEntry[totalEntryCount]; - for (int i = 0; i < totalEntryCount; i++) + var entry = new ResourceDirectoryEntry(); + uint offset = data.ReadUInt32(); + if ((offset & 0x80000000) != 0) + entry.NameOffset = offset & ~0x80000000; + else + entry.IntegerID = offset; + + offset = data.ReadUInt32(); + if ((offset & 0x80000000) != 0) + entry.SubdirectoryOffset = offset & ~0x80000000; + else + entry.DataEntryOffset = offset; + + // Read the name from the offset, if needed + if (entry.NameOffset != default) { - var entry = new ResourceDirectoryEntry(); - uint offset = data.ReadUInt32(); - if ((offset & 0x80000000) != 0) - entry.NameOffset = offset & ~0x80000000; - else - entry.IntegerID = offset; - - offset = data.ReadUInt32(); - if ((offset & 0x80000000) != 0) - entry.SubdirectoryOffset = offset & ~0x80000000; - else - entry.DataEntryOffset = offset; - - // Read the name from the offset, if needed - if (entry.NameOffset != default) - { - long currentOffset = data.Position; - offset = entry.NameOffset + (uint)initialOffset; - data.Seek(offset, SeekOrigin.Begin); - var resourceDirectoryString = new ResourceDirectoryString(); - resourceDirectoryString.Length = data.ReadUInt16(); - resourceDirectoryString.UnicodeString = data.ReadBytes(resourceDirectoryString.Length * 2); - entry.Name = resourceDirectoryString; - data.Seek(currentOffset, SeekOrigin.Begin); - } - - resourceDirectoryTable.Entries[i] = entry; + long currentOffset = data.Position; + offset = entry.NameOffset + (uint)initialOffset; + data.Seek(offset, SeekOrigin.Begin); + var resourceDirectoryString = new ResourceDirectoryString(); + resourceDirectoryString.Length = data.ReadUInt16(); + resourceDirectoryString.UnicodeString = data.ReadBytes(resourceDirectoryString.Length * 2); + entry.Name = resourceDirectoryString; + data.Seek(currentOffset, SeekOrigin.Begin); } + + resourceDirectoryTable.Entries[i] = entry; } - // Read all leaves at this level - if (totalEntryCount > 0) + // Loop through and process the entries + foreach (var entry in resourceDirectoryTable.Entries) { - foreach (var entry in resourceDirectoryTable.Entries) + if (entry.DataEntryOffset != 0) { - if (entry.SubdirectoryOffset != 0) - continue; - uint offset = entry.DataEntryOffset + (uint)initialOffset; data.Seek(offset, SeekOrigin.Begin); @@ -2314,18 +2446,11 @@ namespace BurnOutSharp.Builder entry.DataEntry = resourceDataEntry; } - } - - // Now go one level lower - if (totalEntryCount > 0) - { - foreach (var entry in resourceDirectoryTable.Entries) + else if (entry.SubdirectoryOffset != 0) { - if (entry.DataEntryOffset != 0) - continue; - uint offset = entry.SubdirectoryOffset + (uint)initialOffset; data.Seek(offset, SeekOrigin.Begin); + entry.Subdirectory = ParseResourceDirectoryTable(data, initialOffset, sections); } } diff --git a/BurnOutSharp.Models/PortableExecutable/BaseRelocationBlock.cs b/BurnOutSharp.Models/PortableExecutable/BaseRelocationBlock.cs index 0831d315..1f0b1099 100644 --- a/BurnOutSharp.Models/PortableExecutable/BaseRelocationBlock.cs +++ b/BurnOutSharp.Models/PortableExecutable/BaseRelocationBlock.cs @@ -46,6 +46,6 @@ /// in the Page RVA field for the block. This offset /// specifies where the base relocation is to be applied. /// - public ushort[] TypeOffsetFieldEntries; + public BaseRelocationTypeOffsetFieldEntry[] TypeOffsetFieldEntries; } } diff --git a/BurnOutSharp.Models/PortableExecutable/BaseRelocationTypeOffsetFieldEntry.cs b/BurnOutSharp.Models/PortableExecutable/BaseRelocationTypeOffsetFieldEntry.cs new file mode 100644 index 00000000..8d018c6a --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/BaseRelocationTypeOffsetFieldEntry.cs @@ -0,0 +1,22 @@ +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// Type or Offset field entry is a WORD (2 bytes). + /// + /// + public class BaseRelocationTypeOffsetFieldEntry + { + /// + /// Stored in the high 4 bits of the WORD, a value that indicates the type + /// of base relocation to be applied. For more information, see + /// + public BaseRelocationTypes BaseRelocationType; + + /// + /// Stored in the remaining 12 bits of the WORD, an offset from the starting + /// address that was specified in the Page RVA field for the block. This + /// offset specifies where the base relocation is to be applied. + /// + public ushort Offset; + } +} diff --git a/BurnOutSharp.Models/PortableExecutable/Executable.cs b/BurnOutSharp.Models/PortableExecutable/Executable.cs index b5eda76d..0beed375 100644 --- a/BurnOutSharp.Models/PortableExecutable/Executable.cs +++ b/BurnOutSharp.Models/PortableExecutable/Executable.cs @@ -68,6 +68,11 @@ namespace BurnOutSharp.Models.PortableExecutable // the object file contains managed code. The format of the metadata is not // documented, but can be handed to the CLR interfaces for handling metadata. + /// + /// Base relocation table (.reloc) + /// + public BaseRelocationBlock[] BaseRelocationTable { get; set; } + /// /// Debug table (.debug*) /// @@ -125,7 +130,6 @@ namespace BurnOutSharp.Models.PortableExecutable // - Delay Bound Import Address Table // - Delay Unload Import Address Table // - The .pdata Section [Multiple formats per entry] - // - The .reloc Section (Image Only) // - The .tls Section // - TLS Callback Functions // - [The Load Configuration Structure (Image Only)] diff --git a/BurnOutSharp.Wrappers/LinearExecutable.cs b/BurnOutSharp.Wrappers/LinearExecutable.cs index 6449afa4..ad0da865 100644 --- a/BurnOutSharp.Wrappers/LinearExecutable.cs +++ b/BurnOutSharp.Wrappers/LinearExecutable.cs @@ -35,7 +35,7 @@ namespace BurnOutSharp.Wrappers public ushort Stub_InitialSSValue => _executable.Stub.Header.InitialSSValue; /// - public ushort Stub_Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; + public ushort Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; /// public ushort Stub_Checksum => _executable.Stub.Header.Checksum; diff --git a/BurnOutSharp.Wrappers/MSDOS.cs b/BurnOutSharp.Wrappers/MSDOS.cs index 12093b05..cf0e5122 100644 --- a/BurnOutSharp.Wrappers/MSDOS.cs +++ b/BurnOutSharp.Wrappers/MSDOS.cs @@ -161,20 +161,20 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {BitConverter.ToString(_executable.Header.Magic).Replace("-", string.Empty)}"); - Console.WriteLine($" Last page bytes: {_executable.Header.LastPageBytes}"); - Console.WriteLine($" Pages: {_executable.Header.Pages}"); - Console.WriteLine($" Relocation items: {_executable.Header.RelocationItems}"); - Console.WriteLine($" Header paragraph size: {_executable.Header.HeaderParagraphSize}"); - Console.WriteLine($" Minimum extra paragraphs: {_executable.Header.MinimumExtraParagraphs}"); - Console.WriteLine($" Maximum extra paragraphs: {_executable.Header.MaximumExtraParagraphs}"); - Console.WriteLine($" Initial SS value: {_executable.Header.InitialSSValue}"); - Console.WriteLine($" Initial SP value: {_executable.Header.InitialSPValue}"); - Console.WriteLine($" Checksum: {_executable.Header.Checksum}"); - Console.WriteLine($" Initial IP value: {_executable.Header.InitialIPValue}"); - Console.WriteLine($" Initial CS value: {_executable.Header.InitialCSValue}"); - Console.WriteLine($" Relocation table address: {_executable.Header.RelocationTableAddr}"); - Console.WriteLine($" Overlay number: {_executable.Header.OverlayNumber}"); + Console.WriteLine($" Magic number: {BitConverter.ToString(Magic).Replace("-", string.Empty)}"); + Console.WriteLine($" Last page bytes: {LastPageBytes}"); + Console.WriteLine($" Pages: {Pages}"); + Console.WriteLine($" Relocation items: {RelocationItems}"); + Console.WriteLine($" Header paragraph size: {HeaderParagraphSize}"); + Console.WriteLine($" Minimum extra paragraphs: {MinimumExtraParagraphs}"); + Console.WriteLine($" Maximum extra paragraphs: {MaximumExtraParagraphs}"); + Console.WriteLine($" Initial SS value: {InitialSSValue}"); + Console.WriteLine($" Initial SP value: {InitialSPValue}"); + Console.WriteLine($" Checksum: {Checksum}"); + Console.WriteLine($" Initial IP value: {InitialIPValue}"); + Console.WriteLine($" Initial CS value: {InitialCSValue}"); + Console.WriteLine($" Relocation table address: {RelocationTableAddr}"); + Console.WriteLine($" Overlay number: {OverlayNumber}"); } /// @@ -184,15 +184,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Relocation Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.RelocationItems == 0 || _executable.RelocationTable.Length == 0) + if (RelocationItems == 0 || RelocationTable.Length == 0) { Console.WriteLine(" No relocation table items"); } else { - for (int i = 0; i < _executable.RelocationTable.Length; i++) + for (int i = 0; i < RelocationTable.Length; i++) { - var entry = _executable.RelocationTable[i]; + var entry = RelocationTable[i]; Console.WriteLine($" Relocation Table Entry {i}"); Console.WriteLine($" Offset = {entry.Offset}"); Console.WriteLine($" Segment = {entry.Segment}"); diff --git a/BurnOutSharp.Wrappers/NewExecutable.cs b/BurnOutSharp.Wrappers/NewExecutable.cs index 6683d5ef..557c001f 100644 --- a/BurnOutSharp.Wrappers/NewExecutable.cs +++ b/BurnOutSharp.Wrappers/NewExecutable.cs @@ -39,7 +39,7 @@ namespace BurnOutSharp.Wrappers public ushort Stub_InitialSSValue => _executable.Stub.Header.InitialSSValue; /// - public ushort Stub_Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; + public ushort Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; /// public ushort Stub_Checksum => _executable.Stub.Header.Checksum; @@ -302,20 +302,20 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" MS-DOS Stub Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {BitConverter.ToString(_executable.Stub.Header.Magic).Replace("-", string.Empty)}"); - Console.WriteLine($" Last page bytes: {_executable.Stub.Header.LastPageBytes}"); - Console.WriteLine($" Pages: {_executable.Stub.Header.Pages}"); - Console.WriteLine($" Relocation items: {_executable.Stub.Header.RelocationItems}"); - Console.WriteLine($" Header paragraph size: {_executable.Stub.Header.HeaderParagraphSize}"); - Console.WriteLine($" Minimum extra paragraphs: {_executable.Stub.Header.MinimumExtraParagraphs}"); - Console.WriteLine($" Maximum extra paragraphs: {_executable.Stub.Header.MaximumExtraParagraphs}"); - Console.WriteLine($" Initial SS value: {_executable.Stub.Header.InitialSSValue}"); - Console.WriteLine($" Initial SP value: {_executable.Stub.Header.InitialSPValue}"); - Console.WriteLine($" Checksum: {_executable.Stub.Header.Checksum}"); - Console.WriteLine($" Initial IP value: {_executable.Stub.Header.InitialIPValue}"); - Console.WriteLine($" Initial CS value: {_executable.Stub.Header.InitialCSValue}"); - Console.WriteLine($" Relocation table address: {_executable.Stub.Header.RelocationTableAddr}"); - Console.WriteLine($" Overlay number: {_executable.Stub.Header.OverlayNumber}"); + Console.WriteLine($" Magic number: {BitConverter.ToString(Stub_Magic).Replace("-", string.Empty)}"); + Console.WriteLine($" Last page bytes: {Stub_LastPageBytes}"); + Console.WriteLine($" Pages: {Stub_Pages}"); + Console.WriteLine($" Relocation items: {Stub_RelocationItems}"); + Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize}"); + Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs}"); + Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs}"); + Console.WriteLine($" Initial SS value: {Stub_InitialSSValue}"); + Console.WriteLine($" Initial SP value: {Stub_InitialSPValue}"); + Console.WriteLine($" Checksum: {Stub_Checksum}"); + Console.WriteLine($" Initial IP value: {Stub_InitialIPValue}"); + Console.WriteLine($" Initial CS value: {Stub_InitialCSValue}"); + Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr}"); + Console.WriteLine($" Overlay number: {Stub_OverlayNumber}"); Console.WriteLine(); } @@ -326,11 +326,11 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" MS-DOS Stub Extended Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Reserved words: {string.Join(", ", _executable.Stub.Header.Reserved1)}"); - Console.WriteLine($" OEM identifier: {_executable.Stub.Header.OEMIdentifier}"); - Console.WriteLine($" OEM information: {_executable.Stub.Header.OEMInformation}"); - Console.WriteLine($" Reserved words: {string.Join(", ", _executable.Stub.Header.Reserved2)}"); - Console.WriteLine($" New EXE header address: {_executable.Stub.Header.NewExeHeaderAddr}"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier}"); + Console.WriteLine($" OEM information: {Stub_OEMInformation}"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr}"); Console.WriteLine(); } @@ -341,37 +341,37 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {BitConverter.ToString(_executable.Header.Magic).Replace("-", string.Empty)}"); - Console.WriteLine($" Linker version: {_executable.Header.LinkerVersion}"); - Console.WriteLine($" Linker revision: {_executable.Header.LinkerRevision}"); - Console.WriteLine($" Entry table offset: {_executable.Header.EntryTableOffset}"); - Console.WriteLine($" Entry table size: {_executable.Header.EntryTableSize}"); - Console.WriteLine($" CRC checksum: {_executable.Header.CrcChecksum}"); - Console.WriteLine($" Flag word: {_executable.Header.FlagWord}"); - Console.WriteLine($" Automatic data segment number: {_executable.Header.AutomaticDataSegmentNumber}"); - Console.WriteLine($" Initial heap allocation: {_executable.Header.InitialHeapAlloc}"); - Console.WriteLine($" Initial stack allocation: {_executable.Header.InitialStackAlloc}"); - Console.WriteLine($" Initial CS:IP setting: {_executable.Header.InitialCSIPSetting}"); - Console.WriteLine($" Initial SS:SP setting: {_executable.Header.InitialSSSPSetting}"); - Console.WriteLine($" File segment count: {_executable.Header.FileSegmentCount}"); - Console.WriteLine($" Module reference table size: {_executable.Header.ModuleReferenceTableSize}"); - Console.WriteLine($" Non-resident name table size: {_executable.Header.NonResidentNameTableSize}"); - Console.WriteLine($" Segment table offset: {_executable.Header.SegmentTableOffset}"); - Console.WriteLine($" Resource table offset: {_executable.Header.ResourceTableOffset}"); - Console.WriteLine($" Resident name table offset: {_executable.Header.ResidentNameTableOffset}"); - Console.WriteLine($" Module reference table offset: {_executable.Header.ModuleReferenceTableOffset}"); - Console.WriteLine($" Imported names table offset: {_executable.Header.ImportedNamesTableOffset}"); - Console.WriteLine($" Non-resident name table offset: {_executable.Header.NonResidentNamesTableOffset}"); - Console.WriteLine($" Moveable entries count: {_executable.Header.MovableEntriesCount}"); - Console.WriteLine($" Segment alignment shift count: {_executable.Header.SegmentAlignmentShiftCount}"); - Console.WriteLine($" Resource entries count: {_executable.Header.ResourceEntriesCount}"); - Console.WriteLine($" Target operating system: {_executable.Header.TargetOperatingSystem}"); - Console.WriteLine($" Additional flags: {_executable.Header.AdditionalFlags}"); - Console.WriteLine($" Return thunk offset: {_executable.Header.ReturnThunkOffset}"); - Console.WriteLine($" Segment reference thunk offset: {_executable.Header.SegmentReferenceThunkOffset}"); - Console.WriteLine($" Minimum code swap area size: {_executable.Header.MinCodeSwapAreaSize}"); - Console.WriteLine($" Windows SDK revision: {_executable.Header.WindowsSDKRevision}"); - Console.WriteLine($" Windows SDK version: {_executable.Header.WindowsSDKVersion}"); + Console.WriteLine($" Magic number: {BitConverter.ToString(Magic).Replace("-", string.Empty)}"); + Console.WriteLine($" Linker version: {LinkerVersion}"); + Console.WriteLine($" Linker revision: {LinkerRevision}"); + Console.WriteLine($" Entry table offset: {EntryTableOffset}"); + Console.WriteLine($" Entry table size: {EntryTableSize}"); + Console.WriteLine($" CRC checksum: {CrcChecksum}"); + Console.WriteLine($" Flag word: {FlagWord}"); + Console.WriteLine($" Automatic data segment number: {AutomaticDataSegmentNumber}"); + Console.WriteLine($" Initial heap allocation: {InitialHeapAlloc}"); + Console.WriteLine($" Initial stack allocation: {InitialStackAlloc}"); + Console.WriteLine($" Initial CS:IP setting: {InitialCSIPSetting}"); + Console.WriteLine($" Initial SS:SP setting: {InitialSSSPSetting}"); + Console.WriteLine($" File segment count: {FileSegmentCount}"); + Console.WriteLine($" Module reference table size: {ModuleReferenceTableSize}"); + Console.WriteLine($" Non-resident name table size: {NonResidentNameTableSize}"); + Console.WriteLine($" Segment table offset: {SegmentTableOffset}"); + Console.WriteLine($" Resource table offset: {ResourceTableOffset}"); + Console.WriteLine($" Resident name table offset: {ResidentNameTableOffset}"); + Console.WriteLine($" Module reference table offset: {ModuleReferenceTableOffset}"); + Console.WriteLine($" Imported names table offset: {ImportedNamesTableOffset}"); + Console.WriteLine($" Non-resident name table offset: {NonResidentNamesTableOffset}"); + Console.WriteLine($" Moveable entries count: {MovableEntriesCount}"); + Console.WriteLine($" Segment alignment shift count: {SegmentAlignmentShiftCount}"); + Console.WriteLine($" Resource entries count: {ResourceEntriesCount}"); + Console.WriteLine($" Target operating system: {TargetOperatingSystem}"); + Console.WriteLine($" Additional flags: {AdditionalFlags}"); + Console.WriteLine($" Return thunk offset: {ReturnThunkOffset}"); + Console.WriteLine($" Segment reference thunk offset: {SegmentReferenceThunkOffset}"); + Console.WriteLine($" Minimum code swap area size: {MinCodeSwapAreaSize}"); + Console.WriteLine($" Windows SDK revision: {WindowsSDKRevision}"); + Console.WriteLine($" Windows SDK version: {WindowsSDKVersion}"); Console.WriteLine(); } @@ -382,15 +382,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Segment Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.FileSegmentCount == 0 || _executable.SegmentTable.Length == 0) + if (FileSegmentCount == 0 || SegmentTable.Length == 0) { Console.WriteLine(" No segment table items"); } else { - for (int i = 0; i < _executable.SegmentTable.Length; i++) + for (int i = 0; i < SegmentTable.Length; i++) { - var entry = _executable.SegmentTable[i]; + var entry = SegmentTable[i]; Console.WriteLine($" Segment Table Entry {i}"); Console.WriteLine($" Offset = {entry.Offset}"); Console.WriteLine($" Length = {entry.Length}"); @@ -408,17 +408,17 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Resource Table Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Alignment shift count: {_executable.ResourceTable.AlignmentShiftCount}"); - if (_executable.Header.ResourceEntriesCount == 0 || _executable.ResourceTable.ResourceTypes.Length == 0) + Console.WriteLine($" Alignment shift count: {ResourceTable.AlignmentShiftCount}"); + if (ResourceEntriesCount == 0 || ResourceTable.ResourceTypes.Length == 0) { Console.WriteLine(" No resource table items"); } else { - for (int i = 0; i < _executable.ResourceTable.ResourceTypes.Length; i++) + for (int i = 0; i < ResourceTable.ResourceTypes.Length; i++) { // TODO: If not integer type, print out name - var entry = _executable.ResourceTable.ResourceTypes[i]; + var entry = ResourceTable.ResourceTypes[i]; Console.WriteLine($" Resource Table Entry {i}"); Console.WriteLine($" Type ID = {entry.TypeID} (Is Integer Type: {entry.IsIntegerType()})"); Console.WriteLine($" Resource count = {entry.ResourceCount}"); @@ -445,13 +445,13 @@ namespace BurnOutSharp.Wrappers } } - if (_executable.ResourceTable.TypeAndNameStrings.Count == 0) + if (ResourceTable.TypeAndNameStrings.Count == 0) { Console.WriteLine(" No resource table type/name strings"); } else { - foreach (var typeAndNameString in _executable.ResourceTable.TypeAndNameStrings) + foreach (var typeAndNameString in ResourceTable.TypeAndNameStrings) { Console.WriteLine($" Resource Type/Name Offset {typeAndNameString.Key}"); Console.WriteLine($" Length = {typeAndNameString.Value.Length}"); @@ -468,15 +468,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Resident-Name Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.ResidentNameTableOffset == 0 || _executable.ResidentNameTable.Length == 0) + if (ResidentNameTableOffset == 0 || ResidentNameTable.Length == 0) { Console.WriteLine(" No resident-name table items"); } else { - for (int i = 0; i < _executable.ResidentNameTable.Length; i++) + for (int i = 0; i < ResidentNameTable.Length; i++) { - var entry = _executable.ResidentNameTable[i]; + var entry = ResidentNameTable[i]; Console.WriteLine($" Resident-Name Table Entry {i}"); Console.WriteLine($" Length = {entry.Length}"); Console.WriteLine($" Name string = {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString) : "[EMPTY]")}"); @@ -493,18 +493,18 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Module-Reference Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.ModuleReferenceTableSize == 0 || _executable.ModuleReferenceTable.Length == 0) + if (ModuleReferenceTableSize == 0 || ModuleReferenceTable.Length == 0) { Console.WriteLine(" No module-reference table items"); } else { - for (int i = 0; i < _executable.ModuleReferenceTable.Length; i++) + for (int i = 0; i < ModuleReferenceTable.Length; i++) { // TODO: Read the imported names table and print value here - var entry = _executable.ModuleReferenceTable[i]; + var entry = ModuleReferenceTable[i]; Console.WriteLine($" Module-Reference Table Entry {i}"); - Console.WriteLine($" Offset = {entry.Offset} (adjusted to be {entry.Offset + _executable.Stub.Header.NewExeHeaderAddr + _executable.Header.ImportedNamesTableOffset})"); + Console.WriteLine($" Offset = {entry.Offset} (adjusted to be {entry.Offset + Stub_NewExeHeaderAddr + ImportedNamesTableOffset})"); } } Console.WriteLine(); @@ -517,13 +517,13 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Imported-Name Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.ImportedNamesTableOffset == 0 || _executable.ImportedNameTable.Count == 0) + if (ImportedNamesTableOffset == 0 || ImportedNameTable.Count == 0) { Console.WriteLine(" No imported-name table items"); } else { - foreach (var entry in _executable.ImportedNameTable) + foreach (var entry in ImportedNameTable) { Console.WriteLine($" Imported-Name Table at Offset {entry.Key}"); Console.WriteLine($" Length = {entry.Value.Length}"); @@ -540,15 +540,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Entry Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.EntryTableSize == 0 || _executable.EntryTable.Length == 0) + if (EntryTableSize == 0 || EntryTable.Length == 0) { Console.WriteLine(" No entry table items"); } else { - for (int i = 0; i < _executable.EntryTable.Length; i++) + for (int i = 0; i < EntryTable.Length; i++) { - var entry = _executable.EntryTable[i]; + var entry = EntryTable[i]; Console.WriteLine($" Entry Table Entry {i}"); Console.WriteLine($" Entry count = {entry.EntryCount}"); Console.WriteLine($" Segment indicator = {entry.SegmentIndicator} ({entry.GetEntryType()})"); @@ -577,15 +577,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Nonresident-Name Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.Header.NonResidentNameTableSize == 0 || _executable.NonResidentNameTable.Length == 0) + if (NonResidentNameTableSize == 0 || NonResidentNameTable.Length == 0) { Console.WriteLine(" No nonresident-name table items"); } else { - for (int i = 0; i < _executable.NonResidentNameTable.Length; i++) + for (int i = 0; i < NonResidentNameTable.Length; i++) { - var entry = _executable.NonResidentNameTable[i]; + var entry = NonResidentNameTable[i]; Console.WriteLine($" Nonresident-Name Table Entry {i}"); Console.WriteLine($" Length = {entry.Length}"); Console.WriteLine($" Name string = {(entry.NameString != null ? Encoding.ASCII.GetString(entry.NameString) : "[EMPTY]")}"); diff --git a/BurnOutSharp.Wrappers/PortableExecutable.cs b/BurnOutSharp.Wrappers/PortableExecutable.cs index 50e8b0c0..ac647628 100644 --- a/BurnOutSharp.Wrappers/PortableExecutable.cs +++ b/BurnOutSharp.Wrappers/PortableExecutable.cs @@ -41,7 +41,7 @@ namespace BurnOutSharp.Wrappers public ushort Stub_InitialSSValue => _executable.Stub.Header.InitialSSValue; /// - public ushort Stub_Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; + public ushort Stub_InitialSPValue => _executable.Stub.Header.InitialSPValue; /// public ushort Stub_Checksum => _executable.Stub.Header.Checksum; @@ -296,6 +296,9 @@ namespace BurnOutSharp.Wrappers #region Sections + /// + public Models.PortableExecutable.BaseRelocationBlock[] BaseRelocationTable => _executable.BaseRelocationTable; + /// public Models.PortableExecutable.DebugTable DebugTable => _executable.DebugTable; @@ -342,7 +345,7 @@ namespace BurnOutSharp.Wrappers return null; // If we have certificate data, use that as the end - if (_executable.OptionalHeader?.CertificateTable != null) + if (OH_CertificateTable != null) { var certificateTable = _executable.OptionalHeader.CertificateTable; int certificateTableAddress = (int)certificateTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable); @@ -458,11 +461,11 @@ namespace BurnOutSharp.Wrappers lock (_sourceDataLock) { // Use the cached data if possible - if (_resourceData != null) + if (_resourceData != null && _resourceData.Count != 0) return _resourceData; // If we have no resource table, just return - if (_executable.OptionalHeader?.ResourceTable == null + if (OH_ResourceTable == null || _executable.OptionalHeader.ResourceTable.VirtualAddress == 0 || _executable.ResourceDirectoryTable == null) return null; @@ -622,7 +625,7 @@ namespace BurnOutSharp.Wrappers /// Cached raw section data /// private byte[][] _sectionData = null; - + /// /// Cached resource data /// @@ -717,7 +720,8 @@ namespace BurnOutSharp.Wrappers return null; // Ensure that we have the resource data cached - _ = ResourceData; + if (ResourceData == null) + return null; // If we don't have string version info in this executable var stringTable = _versionInfo?.StringFileInfo?.Children; @@ -744,7 +748,8 @@ namespace BurnOutSharp.Wrappers return _assemblyManifest; // Ensure that we have the resource data cached - _ = ResourceData; + if (ResourceData == null) + return null; // Return the now-cached assembly manifest return _assemblyManifest; @@ -759,12 +764,12 @@ namespace BurnOutSharp.Wrappers /// public void PrintAllSections() { - foreach (var section in _executable.SectionTable) + foreach (var section in SectionTable) { // TODO: Handle long section names with leading `/` string sectionName = Encoding.UTF8.GetString(section.Name); - int sectionAddr = (int)section.PointerToRawData; - int sectionEnd = sectionAddr + (int)section.VirtualSize; + uint sectionAddr = section.PointerToRawData; + uint sectionEnd = sectionAddr + section.VirtualSize; Console.WriteLine($"{sectionName}: {sectionAddr} -> {sectionEnd}"); } } @@ -789,6 +794,9 @@ namespace BurnOutSharp.Wrappers PrintCOFFSymbolTable(); PrintAttributeCertificateTable(); PrintDelayLoadDirectoryTable(); + + // Named Sections + PrintBaseRelocationTable(); PrintDebugTable(); PrintExportTable(); PrintImportTable(); @@ -802,20 +810,20 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" MS-DOS Stub Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Magic number: {BitConverter.ToString(_executable.Stub.Header.Magic).Replace("-", string.Empty)}"); - Console.WriteLine($" Last page bytes: {_executable.Stub.Header.LastPageBytes}"); - Console.WriteLine($" Pages: {_executable.Stub.Header.Pages}"); - Console.WriteLine($" Relocation items: {_executable.Stub.Header.RelocationItems}"); - Console.WriteLine($" Header paragraph size: {_executable.Stub.Header.HeaderParagraphSize}"); - Console.WriteLine($" Minimum extra paragraphs: {_executable.Stub.Header.MinimumExtraParagraphs}"); - Console.WriteLine($" Maximum extra paragraphs: {_executable.Stub.Header.MaximumExtraParagraphs}"); - Console.WriteLine($" Initial SS value: {_executable.Stub.Header.InitialSSValue}"); - Console.WriteLine($" Initial SP value: {_executable.Stub.Header.InitialSPValue}"); - Console.WriteLine($" Checksum: {_executable.Stub.Header.Checksum}"); - Console.WriteLine($" Initial IP value: {_executable.Stub.Header.InitialIPValue}"); - Console.WriteLine($" Initial CS value: {_executable.Stub.Header.InitialCSValue}"); - Console.WriteLine($" Relocation table address: {_executable.Stub.Header.RelocationTableAddr}"); - Console.WriteLine($" Overlay number: {_executable.Stub.Header.OverlayNumber}"); + Console.WriteLine($" Magic number: {BitConverter.ToString(Stub_Magic).Replace("-", string.Empty)}"); + Console.WriteLine($" Last page bytes: {Stub_LastPageBytes}"); + Console.WriteLine($" Pages: {Stub_Pages}"); + Console.WriteLine($" Relocation items: {Stub_RelocationItems}"); + Console.WriteLine($" Header paragraph size: {Stub_HeaderParagraphSize}"); + Console.WriteLine($" Minimum extra paragraphs: {Stub_MinimumExtraParagraphs}"); + Console.WriteLine($" Maximum extra paragraphs: {Stub_MaximumExtraParagraphs}"); + Console.WriteLine($" Initial SS value: {Stub_InitialSSValue}"); + Console.WriteLine($" Initial SP value: {Stub_InitialSPValue}"); + Console.WriteLine($" Checksum: {Stub_Checksum}"); + Console.WriteLine($" Initial IP value: {Stub_InitialIPValue}"); + Console.WriteLine($" Initial CS value: {Stub_InitialCSValue}"); + Console.WriteLine($" Relocation table address: {Stub_RelocationTableAddr}"); + Console.WriteLine($" Overlay number: {Stub_OverlayNumber}"); Console.WriteLine(); } @@ -826,11 +834,11 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" MS-DOS Stub Extended Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Reserved words: {string.Join(", ", _executable.Stub.Header.Reserved1)}"); - Console.WriteLine($" OEM identifier: {_executable.Stub.Header.OEMIdentifier}"); - Console.WriteLine($" OEM information: {_executable.Stub.Header.OEMInformation}"); - Console.WriteLine($" Reserved words: {string.Join(", ", _executable.Stub.Header.Reserved2)}"); - Console.WriteLine($" New EXE header address: {_executable.Stub.Header.NewExeHeaderAddr}"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved1)}"); + Console.WriteLine($" OEM identifier: {Stub_OEMIdentifier}"); + Console.WriteLine($" OEM information: {Stub_OEMInformation}"); + Console.WriteLine($" Reserved words: {string.Join(", ", Stub_Reserved2)}"); + Console.WriteLine($" New EXE header address: {Stub_NewExeHeaderAddr}"); Console.WriteLine(); } @@ -841,14 +849,14 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" COFF File Header Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Signature: {BitConverter.ToString(_executable.Signature).Replace("-", string.Empty)}"); - Console.WriteLine($" Machine: {_executable.COFFFileHeader.Machine}"); - Console.WriteLine($" Number of sections: {_executable.COFFFileHeader.NumberOfSections}"); - Console.WriteLine($" Time/Date stamp: {_executable.COFFFileHeader.TimeDateStamp}"); - Console.WriteLine($" Pointer to symbol table: {_executable.COFFFileHeader.PointerToSymbolTable}"); - Console.WriteLine($" Number of symbols: {_executable.COFFFileHeader.NumberOfSymbols}"); - Console.WriteLine($" Size of optional header: {_executable.COFFFileHeader.SizeOfOptionalHeader}"); - Console.WriteLine($" Characteristics: {_executable.COFFFileHeader.Characteristics}"); + Console.WriteLine($" Signature: {BitConverter.ToString(Signature).Replace("-", string.Empty)}"); + Console.WriteLine($" Machine: {Machine}"); + Console.WriteLine($" Number of sections: {NumberOfSections}"); + Console.WriteLine($" Time/Date stamp: {TimeDateStamp}"); + Console.WriteLine($" Pointer to symbol table: {PointerToSymbolTable}"); + Console.WriteLine($" Number of symbols: {NumberOfSymbols}"); + Console.WriteLine($" Size of optional header: {SizeOfOptionalHeader}"); + Console.WriteLine($" Characteristics: {Characteristics}"); Console.WriteLine(); } @@ -859,166 +867,151 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Optional Header Information:"); Console.WriteLine(" -------------------------"); - if (_executable.COFFFileHeader.SizeOfOptionalHeader == 0 || _executable.OptionalHeader == null) + if (SizeOfOptionalHeader == 0) { Console.WriteLine(" No optional header present"); } else { - Console.WriteLine($" Magic: {_executable.OptionalHeader.Magic}"); - Console.WriteLine($" Major linker version: {_executable.OptionalHeader.MajorLinkerVersion}"); - Console.WriteLine($" Minor linker version: {_executable.OptionalHeader.MinorLinkerVersion}"); - Console.WriteLine($" Size of code section: {_executable.OptionalHeader.SizeOfCode}"); - Console.WriteLine($" Size of initialized data: {_executable.OptionalHeader.SizeOfInitializedData}"); - Console.WriteLine($" Size of uninitialized data: {_executable.OptionalHeader.SizeOfUninitializedData}"); - Console.WriteLine($" Address of entry point: {_executable.OptionalHeader.AddressOfEntryPoint}"); - Console.WriteLine($" Base of code: {_executable.OptionalHeader.BaseOfCode}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Base of data: {_executable.OptionalHeader.BaseOfData}"); + Console.WriteLine($" Magic: {OH_Magic}"); + Console.WriteLine($" Major linker version: {OH_MajorLinkerVersion}"); + Console.WriteLine($" Minor linker version: {OH_MinorLinkerVersion}"); + Console.WriteLine($" Size of code section: {OH_SizeOfCode}"); + Console.WriteLine($" Size of initialized data: {OH_SizeOfInitializedData}"); + Console.WriteLine($" Size of uninitialized data: {OH_SizeOfUninitializedData}"); + Console.WriteLine($" Address of entry point: {OH_AddressOfEntryPoint}"); + Console.WriteLine($" Base of code: {OH_BaseOfCode}"); + if (OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) + Console.WriteLine($" Base of data: {OH_BaseOfData}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Image base: {_executable.OptionalHeader.ImageBase_PE32}"); - else if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32Plus) - Console.WriteLine($" Image base: {_executable.OptionalHeader.ImageBase_PE32Plus}"); - Console.WriteLine($" Section alignment: {_executable.OptionalHeader.SectionAlignment}"); - Console.WriteLine($" File alignment: {_executable.OptionalHeader.FileAlignment}"); - Console.WriteLine($" Major operating system version: {_executable.OptionalHeader.MajorOperatingSystemVersion}"); - Console.WriteLine($" Minor operating system version: {_executable.OptionalHeader.MinorOperatingSystemVersion}"); - Console.WriteLine($" Major image version: {_executable.OptionalHeader.MajorImageVersion}"); - Console.WriteLine($" Minor image version: {_executable.OptionalHeader.MinorImageVersion}"); - Console.WriteLine($" Major subsystem version: {_executable.OptionalHeader.MajorSubsystemVersion}"); - Console.WriteLine($" Minor subsystem version: {_executable.OptionalHeader.MinorSubsystemVersion}"); - Console.WriteLine($" Win32 version value: {_executable.OptionalHeader.Win32VersionValue}"); - Console.WriteLine($" Size of image: {_executable.OptionalHeader.SizeOfImage}"); - Console.WriteLine($" Size of headers: {_executable.OptionalHeader.SizeOfHeaders}"); - Console.WriteLine($" Checksum: {_executable.OptionalHeader.CheckSum}"); - Console.WriteLine($" Subsystem: {_executable.OptionalHeader.Subsystem}"); - Console.WriteLine($" DLL characteristics: {_executable.OptionalHeader.DllCharacteristics}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Size of stack reserve: {_executable.OptionalHeader.SizeOfStackReserve_PE32}"); - else if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32Plus) - Console.WriteLine($" Size of stack reserve: {_executable.OptionalHeader.SizeOfStackReserve_PE32Plus}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Size of stack commit: {_executable.OptionalHeader.SizeOfStackCommit_PE32}"); - else if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32Plus) - Console.WriteLine($" Size of stack commit: {_executable.OptionalHeader.SizeOfStackCommit_PE32Plus}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Size of heap reserve: {_executable.OptionalHeader.SizeOfHeapReserve_PE32}"); - else if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32Plus) - Console.WriteLine($" Size of heap reserve: {_executable.OptionalHeader.SizeOfHeapReserve_PE32Plus}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) - Console.WriteLine($" Size of heap commit: {_executable.OptionalHeader.SizeOfHeapCommit_PE32}"); - else if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32Plus) - Console.WriteLine($" Size of heap commit: {_executable.OptionalHeader.SizeOfHeapCommit_PE32Plus}"); - Console.WriteLine($" Loader flags: {_executable.OptionalHeader.LoaderFlags}"); - Console.WriteLine($" Number of data-directory entries: {_executable.OptionalHeader.NumberOfRvaAndSizes}"); + Console.WriteLine($" Image base: {OH_ImageBase}"); + Console.WriteLine($" Section alignment: {OH_SectionAlignment}"); + Console.WriteLine($" File alignment: {OH_FileAlignment}"); + Console.WriteLine($" Major operating system version: {OH_MajorOperatingSystemVersion}"); + Console.WriteLine($" Minor operating system version: {OH_MinorOperatingSystemVersion}"); + Console.WriteLine($" Major image version: {OH_MajorImageVersion}"); + Console.WriteLine($" Minor image version: {OH_MinorImageVersion}"); + Console.WriteLine($" Major subsystem version: {OH_MajorSubsystemVersion}"); + Console.WriteLine($" Minor subsystem version: {OH_MinorSubsystemVersion}"); + Console.WriteLine($" Win32 version value: {OH_Win32VersionValue}"); + Console.WriteLine($" Size of image: {OH_SizeOfImage}"); + Console.WriteLine($" Size of headers: {OH_SizeOfHeaders}"); + Console.WriteLine($" Checksum: {OH_CheckSum}"); + Console.WriteLine($" Subsystem: {OH_Subsystem}"); + Console.WriteLine($" DLL characteristics: {OH_DllCharacteristics}"); + Console.WriteLine($" Size of stack reserve: {OH_SizeOfStackReserve}"); + Console.WriteLine($" Size of stack commit: {OH_SizeOfStackCommit}"); + Console.WriteLine($" Size of heap reserve: {OH_SizeOfHeapReserve}"); + Console.WriteLine($" Size of heap commit: {OH_SizeOfHeapCommit}"); + Console.WriteLine($" Loader flags: {OH_LoaderFlags}"); + Console.WriteLine($" Number of data-directory entries: {OH_NumberOfRvaAndSizes}"); - if (_executable.OptionalHeader.ExportTable != null) + if (OH_ExportTable != null) { Console.WriteLine(" Export Table (1)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ExportTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ExportTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ExportTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ExportTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ExportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ExportTable.Size}"); } - if (_executable.OptionalHeader.ImportTable != null) + if (OH_ImportTable != null) { Console.WriteLine(" Import Table (2)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ImportTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ImportTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ImportTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ImportTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ImportTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ImportTable.Size}"); } - if (_executable.OptionalHeader.ResourceTable != null) + if (OH_ResourceTable != null) { Console.WriteLine(" Resource Table (3)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ResourceTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ResourceTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ResourceTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ResourceTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ResourceTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ResourceTable.Size}"); } - if (_executable.OptionalHeader.ExceptionTable != null) + if (OH_ExceptionTable != null) { Console.WriteLine(" Exception Table (4)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ExceptionTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ExceptionTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ExceptionTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ExceptionTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ExceptionTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ExceptionTable.Size}"); } - if (_executable.OptionalHeader.CertificateTable != null) + if (OH_CertificateTable != null) { Console.WriteLine(" Certificate Table (5)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.CertificateTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.CertificateTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.CertificateTable.Size}"); + Console.WriteLine($" Virtual address: {OH_CertificateTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_CertificateTable.Size}"); } - if (_executable.OptionalHeader.BaseRelocationTable != null) + if (OH_BaseRelocationTable != null) { Console.WriteLine(" Base Relocation Table (6)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.BaseRelocationTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.BaseRelocationTable.Size}"); + Console.WriteLine($" Virtual address: {OH_BaseRelocationTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_BaseRelocationTable.Size}"); } - if (_executable.OptionalHeader.Debug != null) + if (OH_Debug != null) { Console.WriteLine(" Debug Table (7)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.Debug.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.Debug.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.Debug.Size}"); + Console.WriteLine($" Virtual address: {OH_Debug.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_Debug.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_Debug.Size}"); } - if (_executable.OptionalHeader.NumberOfRvaAndSizes >= 8) + if (OH_NumberOfRvaAndSizes >= 8) { Console.WriteLine(" Architecture Table (8)"); Console.WriteLine($" Virtual address: 0"); Console.WriteLine($" Physical address: 0"); Console.WriteLine($" Size: 0"); } - if (_executable.OptionalHeader.GlobalPtr != null) + if (OH_GlobalPtr != null) { Console.WriteLine(" Global Pointer Register (9)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.GlobalPtr.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.GlobalPtr.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.GlobalPtr.Size}"); + Console.WriteLine($" Virtual address: {OH_GlobalPtr.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_GlobalPtr.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_GlobalPtr.Size}"); } - if (_executable.OptionalHeader.ThreadLocalStorageTable != null) + if (OH_ThreadLocalStorageTable != null) { Console.WriteLine(" Thread Local Storage (TLS) Table (10)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ThreadLocalStorageTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ThreadLocalStorageTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ThreadLocalStorageTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ThreadLocalStorageTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ThreadLocalStorageTable.Size}"); } - if (_executable.OptionalHeader.LoadConfigTable != null) + if (OH_LoadConfigTable != null) { Console.WriteLine(" Load Config Table (11)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.LoadConfigTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.LoadConfigTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.LoadConfigTable.Size}"); + Console.WriteLine($" Virtual address: {OH_LoadConfigTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_LoadConfigTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_LoadConfigTable.Size}"); } - if (_executable.OptionalHeader.BoundImport != null) + if (OH_BoundImport != null) { Console.WriteLine(" Bound Import Table (12)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.BoundImport.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.BoundImport.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.BoundImport.Size}"); + Console.WriteLine($" Virtual address: {OH_BoundImport.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_BoundImport.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_BoundImport.Size}"); } - if (_executable.OptionalHeader.ImportAddressTable != null) + if (OH_ImportAddressTable != null) { Console.WriteLine(" Import Address Table (13)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.ImportAddressTable.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.ImportAddressTable.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.ImportAddressTable.Size}"); + Console.WriteLine($" Virtual address: {OH_ImportAddressTable.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_ImportAddressTable.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_ImportAddressTable.Size}"); } - if (_executable.OptionalHeader.DelayImportDescriptor != null) + if (OH_DelayImportDescriptor != null) { Console.WriteLine(" Delay Import Descriptior (14)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.DelayImportDescriptor.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.DelayImportDescriptor.Size}"); + Console.WriteLine($" Virtual address: {OH_DelayImportDescriptor.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_DelayImportDescriptor.Size}"); } - if (_executable.OptionalHeader.CLRRuntimeHeader != null) + if (OH_CLRRuntimeHeader != null) { Console.WriteLine(" CLR Runtime Header (15)"); - Console.WriteLine($" Virtual address: {_executable.OptionalHeader.CLRRuntimeHeader.VirtualAddress}"); - Console.WriteLine($" Physical address: {_executable.OptionalHeader.CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); - Console.WriteLine($" Size: {_executable.OptionalHeader.CLRRuntimeHeader.Size}"); + Console.WriteLine($" Virtual address: {OH_CLRRuntimeHeader.VirtualAddress}"); + Console.WriteLine($" Physical address: {OH_CLRRuntimeHeader.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Size: {OH_CLRRuntimeHeader.Size}"); } - if (_executable.OptionalHeader.NumberOfRvaAndSizes >= 16) + if (OH_NumberOfRvaAndSizes >= 16) { Console.WriteLine(" Reserved (16)"); Console.WriteLine($" Virtual address: 0"); @@ -1036,20 +1029,20 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Section Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.COFFFileHeader.NumberOfSections == 0 || _executable.SectionTable.Length == 0) + if (NumberOfSections == 0 || SectionTable.Length == 0) { Console.WriteLine(" No section table items"); } else { - for (int i = 0; i < _executable.SectionTable.Length; i++) + for (int i = 0; i < SectionTable.Length; i++) { - var entry = _executable.SectionTable[i]; + var entry = SectionTable[i]; Console.WriteLine($" Section Table Entry {i}"); Console.WriteLine($" Name = {Encoding.UTF8.GetString(entry.Name)}"); Console.WriteLine($" Virtual size = {entry.VirtualSize}"); Console.WriteLine($" Virtual address = {entry.VirtualAddress}"); - Console.WriteLine($" Physical address: {entry.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable)}"); + Console.WriteLine($" Physical address: {entry.VirtualAddress.ConvertVirtualAddress(SectionTable)}"); Console.WriteLine($" Size of raw data = {entry.SizeOfRawData}"); Console.WriteLine($" Pointer to raw data = {entry.PointerToRawData}"); Console.WriteLine($" Pointer to relocations = {entry.PointerToRelocations}"); @@ -1071,9 +1064,9 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" COFF Symbol Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.COFFFileHeader.PointerToSymbolTable == 0 - || _executable.COFFFileHeader.NumberOfSymbols == 0 - || _executable.COFFSymbolTable.Length == 0) + if (PointerToSymbolTable == 0 + || NumberOfSymbols == 0 + || COFFSymbolTable.Length == 0) { Console.WriteLine(" No COFF symbol table items"); } @@ -1082,9 +1075,9 @@ namespace BurnOutSharp.Wrappers int auxSymbolsRemaining = 0; int currentSymbolType = 0; - for (int i = 0; i < _executable.COFFSymbolTable.Length; i++) + for (int i = 0; i < COFFSymbolTable.Length; i++) { - var entry = _executable.COFFSymbolTable[i]; + var entry = COFFSymbolTable[i]; Console.WriteLine($" COFF Symbol Table Entry {i} (Subtype {currentSymbolType})"); if (currentSymbolType == 0) { @@ -1199,18 +1192,18 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(); Console.WriteLine(" COFF String Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.COFFStringTable == null - || _executable.COFFStringTable.Strings == null - || _executable.COFFStringTable.Strings.Length == 0) + if (COFFStringTable == null + || COFFStringTable.Strings == null + || COFFStringTable.Strings.Length == 0) { Console.WriteLine(" No COFF string table items"); } else { - Console.WriteLine($" Total size: {_executable.COFFStringTable.TotalSize}"); - for (int i = 0; i < _executable.COFFStringTable.Strings.Length; i++) + Console.WriteLine($" Total size: {COFFStringTable.TotalSize}"); + for (int i = 0; i < COFFStringTable.Strings.Length; i++) { - string entry = _executable.COFFStringTable.Strings[i]; + string entry = COFFStringTable.Strings[i]; Console.WriteLine($" COFF String Table Entry {i})"); Console.WriteLine($" Value = {entry}"); } @@ -1226,17 +1219,17 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Attribute Certificate Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.CertificateTable == null - || _executable.OptionalHeader.CertificateTable.VirtualAddress == 0 - || _executable.AttributeCertificateTable.Length == 0) + if (OH_CertificateTable == null + || OH_CertificateTable.VirtualAddress == 0 + || AttributeCertificateTable.Length == 0) { Console.WriteLine(" No attribute certificate table items"); } else { - for (int i = 0; i < _executable.AttributeCertificateTable.Length; i++) + for (int i = 0; i < AttributeCertificateTable.Length; i++) { - var entry = _executable.AttributeCertificateTable[i]; + var entry = AttributeCertificateTable[i]; Console.WriteLine($" Attribute Certificate Table Entry {i}"); Console.WriteLine($" Length = {entry.Length}"); Console.WriteLine($" Revision = {entry.Revision}"); @@ -1288,22 +1281,66 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Delay-Load Directory Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.DelayImportDescriptor == null - || _executable.OptionalHeader.DelayImportDescriptor.VirtualAddress == 0 - || _executable.DelayLoadDirectoryTable == null) + if (OH_DelayImportDescriptor == null + || OH_DelayImportDescriptor.VirtualAddress == 0 + || DelayLoadDirectoryTable == null) { Console.WriteLine(" No delay-load directory table items"); } else { - Console.WriteLine($" Attributes = {_executable.DelayLoadDirectoryTable.Attributes}"); - Console.WriteLine($" Name RVA = {_executable.DelayLoadDirectoryTable.Name}"); - Console.WriteLine($" Module handle = {_executable.DelayLoadDirectoryTable.ModuleHandle}"); - Console.WriteLine($" Delay import address table RVA = {_executable.DelayLoadDirectoryTable.DelayImportAddressTable}"); - Console.WriteLine($" Delay import name table RVA = {_executable.DelayLoadDirectoryTable.DelayImportNameTable}"); - Console.WriteLine($" Bound delay import table RVA = {_executable.DelayLoadDirectoryTable.BoundDelayImportTable}"); - Console.WriteLine($" Unload delay import table RVA = {_executable.DelayLoadDirectoryTable.UnloadDelayImportTable}"); - Console.WriteLine($" Timestamp = {_executable.DelayLoadDirectoryTable.TimeStamp}"); + Console.WriteLine($" Attributes = {DelayLoadDirectoryTable.Attributes}"); + Console.WriteLine($" Name RVA = {DelayLoadDirectoryTable.Name}"); + Console.WriteLine($" Module handle = {DelayLoadDirectoryTable.ModuleHandle}"); + Console.WriteLine($" Delay import address table RVA = {DelayLoadDirectoryTable.DelayImportAddressTable}"); + Console.WriteLine($" Delay import name table RVA = {DelayLoadDirectoryTable.DelayImportNameTable}"); + Console.WriteLine($" Bound delay import table RVA = {DelayLoadDirectoryTable.BoundDelayImportTable}"); + Console.WriteLine($" Unload delay import table RVA = {DelayLoadDirectoryTable.UnloadDelayImportTable}"); + Console.WriteLine($" Timestamp = {DelayLoadDirectoryTable.TimeStamp}"); + } + Console.WriteLine(); + } + + /// + /// Print base relocation table information + /// + private void PrintBaseRelocationTable() + { + Console.WriteLine(" Base Relocation Table Information:"); + Console.WriteLine(" -------------------------"); + if (OH_BaseRelocationTable == null + || OH_BaseRelocationTable.VirtualAddress == 0 + || BaseRelocationTable == null) + { + Console.WriteLine(" No base relocation table items"); + } + else + { + for (int i = 0; i < BaseRelocationTable.Length; i++) + { + var baseRelocationTableEntry = BaseRelocationTable[i]; + Console.WriteLine($" Base Relocation Table Entry {i}"); + Console.WriteLine($" Page RVA: {baseRelocationTableEntry.PageRVA}"); + Console.WriteLine($" Page physical address: {baseRelocationTableEntry.PageRVA.ConvertVirtualAddress(SectionTable)}"); + Console.WriteLine($" Block size: {baseRelocationTableEntry.BlockSize}"); + + Console.WriteLine($" Base Relocation Table {i} Type and Offset Information:"); + Console.WriteLine(" -------------------------"); + if (baseRelocationTableEntry.TypeOffsetFieldEntries == null || baseRelocationTableEntry.TypeOffsetFieldEntries.Length == 0) + { + Console.WriteLine(" No base relocation table type and offset entries"); + } + else + { + for (int j = 0; j < baseRelocationTableEntry.TypeOffsetFieldEntries.Length; j++) + { + var typeOffsetFieldEntry = baseRelocationTableEntry.TypeOffsetFieldEntries[j]; + Console.WriteLine($" Type and Offset Entry {j}"); + Console.WriteLine($" Type: {typeOffsetFieldEntry.BaseRelocationType}"); + Console.WriteLine($" Offset: {typeOffsetFieldEntry.Offset}"); + } + } + } } Console.WriteLine(); } @@ -1315,18 +1352,18 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Debug Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.Debug == null - || _executable.OptionalHeader.Debug.VirtualAddress == 0 - || _executable.DebugTable == null) + if (OH_Debug == null + || OH_Debug.VirtualAddress == 0 + || DebugTable == null) { Console.WriteLine(" No debug table items"); } else { // TODO: If more sections added, model this after the Export Table - for (int i = 0; i < _executable.DebugTable.DebugDirectoryTable.Length; i++) + for (int i = 0; i < DebugTable.DebugDirectoryTable.Length; i++) { - var debugDirectoryEntry = _executable.DebugTable.DebugDirectoryTable[i]; + var debugDirectoryEntry = DebugTable.DebugDirectoryTable[i]; Console.WriteLine($" Debug Directory Table Entry {i}"); Console.WriteLine($" Characteristics: {debugDirectoryEntry.Characteristics}"); Console.WriteLine($" Time/Date stamp: {debugDirectoryEntry.TimeDateStamp}"); @@ -1348,9 +1385,9 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Export Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.ExportTable == null - || _executable.OptionalHeader.ExportTable.VirtualAddress == 0 - || _executable.ExportTable == null) + if (OH_ExportTable == null + || OH_ExportTable.VirtualAddress == 0 + || ExportTable == null) { Console.WriteLine(" No export table items"); } @@ -1359,31 +1396,31 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(); Console.WriteLine(" Export Directory Table Information:"); Console.WriteLine(" -------------------------"); - Console.WriteLine($" Export flags: {_executable.ExportTable.ExportDirectoryTable.ExportFlags}"); - Console.WriteLine($" Time/Date stamp: {_executable.ExportTable.ExportDirectoryTable.TimeDateStamp}"); - Console.WriteLine($" Major version: {_executable.ExportTable.ExportDirectoryTable.MajorVersion}"); - Console.WriteLine($" Minor version: {_executable.ExportTable.ExportDirectoryTable.MinorVersion}"); - Console.WriteLine($" Name RVA: {_executable.ExportTable.ExportDirectoryTable.NameRVA}"); - Console.WriteLine($" Name: {_executable.ExportTable.ExportDirectoryTable.Name}"); - Console.WriteLine($" Ordinal base: {_executable.ExportTable.ExportDirectoryTable.OrdinalBase}"); - Console.WriteLine($" Address table entries: {_executable.ExportTable.ExportDirectoryTable.AddressTableEntries}"); - Console.WriteLine($" Number of name pointers: {_executable.ExportTable.ExportDirectoryTable.NumberOfNamePointers}"); - Console.WriteLine($" Export address table RVA: {_executable.ExportTable.ExportDirectoryTable.ExportAddressTableRVA}"); - Console.WriteLine($" Name pointer table RVA: {_executable.ExportTable.ExportDirectoryTable.NamePointerRVA}"); - Console.WriteLine($" Ordinal table RVA: {_executable.ExportTable.ExportDirectoryTable.OrdinalTableRVA}"); + Console.WriteLine($" Export flags: {ExportTable.ExportDirectoryTable.ExportFlags}"); + Console.WriteLine($" Time/Date stamp: {ExportTable.ExportDirectoryTable.TimeDateStamp}"); + Console.WriteLine($" Major version: {ExportTable.ExportDirectoryTable.MajorVersion}"); + Console.WriteLine($" Minor version: {ExportTable.ExportDirectoryTable.MinorVersion}"); + Console.WriteLine($" Name RVA: {ExportTable.ExportDirectoryTable.NameRVA}"); + Console.WriteLine($" Name: {ExportTable.ExportDirectoryTable.Name}"); + Console.WriteLine($" Ordinal base: {ExportTable.ExportDirectoryTable.OrdinalBase}"); + Console.WriteLine($" Address table entries: {ExportTable.ExportDirectoryTable.AddressTableEntries}"); + Console.WriteLine($" Number of name pointers: {ExportTable.ExportDirectoryTable.NumberOfNamePointers}"); + Console.WriteLine($" Export address table RVA: {ExportTable.ExportDirectoryTable.ExportAddressTableRVA}"); + Console.WriteLine($" Name pointer table RVA: {ExportTable.ExportDirectoryTable.NamePointerRVA}"); + Console.WriteLine($" Ordinal table RVA: {ExportTable.ExportDirectoryTable.OrdinalTableRVA}"); Console.WriteLine(); Console.WriteLine(" Export Address Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ExportTable.ExportAddressTable == null || _executable.ExportTable.ExportAddressTable.Length == 0) + if (ExportTable.ExportAddressTable == null || ExportTable.ExportAddressTable.Length == 0) { Console.WriteLine(" No export address table items"); } else { - for (int i = 0; i < _executable.ExportTable.ExportAddressTable.Length; i++) + for (int i = 0; i < ExportTable.ExportAddressTable.Length; i++) { - var exportAddressTableEntry = _executable.ExportTable.ExportAddressTable[i]; + var exportAddressTableEntry = ExportTable.ExportAddressTable[i]; Console.WriteLine($" Export Address Table Entry {i}"); Console.WriteLine($" Export RVA / Forwarder RVA: {exportAddressTableEntry.ExportRVA}"); } @@ -1392,15 +1429,15 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Name Pointer Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ExportTable.NamePointerTable?.Pointers == null || _executable.ExportTable.NamePointerTable.Pointers.Length == 0) + if (ExportTable.NamePointerTable?.Pointers == null || ExportTable.NamePointerTable.Pointers.Length == 0) { Console.WriteLine(" No name pointer table items"); } else { - for (int i = 0; i < _executable.ExportTable.NamePointerTable.Pointers.Length; i++) + for (int i = 0; i < ExportTable.NamePointerTable.Pointers.Length; i++) { - var namePointerTableEntry = _executable.ExportTable.NamePointerTable.Pointers[i]; + var namePointerTableEntry = ExportTable.NamePointerTable.Pointers[i]; Console.WriteLine($" Name Pointer Table Entry {i}"); Console.WriteLine($" Pointer: {namePointerTableEntry}"); } @@ -1409,15 +1446,15 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Ordinal Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ExportTable.OrdinalTable?.Indexes == null || _executable.ExportTable.OrdinalTable.Indexes.Length == 0) + if (ExportTable.OrdinalTable?.Indexes == null || ExportTable.OrdinalTable.Indexes.Length == 0) { Console.WriteLine(" No ordinal table items"); } else { - for (int i = 0; i < _executable.ExportTable.OrdinalTable.Indexes.Length; i++) + for (int i = 0; i < ExportTable.OrdinalTable.Indexes.Length; i++) { - var ordinalTableEntry = _executable.ExportTable.OrdinalTable.Indexes[i]; + var ordinalTableEntry = ExportTable.OrdinalTable.Indexes[i]; Console.WriteLine($" Ordinal Table Entry {i}"); Console.WriteLine($" Index: {ordinalTableEntry}"); } @@ -1426,15 +1463,15 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Export Name Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ExportTable.ExportNameTable?.Strings == null || _executable.ExportTable.ExportNameTable.Strings.Length == 0) + if (ExportTable.ExportNameTable?.Strings == null || ExportTable.ExportNameTable.Strings.Length == 0) { Console.WriteLine(" No export name table items"); } else { - for (int i = 0; i < _executable.ExportTable.ExportNameTable.Strings.Length; i++) + for (int i = 0; i < ExportTable.ExportNameTable.Strings.Length; i++) { - var exportNameTableEntry = _executable.ExportTable.ExportNameTable.Strings[i]; + var exportNameTableEntry = ExportTable.ExportNameTable.Strings[i]; Console.WriteLine($" Export Name Table Entry {i}"); Console.WriteLine($" String: {exportNameTableEntry}"); } @@ -1450,9 +1487,9 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Import Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.ImportTable == null - || _executable.OptionalHeader.ImportTable.VirtualAddress == 0 - || _executable.ImportTable == null) + if (OH_ImportTable == null + || OH_ImportTable.VirtualAddress == 0 + || ImportTable == null) { Console.WriteLine(" No import table items"); } @@ -1461,15 +1498,15 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(); Console.WriteLine(" Import Directory Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ImportTable.ImportDirectoryTable == null || _executable.ImportTable.ImportDirectoryTable.Length == 0) + if (ImportTable.ImportDirectoryTable == null || ImportTable.ImportDirectoryTable.Length == 0) { Console.WriteLine(" No import directory table items"); } else { - for (int i = 0; i < _executable.ImportTable.ImportDirectoryTable.Length; i++) + for (int i = 0; i < ImportTable.ImportDirectoryTable.Length; i++) { - var importDirectoryTableEntry = _executable.ImportTable.ImportDirectoryTable[i]; + var importDirectoryTableEntry = ImportTable.ImportDirectoryTable[i]; Console.WriteLine($" Import Directory Table Entry {i}"); Console.WriteLine($" Import lookup table RVA: {importDirectoryTableEntry.ImportLookupTableRVA}"); Console.WriteLine($" Time/Date stamp: {importDirectoryTableEntry.TimeDateStamp}"); @@ -1483,13 +1520,13 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Import Lookup Tables Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ImportTable.ImportLookupTables == null || _executable.ImportTable.ImportLookupTables.Count == 0) + if (ImportTable.ImportLookupTables == null || ImportTable.ImportLookupTables.Count == 0) { Console.WriteLine(" No import lookup tables"); } else { - foreach (var kvp in _executable.ImportTable.ImportLookupTables) + foreach (var kvp in ImportTable.ImportLookupTables) { int index = kvp.Key; var importLookupTable = kvp.Value; @@ -1520,13 +1557,13 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Import Address Tables Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ImportTable.ImportAddressTables == null || _executable.ImportTable.ImportAddressTables.Count == 0) + if (ImportTable.ImportAddressTables == null || ImportTable.ImportAddressTables.Count == 0) { Console.WriteLine(" No import address tables"); } else { - foreach (var kvp in _executable.ImportTable.ImportAddressTables) + foreach (var kvp in ImportTable.ImportAddressTables) { int index = kvp.Key; var importAddressTable = kvp.Value; @@ -1544,7 +1581,7 @@ namespace BurnOutSharp.Wrappers { var importLookupTableEntry = importAddressTable[i]; Console.WriteLine($" Import Address Table {index} Entry {i}"); - if (_executable.OptionalHeader.Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) + if (OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32) Console.WriteLine($" Address: {importLookupTableEntry.Address_PE32}"); else Console.WriteLine($" Address: {importLookupTableEntry.Address_PE32Plus}"); @@ -1556,15 +1593,15 @@ namespace BurnOutSharp.Wrappers Console.WriteLine(" Hint/Name Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.ImportTable.HintNameTable == null || _executable.ImportTable.HintNameTable.Length == 0) + if (ImportTable.HintNameTable == null || ImportTable.HintNameTable.Length == 0) { Console.WriteLine(" No hint/name table items"); } else { - for (int i = 0; i < _executable.ImportTable.HintNameTable.Length; i++) + for (int i = 0; i < ImportTable.HintNameTable.Length; i++) { - var hintNameTableEntry = _executable.ImportTable.HintNameTable[i]; + var hintNameTableEntry = ImportTable.HintNameTable[i]; Console.WriteLine($" Hint/Name Table Entry {i}"); Console.WriteLine($" Hint: {hintNameTableEntry.Hint}"); Console.WriteLine($" Name: {hintNameTableEntry.Name}"); @@ -1581,15 +1618,15 @@ namespace BurnOutSharp.Wrappers { Console.WriteLine(" Resource Directory Table Information:"); Console.WriteLine(" -------------------------"); - if (_executable.OptionalHeader?.ResourceTable == null - || _executable.OptionalHeader.ResourceTable.VirtualAddress == 0 - || _executable.ResourceDirectoryTable == null) + if (OH_ResourceTable == null + || OH_ResourceTable.VirtualAddress == 0 + || ResourceDirectoryTable == null) { Console.WriteLine(" No resource directory table items"); } else { - PrintResourceDirectoryTable(_executable.ResourceDirectoryTable, level: 0, types: new List()); + PrintResourceDirectoryTable(ResourceDirectoryTable, level: 0, types: new List()); } Console.WriteLine(); } @@ -2292,6 +2329,10 @@ namespace BurnOutSharp.Wrappers /// Enumerable of matching resources public IEnumerable FindDialogByTitle(string title) { + // Ensure that we have the resource data cached + if (ResourceData == null) + return Enumerable.Empty(); + return ResourceData.Select(r => r.Value) .Select(r => r as Models.PortableExecutable.DialogBoxResource) .Where(d => d != null) @@ -2309,6 +2350,10 @@ namespace BurnOutSharp.Wrappers /// Enumerable of matching resources public IEnumerable FindDialogBoxByItemTitle(string title) { + // Ensure that we have the resource data cached + if (ResourceData == null) + return Enumerable.Empty(); + return ResourceData.Select(r => r.Value) .Select(r => r as Models.PortableExecutable.DialogBoxResource) .Where(d => d != null) @@ -2331,6 +2376,24 @@ namespace BurnOutSharp.Wrappers }); } + /// + /// Find string table resources by contained string entry + /// + /// String entry to check for + /// Enumerable of matching resources + public IEnumerable> FindStringTableByEntry(string entry) + { + // Ensure that we have the resource data cached + if (ResourceData == null) + return Enumerable.Empty>(); + + return ResourceData.Select(r => r.Value) + .Select(r => r as Dictionary) + .Where(st => st != null) + .Where(st => st.Select(kvp => kvp.Value) + .Any(s => s.Contains(entry))); + } + /// /// Find unparsed resources by type name /// @@ -2338,6 +2401,10 @@ namespace BurnOutSharp.Wrappers /// Enumerable of matching resources public IEnumerable FindResourceByNamedType(string typeName) { + // Ensure that we have the resource data cached + if (ResourceData == null) + return Enumerable.Empty(); + return ResourceData.Where(kvp => kvp.Key.Contains(typeName)) .Select(kvp => kvp.Value as byte[]) .Where(b => b != null); @@ -2350,6 +2417,10 @@ namespace BurnOutSharp.Wrappers /// Enumerable of matching resources public IEnumerable FindGenericResource(string value) { + // Ensure that we have the resource data cached + if (ResourceData == null) + return Enumerable.Empty(); + return ResourceData.Select(r => r.Value) .Select(r => r as byte[]) .Where(b => b != null) @@ -2379,7 +2450,7 @@ namespace BurnOutSharp.Wrappers } catch { } - return true; + return false; }); } @@ -2435,76 +2506,84 @@ namespace BurnOutSharp.Wrappers // If we have a known resource type if (types != null && types.Count > 0 && types[0] is uint resourceType) { - switch ((Models.PortableExecutable.ResourceType)resourceType) + try { - case Models.PortableExecutable.ResourceType.RT_CURSOR: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_BITMAP: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_ICON: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_MENU: - value = entry.AsMenu(); - break; - case Models.PortableExecutable.ResourceType.RT_DIALOG: - value = entry.AsDialogBox(); - break; - case Models.PortableExecutable.ResourceType.RT_STRING: - value = entry.AsStringTable(); - break; - case Models.PortableExecutable.ResourceType.RT_FONTDIR: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_FONT: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_ACCELERATOR: - value = entry.AsAcceleratorTableResource(); - break; - case Models.PortableExecutable.ResourceType.RT_RCDATA: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_MESSAGETABLE: - value = entry.AsMessageResourceData(); - break; - case Models.PortableExecutable.ResourceType.RT_GROUP_CURSOR: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_GROUP_ICON: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_VERSION: - _versionInfo = entry.AsVersionInfo(); - value = _versionInfo; - break; - case Models.PortableExecutable.ResourceType.RT_DLGINCLUDE: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_PLUGPLAY: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_VXD: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_ANICURSOR: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_ANIICON: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_HTML: - value = entry.Data; - break; - case Models.PortableExecutable.ResourceType.RT_MANIFEST: - _assemblyManifest = entry.AsAssemblyManifest(); - value = _versionInfo; - break; - default: - value = entry.Data; - break; + switch ((Models.PortableExecutable.ResourceType)resourceType) + { + case Models.PortableExecutable.ResourceType.RT_CURSOR: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_BITMAP: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_ICON: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_MENU: + value = entry.AsMenu(); + break; + case Models.PortableExecutable.ResourceType.RT_DIALOG: + value = entry.AsDialogBox(); + break; + case Models.PortableExecutable.ResourceType.RT_STRING: + value = entry.AsStringTable(); + break; + case Models.PortableExecutable.ResourceType.RT_FONTDIR: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_FONT: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_ACCELERATOR: + value = entry.AsAcceleratorTableResource(); + break; + case Models.PortableExecutable.ResourceType.RT_RCDATA: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_MESSAGETABLE: + value = entry.AsMessageResourceData(); + break; + case Models.PortableExecutable.ResourceType.RT_GROUP_CURSOR: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_GROUP_ICON: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_VERSION: + _versionInfo = entry.AsVersionInfo(); + value = _versionInfo; + break; + case Models.PortableExecutable.ResourceType.RT_DLGINCLUDE: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_PLUGPLAY: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_VXD: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_ANICURSOR: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_ANIICON: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_HTML: + value = entry.Data; + break; + case Models.PortableExecutable.ResourceType.RT_MANIFEST: + _assemblyManifest = entry.AsAssemblyManifest(); + value = _versionInfo; + break; + default: + value = entry.Data; + break; + } + } + catch + { + // Fall back on byte array data for malformed items + value = entry.Data; } } @@ -2552,7 +2631,7 @@ namespace BurnOutSharp.Wrappers public Models.PortableExecutable.SectionHeader GetFirstSection(string name, bool exact = false) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2577,7 +2656,7 @@ namespace BurnOutSharp.Wrappers public Models.PortableExecutable.SectionHeader GetLastSection(string name, bool exact = false) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2601,7 +2680,7 @@ namespace BurnOutSharp.Wrappers public Models.PortableExecutable.SectionHeader GetSection(int index) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2621,7 +2700,7 @@ namespace BurnOutSharp.Wrappers public byte[] GetFirstSectionData(string name, bool exact = false) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2634,8 +2713,8 @@ namespace BurnOutSharp.Wrappers return null; // Get the section data from the table - var section = _executable.SectionTable[index]; - uint address = section.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable); + var section = SectionTable[index]; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (address == 0) return null; @@ -2670,7 +2749,7 @@ namespace BurnOutSharp.Wrappers public byte[] GetFirstSectionDataWithOffset(string name, bool exact = false, int offset = 0) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2683,8 +2762,8 @@ namespace BurnOutSharp.Wrappers return null; // Get the section data from the table - var section = _executable.SectionTable[index]; - uint address = section.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable); + var section = SectionTable[index]; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (address == 0) return null; @@ -2706,7 +2785,7 @@ namespace BurnOutSharp.Wrappers public byte[] GetLastSectionData(string name, bool exact = false) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2719,8 +2798,8 @@ namespace BurnOutSharp.Wrappers return null; // Get the section data from the table - var section = _executable.SectionTable[index]; - uint address = section.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable); + var section = SectionTable[index]; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (address == 0) return null; @@ -2753,7 +2832,7 @@ namespace BurnOutSharp.Wrappers public byte[] GetSectionData(int index) { // If we have no sections - if (_executable.SectionTable == null || !SectionTable.Any()) + if (SectionTable == null || !SectionTable.Any()) return null; // If the section doesn't exist @@ -2761,8 +2840,8 @@ namespace BurnOutSharp.Wrappers return null; // Get the section data from the table - var section = _executable.SectionTable[index]; - uint address = section.VirtualAddress.ConvertVirtualAddress(_executable.SectionTable); + var section = SectionTable[index]; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); if (address == 0) return null; diff --git a/BurnOutSharp.Wrappers/WrapperBase.cs b/BurnOutSharp.Wrappers/WrapperBase.cs index 604ab480..ca4dd15e 100644 --- a/BurnOutSharp.Wrappers/WrapperBase.cs +++ b/BurnOutSharp.Wrappers/WrapperBase.cs @@ -73,10 +73,10 @@ namespace BurnOutSharp.Wrappers switch (_dataSource) { case DataSource.ByteArray: - return _byteArrayOffset + position + length < _byteArrayData.Length; + return _byteArrayOffset + position + length <= _byteArrayData.Length; case DataSource.Stream: - return position + length < _streamData.Length; + return position + length <= _streamData.Length; // Everything else is invalid case DataSource.UNKNOWN: diff --git a/BurnOutSharp/BurnOutSharp.csproj b/BurnOutSharp/BurnOutSharp.csproj index cd4b714d..edc77a54 100644 --- a/BurnOutSharp/BurnOutSharp.csproj +++ b/BurnOutSharp/BurnOutSharp.csproj @@ -73,11 +73,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - + + diff --git a/BurnOutSharp/ExecutableType/Microsoft/Constants.cs b/BurnOutSharp/ExecutableType/Microsoft/Constants.cs deleted file mode 100644 index 41bf3ae8..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Constants.cs +++ /dev/null @@ -1,74 +0,0 @@ -namespace BurnOutSharp.ExecutableType.Microsoft -{ - /// - /// All constant values needed for file header reading - /// - internal static class Constants - { - public const ushort IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ - public const ushort IMAGE_OS2_SIGNATURE = 0x454E; // NE - public const ushort IMAGE_OS2_SIGNATURE_LE = 0x454C; // LE - public const uint IMAGE_NT_SIGNATURE = 0x00004550; // PE00 - - #region IMAGE_DOS_HEADER - - public const ushort ENEWEXE = 0x40; // Value of E_LFARLC for new .EXEs - public const ushort ENEWHDR = 0x003C; // Offset in old hdr. of ptr. to new - public const ushort ERESWDS = 0x0010; // No. of reserved words (OLD) - public const ushort ERES1WDS = 0x0004; // No. of reserved words in e_res - public const ushort ERES2WDS = 0x000A; // No. of reserved words in e_res2 - public const ushort ECP = 0x0004; // Offset in struct of E_CP - public const ushort ECBLP = 0x0002; // Offset in struct of E_CBLP - public const ushort EMINALLOC = 0x000A; // Offset in struct of E_MINALLOC - - #endregion - - #region IMAGE_OS2_HEADER - - public const ushort NERESWORDS = 3; // 6 bytes reserved - public const ushort NECRC = 8; //Offset into new header of NE_CRC - - #endregion - - #region NewSeg - - public const ushort NSALIGN = 9; // Segment data aligned on 512 byte boundaries - public const ushort NSLOADED = 0x0004; // ns_sector field contains memory addr - - #endregion - - #region RsrcNameInfo - - public const ushort RSORDID = 0x8000; /* if high bit of ID set then integer id */ - - /* otherwise ID is offset of string from - the beginning of the resource table */ - /* Ideally these are the same as the */ - /* corresponding segment flags */ - public const ushort RNMOVE = 0x0010; /* Moveable resource */ - public const ushort RNPURE = 0x0020; /* Pure (read-only) resource */ - public const ushort RNPRELOAD = 0x0040; /* Preloaded resource */ - public const ushort RNDISCARD = 0xF000; /* Discard priority level for resource */ - - #endregion - - #region IMAGE_OPTIONAL_HEADER - - public const ushort IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16; - - #endregion - - #region IMAGE_SECTION_HEADER - - public const int IMAGE_SIZEOF_SHORT_NAME = 8; - - #endregion - - #region IMAGE_RESOURCE_DATA_ENTRY - - public const uint IMAGE_RESOURCE_DATA_IS_DIRECTORY = 0x80000000; - public const uint IMAGE_RESOURCE_NAME_IS_STRING = 0x80000000; - - #endregion - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Enums.cs b/BurnOutSharp/ExecutableType/Microsoft/Enums.cs deleted file mode 100644 index afa570f6..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Enums.cs +++ /dev/null @@ -1,1189 +0,0 @@ -using System; - -namespace BurnOutSharp.ExecutableType.Microsoft -{ - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#debug-type - public enum DebugType : uint - { - /// - /// An unknown value that is ignored by all tools. - /// - IMAGE_DEBUG_TYPE_UNKNOWN = 0, - - /// - /// The COFF debug information (line numbers, symbol table, and string table). - /// This type of debug information is also pointed to by fields in the file headers. - /// - IMAGE_DEBUG_TYPE_COFF = 1, - - /// - /// The Visual C++ debug information. - /// - IMAGE_DEBUG_TYPE_CODEVIEW = 2, - - /// - /// The frame pointer omission (FPO) information. - /// This information tells the debugger how to interpret nonstandard stack frames, - /// which use the EBP register for a purpose other than as a frame pointer. - /// - IMAGE_DEBUG_TYPE_FPO = 3, - - /// - /// The location of DBG file. - /// - IMAGE_DEBUG_TYPE_MISC = 4, - - /// - /// A copy of .pdata section. - /// - IMAGE_DEBUG_TYPE_EXCEPTION = 5, - - /// - /// Reserved. - /// - IMAGE_DEBUG_TYPE_FIXUP = 6, - - /// - /// The mapping from an RVA in image to an RVA in source image. - /// - IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7, - - /// - /// The mapping from an RVA in source image to an RVA in image. - /// - IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8, - - /// - /// Reserved for Borland. - /// - IMAGE_DEBUG_TYPE_BORLAND = 9, - - /// - /// Reserved. - /// - IMAGE_DEBUG_TYPE_RESERVED10 = 10, - - /// - /// Reserved. - /// - IMAGE_DEBUG_TYPE_CLSID = 11, - - /// - /// PE determinism or reproducibility. - /// - IMAGE_DEBUG_TYPE_REPRO = 16, - - /// - /// Extended DLL characteristics bits. - /// - IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#dll-characteristics - [Flags] - public enum DllCharacteristics : ushort - { - /// - /// Reserved, must be zero. - /// - Reserved1 = 0x0001, - - /// - /// Reserved, must be zero. - /// - Reserved2 = 0x0002, - - /// - /// Reserved, must be zero. - /// - Reserved4 = 0x0004, - - /// - /// Reserved, must be zero. - /// - Reserved8 = 0x0008, - - /// - /// Image can handle a high entropy 64-bit virtual address space. - /// - IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, - - /// - /// DLL can be relocated at load time. - /// - IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, - - /// - /// Code Integrity checks are enforced. - /// - IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, - - /// - /// Image is NX compatible. - /// - IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100, - - /// - /// Isolation aware, but do not isolate the image. - /// - IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, - - /// - /// Does not use structured exception (SE) handling. - /// No SE handler may be called in this image. - /// - IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, - - /// - /// Do not bind the image. - /// - IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, - - /// - /// Image must execute in an AppContainer. - /// - IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000, - - /// - /// A WDM driver. - /// - IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, - - /// - /// Image supports Control Flow Guard. - /// - IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000, - - /// - /// Terminal Server aware. - /// - IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000, - } - - // https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo - [Flags] - public enum FileInfoFileFlags : uint - { - /// - /// The file contains debugging information or is compiled with debugging features enabled. - /// - VS_FF_DEBUG = 0x00000001, - - /// - /// The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data. - /// - VS_FF_INFOINFERRED = 0x00000010, - - /// - /// The file has been modified and is not identical to the original shipping file of the same version number. - /// - VS_FF_PATCHED = 0x00000004, - - /// - /// The file is a development version, not a commercially released product. - /// - VS_FF_PRERELEASE = 0x00000002, - - /// - /// The file was not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry. - /// - VS_FF_PRIVATEBUILD = 0x00000008, - - /// - /// The file was built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry. - /// - VS_FF_SPECIALBUILD = 0x00000020, - } - - // https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo - public enum FileInfoFileType : uint - { - /// - /// The file contains an application. - /// - VFT_APP = 0x00000001, - - /// - /// The file contains a DLL. - /// - VFT_DLL = 0x00000002, - - /// - /// The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver. - /// - VFT_DRV = 0x00000003, - - /// - /// The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file. - /// - VFT_FONT = 0x00000004, - - /// - /// The file contains a static-link library. - /// - VFT_STATIC_LIB = 0x00000007, - - /// - /// The file type is unknown to the system. - /// - VFT_UNKNOWN = 0x00000000, - - /// - /// The file contains a virtual device. - /// - VFT_VXD = 0x00000005, - } - - // https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo - public enum FileInfoFileSubtype : uint - { - #region VFT_DRV - - /// - /// The file contains a communications driver. - /// - VFT2_DRV_COMM = 0x0000000A, - - /// - /// The file contains a display driver. - /// - VFT2_DRV_DISPLAY = 0x00000004, - - /// - /// The file contains an installable driver. - /// - VFT2_DRV_INSTALLABLE = 0x00000008, - - /// - /// The file contains a keyboard driver. - /// - VFT2_DRV_KEYBOARD = 0x00000002, - - /// - /// The file contains a language driver. - /// - VFT2_DRV_LANGUAGE = 0x00000003, - - /// - /// The file contains a mouse driver. - /// - VFT2_DRV_MOUSE = 0x00000005, - - /// - /// The file contains a network driver. - /// - VFT2_DRV_NETWORK = 0x00000006, - - /// - /// The file contains a printer driver. - /// - VFT2_DRV_PRINTER = 0x00000001, - - /// - /// The file contains a sound driver. - /// - VFT2_DRV_SOUND = 0x00000009, - - /// - /// The file contains a system driver. - /// - VFT2_DRV_SYSTEM = 0x00000007, - - /// - /// The file contains a versioned printer driver. - /// - VFT2_DRV_VERSIONED_PRINTER = 0x0000000C, - - #endregion - - #region VFT_FONT - - /// - /// The file contains a raster font. - /// - VFT2_FONT_RASTER = 0x00000001, - - /// - /// The file contains a TrueType font. - /// - VFT2_FONT_TRUETYPE = 0x00000003, - - /// - /// The file contains a vector font. - /// - VFT2_FONT_VECTOR = 0x00000002, - - #endregion - - /// - /// The driver type is unknown by the system. - /// The font type is unknown by the system. - /// - VFT2_UNKNOWN = 0x00000000, - } - - // https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo - [Flags] - public enum FileInfoOS : uint - { - /// - /// The file was designed for MS-DOS. - /// - VOS_DOS = 0x00010000, - - /// - /// The file was designed for Windows NT. - /// - VOS_NT = 0x00040000, - - /// - /// The file was designed for 16-bit Windows. - /// - VOS__WINDOWS16 = 0x00000001, - - /// - /// The file was designed for 32-bit Windows. - /// - VOS__WINDOWS32 = 0x00000004, - - /// - /// The file was designed for 16-bit OS/2. - /// - VOS_OS216 = 0x00020000, - - /// - /// The file was designed for 32-bit OS/2. - /// - VOS_OS232 = 0x00030000, - - /// - /// The file was designed for 16-bit Presentation Manager. - /// - VOS__PM16 = 0x00000002, - - /// - /// The file was designed for 32-bit Presentation Manager. - /// - VOS__PM32 = 0x00000003, - - /// - /// The operating system for which the file was designed is unknown to the system. - /// - VOS_UNKNOWN = 0x00000000, - - /// - /// The file was designed for 16-bit Windows running on MS-DOS. - /// - VOS_DOS_WINDOWS16 = 0x00010001, - - /// - /// The file was designed for 32-bit Windows running on MS-DOS. - /// - VOS_DOS_WINDOWS32 = 0x00010004, - - /// - /// The file was designed for Windows NT. - /// - VOS_NT_WINDOWS32 = 0x00040004, - - /// - /// The file was designed for 16-bit Presentation Manager running on 16-bit OS/2. - /// - VOS_OS216_PM16 = 0x00020002, - - /// - /// The file was designed for 32-bit Presentation Manager running on 32-bit OS/2. - /// - VOS_OS232_PM32 = 0x00030003, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-data-directories-image-only - public enum ImageDirectory : byte - { - /// - /// The export table address and size. (.edata) - /// - IMAGE_DIRECTORY_ENTRY_EXPORT = 0, - - /// - /// The import table address and size. (.idata) - /// - IMAGE_DIRECTORY_ENTRY_IMPORT = 1, - - /// - /// The resource table address and size. (.rsrc) - /// - IMAGE_DIRECTORY_ENTRY_RESOURCE = 2, - - /// - /// The exception table address and size. (.pdata) - /// - IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3, - - /// - /// The attribute certificate table address and size. - /// - IMAGE_DIRECTORY_ENTRY_SECURITY = 4, - - /// - /// The base relocation table address and size. (.reloc) - /// - IMAGE_DIRECTORY_ENTRY_BASERELOC = 5, - - /// - /// The debug data starting address and size. (.debug) - /// - IMAGE_DIRECTORY_ENTRY_DEBUG = 6, - - /// - /// Reserved, must be 0 - /// - IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7, - - /// - /// The RVA of the value to be stored in the global pointer register. - /// The size member of this structure must be set to zero. - /// - IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8, - - /// - /// The thread local storage (TLS) table address and size. (.tls) - /// - IMAGE_DIRECTORY_ENTRY_TLS = 9, - - /// - /// The load configuration table address and size. - /// - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10, - - /// - /// The bound import table address and size. - /// - IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11, - - /// - /// The import address table address and size. - /// - IMAGE_DIRECTORY_ENTRY_IAT = 12, - - /// - /// The delay import descriptor address and size. - /// - IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13, - - /// - /// The CLR runtime header address and size. (.cormeta) - /// - IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14, - - /// - /// Reserved, must be zero - /// - IMAGE_DIRECTORY_RESERVED = 15, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#characteristics - [Flags] - public enum ImageObjectCharacteristics : ushort - { - /// - /// Image only, Windows CE, and Microsoft Windows NT and later. - /// This indicates that the file does not contain base relocations and must therefore be loaded at its preferred base address. - /// If the base address is not available, the loader reports an error. - /// The default behavior of the linker is to strip base relocations from executable (EXE) files. - /// - IMAGE_FILE_RELOCS_STRIPPED = 0x0001, - - /// - /// Image only. This indicates that the image file is valid and can be run. - /// If this flag is not set, it indicates a linker error. - /// - IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002, - - /// - /// COFF line numbers have been removed. - /// This flag is deprecated and should be zero. - /// - [Obsolete] - IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004, - - /// - /// COFF symbol table entries for local symbols have been removed. - /// This flag is deprecated and should be zero. - /// - [Obsolete] - IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008, - - /// - /// Obsolete. Aggressively trim working set. - /// This flag is deprecated for Windows 2000 and later and must be zero. - /// - [Obsolete] - IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010, - - /// - /// Application can handle > 2-GB addresses. - /// - IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020, - - /// - /// This flag is reserved for future use. - /// - Reserved64 = 0x0040, - - /// - /// Little endian: the least significant bit (LSB) precedes the most significant bit (MSB) in memory. - /// This flag is deprecated and should be zero. - /// - [Obsolete] - IMAGE_FILE_BYTES_REVERSED_LO = 0x0080, - - /// - /// Machine is based on a 32-bit-word architecture. - /// - IMAGE_FILE_32BIT_MACHINE = 0x0100, - - /// - /// Debugging information is removed from the image file. - /// - IMAGE_FILE_DEBUG_STRIPPED = 0x0200, - - /// - /// If the image is on removable media, fully load it and copy it to the swap file. - /// - IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400, - - /// - /// If the image is on network media, fully load it and copy it to the swap file. - /// - IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800, - - /// - /// The image file is a system file, not a user program. - /// - IMAGE_FILE_SYSTEM = 0x1000, - - /// - /// The image file is a dynamic-link library (DLL). - /// Such files are considered executable files for almost all purposes, although they cannot be directly run. - /// - IMAGE_FILE_DLL = 0x2000, - - /// - /// The file should be run only on a uniprocessor machine. - /// - IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000, - - /// - /// Big endian: the MSB precedes the LSB in memory. - /// This flag is deprecated and should be zero. - /// - [Obsolete] - IMAGE_FILE_BYTES_REVERSED_HI = 0x8000, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types - public enum MachineType : ushort - { - /// - /// The content of this field is assumed to be applicable to any machine type - /// - IMAGE_FILE_MACHINE_UNKNOWN = 0x0000, - - /// - /// Matsushita AM33 - /// - IMAGE_FILE_MACHINE_AM33 = 0x01d3, - - /// - /// x64 - /// - IMAGE_FILE_MACHINE_AMD64 = 0x8664, - - /// - /// ARM little endian - /// - IMAGE_FILE_MACHINE_ARM = 0x01c0, - - /// - /// ARM64 little endian - /// - IMAGE_FILE_MACHINE_ARM64 = 0xaa64, - - /// - /// ARM Thumb-2 little endian - /// - IMAGE_FILE_MACHINE_ARMNT = 0x01c4, - - /// - /// EFI byte code - /// - IMAGE_FILE_MACHINE_EBC = 0x0ebc, - - /// - /// Intel 386 or later processors and compatible processors - /// - IMAGE_FILE_MACHINE_I386 = 0x014c, - - /// - /// Intel Itanium processor family - /// - IMAGE_FILE_MACHINE_IA64 = 0x0200, - - /// - /// Mitsubishi M32R little endian - /// - IMAGE_FILE_MACHINE_M32R = 0x9041, - - /// - /// MIPS16 - /// - IMAGE_FILE_MACHINE_MIPS16 = 0x0266, - - /// - /// MIPS with FPU - /// - IMAGE_FILE_MACHINE_MIPSFPU = 0x0366, - - /// - /// MIPS16 with FPU - /// - IMAGE_FILE_MACHINE_MIPSFPU16 = 0x0466, - - /// - /// Power PC little endian - /// - IMAGE_FILE_MACHINE_POWERPC = 0x01f0, - - /// - /// Power PC with floating point support - /// - IMAGE_FILE_MACHINE_POWERPCFP = 0x01f1, - - /// - /// MIPS little endian - /// - IMAGE_FILE_MACHINE_R4000 = 0x0166, - - /// - /// RISC-V 32-bit address space - /// - IMAGE_FILE_MACHINE_RISCV32 = 0x5032, - - /// - /// RISC-V 64-bit address space - /// - IMAGE_FILE_MACHINE_RISCV64 = 0x5064, - - /// - /// RISC-V 128-bit address space - /// - IMAGE_FILE_MACHINE_RISCV128 = 0x5128, - - /// - /// Hitachi SH3 - /// - IMAGE_FILE_MACHINE_SH3 = 0x01a2, - - /// - /// Hitachi SH3 DSP - /// - IMAGE_FILE_MACHINE_SH3DSP = 0x01a3, - - /// - /// Hitachi SH4 - /// - IMAGE_FILE_MACHINE_SH4 = 0x01a6, - - /// - /// Hitachi SH5 - /// - IMAGE_FILE_MACHINE_SH5 = 0x01a8, - - /// - /// Thumb - /// - IMAGE_FILE_MACHINE_THUMB = 0x01c2, - - /// - /// MIPS little-endian WCE v2 - /// - IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-image-only - public enum OptionalHeaderType : ushort - { - /// - /// ROM image - /// - ROMImage = 0x107, - - /// - /// Normal executable file - /// - PE32 = 0x10b, - - /// - /// PE32+ images allow for a 64-bit address space while limiting the image size to 2 gigabytes. - /// - PE32Plus = 0x20b, - } - - /// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm - [Flags] - public enum ResourceTableEntryFlags : ushort - { - /// - /// Resource is not fixed. - /// - MOVEABLE = 0x0010, - - /// - /// Resource can be shared. - /// - PURE = 0x0020, - - /// - /// Resource is preloaded. - /// - PRELOAD = 0x0040, - } - - /// - /// Predefined Resource Types - /// - public enum ResourceTypes : ushort - { - RT_CURSOR = 1, - RT_BITMAP = 2, - RT_ICON = 3, - RT_MENU = 4, - RT_DIALOG = 5, - RT_STRING = 6, - RT_FONTDIR = 7, - RT_FONT = 8, - RT_ACCELERATOR = 9, - RT_RCDATA = 10, - RT_MESSAGELIST = 11, // RT_MESSAGETABLE - RT_GROUP_CURSOR = 12, - RT_RESERVED_1 = 13, // Undefined - RT_GROUP_ICON = 14, - RT_RESERVED_2 = 15, // Undefined - RT_VERSION = 16, - RT_DLGINCLUDE = 17, - RT_PLUGPLAY = 19, - RT_VXD = 20, - RT_ANICURSOR = 21, - - RT_NEWRESOURCE = 0x2000, - RT_NEWBITMAP = (RT_BITMAP |RT_NEWRESOURCE), - RT_NEWMENU = (RT_MENU |RT_NEWRESOURCE), - RT_NEWDIALOG = (RT_DIALOG |RT_NEWRESOURCE), - RT_ERROR = 0x7fff, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-flags - [Flags] - public enum SectionCharacteristics : uint - { - /// - /// Reserved for future use. - /// - Reserved0 = 0x00000000, - - /// - /// Reserved for future use. - /// - Reserved1 = 0x00000001, - - /// - /// Reserved for future use. - /// - Reserved2 = 0x00000002, - - /// - /// Reserved for future use. - /// - Reserved4 = 0x00000004, - - /// - /// The section should not be padded to the next boundary. - /// This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. - /// This is valid only for object files. - /// - IMAGE_SCN_TYPE_NO_PAD = 0x00000008, - - /// - /// Reserved for future use. - /// - Reserved16 = 0x00000010, - - /// - /// The section contains executable code. - /// - IMAGE_SCN_CNT_CODE = 0x00000020, - - /// - /// The section contains initialized data. - /// - IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, - - /// - /// The section contains uninitialized data. - /// - IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, - - /// - /// Reserved for future use. - /// - IMAGE_SCN_LNK_OTHER = 0x00000100, - - /// - /// The section contains comments or other information. - /// The .drectve section has this type. - /// This is valid for object files only. - /// - IMAGE_SCN_LNK_INFO = 0x00000200, - - /// - /// Reserved for future use. - /// - Reserved1024 = 0x00000400, - - /// - /// The section will not become part of the image. - /// This is valid only for object files. - /// - IMAGE_SCN_LNK_REMOVE = 0x00000800, - - /// - /// The section contains COMDAT data. - /// This is valid only for object files. - /// - IMAGE_SCN_LNK_COMDAT = 0x00001000, - - /// - /// The section contains data referenced through the global pointer (GP). - /// - IMAGE_SCN_GPREL = 0x00008000, - - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_PURGEABLE = 0x00010000, - - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_16BIT = 0x00020000, - - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_LOCKED = 0x00040000, - - /// - /// Reserved for future use. - /// - IMAGE_SCN_MEM_PRELOAD = 0x00080000, - - /// - /// Align data on a 1-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_1BYTES = 0x00100000, - - /// - /// Align data on a 2-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_2BYTES = 0x00200000, - - /// - /// Align data on a 4-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_4BYTES = 0x00300000, - - /// - /// Align data on a 8-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_8BYTES = 0x00400000, - - /// - /// Align data on a 16-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_16BYTES = 0x00500000, - - /// - /// Align data on a 32-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_32BYTES = 0x00600000, - - /// - /// Align data on a 64-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_64BYTES = 0x00700000, - - /// - /// Align data on a 128-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_128BYTES = 0x00800000, - - /// - /// Align data on a 256-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_256BYTES = 0x00900000, - - /// - /// Align data on a 512-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_512BYTES = 0x00A00000, - - /// - /// Align data on a 1024-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000, - - /// - /// Align data on a 2048-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000, - - /// - /// Align data on a 4096-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000, - - /// - /// Align data on a 8192-byte boundary. Valid only for object files. - /// - IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000, - - /// - /// The section contains extended relocations. - /// - IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, - - /// - /// The section can be discarded as needed. - /// - IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, - - /// - /// The section cannot be cached. - /// - IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, - - /// - /// The section is not pageable. - /// - IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, - - /// - /// The section can be shared in memory. - /// - IMAGE_SCN_MEM_SHARED = 0x10000000, - - /// - /// The section can be executed as code. - /// - IMAGE_SCN_MEM_EXECUTE = 0x20000000, - - /// - /// The section can be read. - /// - IMAGE_SCN_MEM_READ = 0x40000000, - - /// - /// The section can be written to. - /// - IMAGE_SCN_MEM_WRITE = 0x80000000, - } - - /// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm - [Flags] - public enum SegmentTableEntryFlags : ushort - { - /// - /// Segment-type field. - /// - TYPE = 0x0007, - - /// - /// Code-segment type. - /// - CODE = 0x0000, - - /// - /// Data-segment type. - /// - DATA = 0x0001, - - /// - /// Iterated segment flag - /// - ITER = 0x0008, - - /// - /// Segment is not fixed. - /// - MOVEABLE = 0x0010, - - /// - /// Shared segment flag - /// - SHARED = 0x0020, - - /// - /// For compatibility - /// - PURE = 0x0020, - - /// - /// Segment will be preloaded; read-only if this is a data segment. - /// - PRELOAD = 0x0040, - - /// - /// Execute-only (code segment), or read-only (data segment) - /// - EXRD = 0x0080, - - /// - /// Set if segment has relocation records. - /// - RELOCINFO = 0x0100, - - /// - /// Conforming segment - /// - CONFORM = 0x0200, - - /// - /// I/O privilege level (286 DPL bits) - /// - DPL = 0x0C00, - - /// - /// Left shift count for SEGDPL field - /// - SHIFTDPL = 10, - - /// - /// Discard priority. - /// - DISCARD = 0x1000, - - /// - /// 32-bit code segment - /// - NS32BIT = 0x2000, - - /// - /// Huge memory segment, length of segment and minimum allocation size are in segment sector units - /// - HUGE = 0x4000, - } - - [Flags] - public enum TargetOperatingSystems : byte - { - /// - /// Unknown (any "new-format" OS) - /// - NE_UNKNOWN = 0x0, - - /// - /// Microsoft/IBM OS/2 (default) - /// - NE_OS2 = 0x1, - - /// - /// Microsoft Windows - /// - NE_WINDOWS = 0x2, - - /// - /// Microsoft MS-DOS 4.x - /// - NE_DOS4 = 0x3, - - /// - /// Windows 386 - /// - NE_WIN386 = 0x4, - } - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#windows-subsystem - public enum WindowsSubsystem : ushort - { - /// - /// An unknown subsystem - /// - IMAGE_SUBSYSTEM_UNKNOWN = 0, - - /// - /// Device drivers and native Windows processes - /// - IMAGE_SUBSYSTEM_NATIVE = 1, - - /// - /// The Windows graphical user interface (GUI) subsystem - /// - IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, - - /// - /// The Windows character subsystem - /// - IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, - - /// - /// The OS/2 character subsystem - /// - IMAGE_SUBSYSTEM_OS2_CUI = 5, - - /// - /// The Posix character subsystem - /// - IMAGE_SUBSYSTEM_POSIX_CUI = 7, - - /// - /// Native Win9x driver - /// - IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, - - /// - /// Windows CE - /// - IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, - - /// - /// An Extensible Firmware Interface (EFI) application - /// - IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, - - /// - /// An EFI driver with boot services - /// - IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, - - /// - /// An EFI driver with run-time services - /// - IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, - - /// - /// An EFI ROM image - /// - IMAGE_SUBSYSTEM_EFI_ROM = 13, - - /// - /// XBOX - /// - IMAGE_SUBSYSTEM_XBOX = 14, - - /// - /// Windows boot application. - /// - IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16, - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/LE/LinearExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/LE/LinearExecutable.cs deleted file mode 100644 index 5f9fdb92..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/LE/LinearExecutable.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace BurnOutSharp.ExecutableType.Microsoft.LE -{ - /// - /// PLACEHOLDER LE/LX - /// - public class LinearExecutable - { - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/MZ/Headers/MSDOSExecutableHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/MZ/Headers/MSDOSExecutableHeader.cs deleted file mode 100644 index ea36a996..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/MZ/Headers/MSDOSExecutableHeader.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.MZ.Headers -{ - /// - /// The MS-DOS EXE format, also known as MZ after its signature (the initials of Microsoft engineer Mark Zbykowski), - /// was introduced with MS-DOS 2.0 (version 1.0 only sported the simple COM format). It is designed as a relocatable - /// executable running under real mode. As such, only DOS and Windows 9x can use this format natively, but there are - /// several free DOS emulators (e.g., DOSBox) that support it and that run under various operating systems (e.g., - /// Linux, Amiga, Windows NT, etc.). Although they can exist on their own, MZ executables are embedded in all NE, LE, - /// and PE executables, usually as stubs so that when they are ran under DOS, they display a warning. - /// - /// https://wiki.osdev.org/MZ - public class MSDOSExecutableHeader - { - #region Standard Fields - - /// - /// 0x5A4D (ASCII for 'M' and 'Z') [00] - /// - public ushort Magic; - - /// - /// Number of bytes in the last page. [02] - /// - public ushort LastPageBytes; - - /// - /// Number of whole/partial pages. [04] - /// - public ushort Pages; - - /// - /// Number of entries in the relocation table. [06] - /// - public ushort Relocations; - - /// - /// The number of paragraphs taken up by the header.It can be any value, as the loader - /// just uses it to find where the actual executable data starts. It may be larger than - /// what the "standard" fields take up, and you may use it if you want to include your - /// own header metadata, or put the relocation table there, or use it for any other purpose. [08] - /// - public ushort HeaderParagraphSize; - - /// - /// The number of paragraphs required by the program, excluding the PSP and program image. - /// If no free block is big enough, the loading stops. [0A] - /// - public ushort MinimumExtraParagraphs; - - /// - /// The number of paragraphs requested by the program. - /// If no free block is big enough, the biggest one possible is allocated. [0C] - /// - public ushort MaximumExtraParagraphs; - - /// - /// Relocatable segment address for SS. [0E] - /// - public ushort InitialSSValue; - - /// - /// Initial value for SP. [10] - /// - public ushort InitialSPValue; - - /// - /// When added to the sum of all other words in the file, the result should be zero. [12] - /// - public ushort Checksum; - - /// - /// Initial value for IP. [14] - /// - public ushort InitialIPValue; - - /// - /// Relocatable segment address for CS. [16] - /// - public ushort InitialCSValue; - - /// - /// The (absolute) offset to the relocation table. [18] - /// - public ushort RelocationTableAddr; - - /// - /// Value used for overlay management. - /// If zero, this is the main executable. [1A] - /// - public ushort OverlayNumber; - - #endregion - - #region PE Extensions - - /// - /// Reserved words [1C] - /// - public ushort[] Reserved1; - - /// - /// Defined by name but no other information is given; typically zeroes [24] - /// - public ushort OEMIdentifier; - - /// - /// Defined by name but no other information is given; typically zeroes [26] - /// - public ushort OEMInformation; - - /// - /// Reserved words [28] - /// - public ushort[] Reserved2; - - /// - /// Starting address of the PE header [3C] - /// - public int NewExeHeaderAddr; - - #endregion - - /// - /// All data after the last item in the header but before the new EXE header address - /// - public byte[] ExecutableData; - - public static MSDOSExecutableHeader Deserialize(Stream stream, bool asStub = true) - { - MSDOSExecutableHeader idh = new MSDOSExecutableHeader(); - - idh.Magic = stream.ReadUInt16(); - idh.LastPageBytes = stream.ReadUInt16(); - idh.Pages = stream.ReadUInt16(); - idh.Relocations = stream.ReadUInt16(); - idh.HeaderParagraphSize = stream.ReadUInt16(); - idh.MinimumExtraParagraphs = stream.ReadUInt16(); - idh.MaximumExtraParagraphs = stream.ReadUInt16(); - idh.InitialSSValue = stream.ReadUInt16(); - idh.InitialSPValue = stream.ReadUInt16(); - idh.Checksum = stream.ReadUInt16(); - idh.InitialIPValue = stream.ReadUInt16(); - idh.InitialCSValue = stream.ReadUInt16(); - idh.RelocationTableAddr = stream.ReadUInt16(); - idh.OverlayNumber = stream.ReadUInt16(); - - // If we're not reading as a stub, return now - if (!asStub) - return idh; - - idh.Reserved1 = new ushort[Constants.ERES1WDS]; - for (int i = 0; i < Constants.ERES1WDS; i++) - { - idh.Reserved1[i] = stream.ReadUInt16(); - } - - idh.OEMIdentifier = stream.ReadUInt16(); - idh.OEMInformation = stream.ReadUInt16(); - idh.Reserved2 = new ushort[Constants.ERES2WDS]; - for (int i = 0; i < Constants.ERES2WDS; i++) - { - idh.Reserved2[i] = stream.ReadUInt16(); - } - - idh.NewExeHeaderAddr = stream.ReadInt32(); - idh.ExecutableData = stream.ReadBytes(idh.NewExeHeaderAddr - (int)stream.Position); - - return idh; - } - - public static MSDOSExecutableHeader Deserialize(byte[] content, ref int offset, bool asStub = true) - { - MSDOSExecutableHeader idh = new MSDOSExecutableHeader(); - - idh.Magic = content.ReadUInt16(ref offset); - idh.LastPageBytes = content.ReadUInt16(ref offset); - idh.Pages = content.ReadUInt16(ref offset); - idh.Relocations = content.ReadUInt16(ref offset); - idh.HeaderParagraphSize = content.ReadUInt16(ref offset); - idh.MinimumExtraParagraphs = content.ReadUInt16(ref offset); - idh.MaximumExtraParagraphs = content.ReadUInt16(ref offset); - idh.InitialSSValue = content.ReadUInt16(ref offset); - idh.InitialSPValue = content.ReadUInt16(ref offset); - idh.Checksum = content.ReadUInt16(ref offset); - idh.InitialIPValue = content.ReadUInt16(ref offset); - idh.InitialCSValue = content.ReadUInt16(ref offset); - idh.RelocationTableAddr = content.ReadUInt16(ref offset); - idh.OverlayNumber = content.ReadUInt16(ref offset); - - // If we're not reading as a stub, return now - if (!asStub) - return idh; - - idh.Reserved1 = new ushort[Constants.ERES1WDS]; - for (int i = 0; i < Constants.ERES1WDS; i++) - { - idh.Reserved1[i] = content.ReadUInt16(ref offset); - } - - idh.OEMIdentifier = content.ReadUInt16(ref offset); - idh.OEMInformation = content.ReadUInt16(ref offset); - idh.Reserved2 = new ushort[Constants.ERES2WDS]; - for (int i = 0; i < Constants.ERES2WDS; i++) - { - idh.Reserved2[i] = content.ReadUInt16(ref offset); - } - - idh.NewExeHeaderAddr = content.ReadInt32(ref offset); - idh.ExecutableData = content.ReadBytes(ref offset, idh.NewExeHeaderAddr - offset); - - return idh; - } - } -} diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResidentNameTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResidentNameTableEntry.cs deleted file mode 100644 index 445cd485..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResidentNameTableEntry.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Entries -{ - /// - /// These name strings are case-sensitive and are not null-terminated - /// - public class ResidentNameTableEntry - { - /// - /// Length of the name string that follows. - /// A zero value indicates the end of the name table. - /// - public byte Length; - - /// - /// ASCII text of the name string. - /// - public byte[] Data; - - /// - /// Ordinal number (index into entry table). - /// This value is ignored for the module name. - /// - public ushort OrdinalNumber; - - /// - /// ASCII text of the name string - /// - public string DataAsString - { - get - { - if (Data == null) - return string.Empty; - - // Try to read direct as ASCII - try - { - return Encoding.ASCII.GetString(Data); - } - catch { } - - // If ASCII encoding fails, then just return an empty string - return string.Empty; - } - } - - public static ResidentNameTableEntry Deserialize(Stream stream) - { - var rnte = new ResidentNameTableEntry(); - - rnte.Length = stream.ReadByteValue(); - if (rnte.Length == 0) - return rnte; - - rnte.Data = stream.ReadBytes(rnte.Length); - rnte.OrdinalNumber = stream.ReadUInt16(); - - return rnte; - } - - public static ResidentNameTableEntry Deserialize(byte[] content, ref int offset) - { - var rnte = new ResidentNameTableEntry(); - - rnte.Length = content.ReadByte(ref offset); - if (rnte.Length == 0) - return rnte; - - rnte.Data = content.ReadBytes(ref offset, rnte.Length); - rnte.OrdinalNumber = content.ReadUInt16(ref offset); - - return rnte; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceNameString.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceNameString.cs deleted file mode 100644 index f6287791..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceNameString.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Entries -{ - /// - /// Resource type and name strings - /// - public class ResourceNameString - { - /// - /// Length of the type or name string that follows. A zero value - /// indicates the end of the resource type and name string, also - /// the end of the resource table. - /// - public byte Length; - - /// - /// ASCII text of the type or name string. - /// - public char[] Value; - - public static ResourceNameString Deserialize(Stream stream) - { - var rns = new ResourceNameString(); - - rns.Length = stream.ReadByteValue(); - rns.Value = stream.ReadChars(rns.Length, Encoding.ASCII); - - return rns; - } - - public static ResourceNameString Deserialize(byte[] content, ref int offset) - { - var rns = new ResourceNameString(); - - rns.Length = content.ReadByte(ref offset); - rns.Value = Encoding.ASCII.GetChars(content, offset, rns.Length); offset += rns.Length; - - return rns; - } - } -} diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTableEntry.cs deleted file mode 100644 index c99344e0..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTableEntry.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Entries -{ - /// - /// A table of resources for this type - /// - public class ResourceTableEntry - { - /// - /// File offset to the contents of the resource data, - /// relative to beginning of file. The offset is in terms - /// of the alignment shift count value specified at - /// beginning of the resource table. - /// - public ushort Offset; - - /// - /// Length of the resource in the file (in bytes). - /// - public ushort Length; - - /// - /// Resource flags - /// - public ResourceTableEntryFlags Flags; - - /// - /// This is an integer type if the high-order - /// bit is set (8000h), otherwise it is the offset to the - /// resource string, the offset is relative to the - /// beginning of the resource table. - /// - public ushort ResourceID; - - /// - /// Reserved. - /// - public ushort Handle; - - /// - /// Reserved. - /// - public ushort Usage; - - public static ResourceTableEntry Deserialize(Stream stream) - { - var ni = new ResourceTableEntry(); - - ni.Offset = stream.ReadUInt16(); - ni.Length = stream.ReadUInt16(); - ni.Flags = (ResourceTableEntryFlags)stream.ReadUInt16(); - ni.ResourceID = stream.ReadUInt16(); - ni.Handle = stream.ReadUInt16(); - ni.Usage = stream.ReadUInt16(); - - return ni; - } - - public static ResourceTableEntry Deserialize(byte[] content, ref int offset) - { - var ni = new ResourceTableEntry(); - - ni.Offset = content.ReadUInt16(ref offset); - ni.Length = content.ReadUInt16(ref offset); - ni.Flags = (ResourceTableEntryFlags)content.ReadUInt16(ref offset); - ni.ResourceID = content.ReadUInt16(ref offset); - ni.Handle = content.ReadUInt16(ref offset); - ni.Usage = content.ReadUInt16(ref offset); - - return ni; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTypeInformationBlock.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTypeInformationBlock.cs deleted file mode 100644 index 91d50a21..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/ResourceTypeInformationBlock.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Entries -{ - /// - /// Resource type information block - /// - public class ResourceTypeInformationBlock - { - /// - /// Type ID. This is an integer type if the high-order bit is - /// set (8000h); otherwise, it is an offset to the type string, - /// the offset is relative to the beginning of the resource - /// table. A zero type ID marks the end of the resource type - /// information blocks. - /// - public ushort TypeID; - - /// - /// Number of resources for this type. - /// - public ushort ResourceCount; - - /// - /// Reserved. - /// - public uint Reserved; - - /// - /// Reserved. - /// - public ResourceTableEntry[] ResourceTable; - - public static ResourceTypeInformationBlock Deserialize(Stream stream) - { - var rtib = new ResourceTypeInformationBlock(); - - rtib.TypeID = stream.ReadUInt16(); - rtib.ResourceCount = stream.ReadUInt16(); - rtib.Reserved = stream.ReadUInt32(); - - rtib.ResourceTable = new ResourceTableEntry[rtib.ResourceCount]; - for (int i = 0; i < rtib.ResourceCount; i++) - { - rtib.ResourceTable[i] = ResourceTableEntry.Deserialize(stream); - } - - return rtib; - } - - public static ResourceTypeInformationBlock Deserialize(byte[] content, ref int offset) - { - var rtib = new ResourceTypeInformationBlock(); - - rtib.TypeID = content.ReadUInt16(ref offset); - rtib.ResourceCount = content.ReadUInt16(ref offset); - rtib.Reserved = content.ReadUInt32(ref offset); - - rtib.ResourceTable = new ResourceTableEntry[rtib.ResourceCount]; - for (int i = 0; i < rtib.ResourceCount; i++) - { - rtib.ResourceTable[i] = ResourceTableEntry.Deserialize(content, ref offset); - } - - return rtib; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/SegmentTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/SegmentTableEntry.cs deleted file mode 100644 index 544932bc..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Entries/SegmentTableEntry.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Entries -{ - /// - /// The segment table contains an entry for each segment in the executable - /// file. The number of segment table entries are defined in the segmented - /// EXE header. The first entry in the segment table is segment number 1. - /// The following is the structure of a segment table entry. - /// - public class SegmentTableEntry - { - /// - /// Logical-sector offset (n byte) to the contents of the segment - /// data, relative to the beginning of the file. Zero means no - /// file data. - /// - public ushort StartFileSector; - - /// - /// Length of the segment in the file, in bytes. Zero means 64K. - /// - public ushort BytesInFile; - - /// - /// Attribute flags - /// - public SegmentTableEntryFlags Flags; - - /// - /// Minimum allocation size of the segment, in bytes. - /// Total size of the segment. Zero means 64K - /// - public ushort MinimumAllocation; - - public static SegmentTableEntry Deserialize(Stream stream) - { - var nste = new SegmentTableEntry(); - - nste.StartFileSector = stream.ReadUInt16(); - nste.BytesInFile = stream.ReadUInt16(); - nste.Flags = (SegmentTableEntryFlags)stream.ReadUInt16(); - nste.MinimumAllocation = stream.ReadUInt16(); - - return nste; - } - - public static SegmentTableEntry Deserialize(byte[] content, ref int offset) - { - var nste = new SegmentTableEntry(); - - nste.StartFileSector = content.ReadUInt16(ref offset); - nste.BytesInFile = content.ReadUInt16(ref offset); - nste.Flags = (SegmentTableEntryFlags)content.ReadUInt16(ref offset); - nste.MinimumAllocation = content.ReadUInt16(ref offset); - - return nste; - } - } -} diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Headers/NewExecutableHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Headers/NewExecutableHeader.cs deleted file mode 100644 index e5c97aeb..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Headers/NewExecutableHeader.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Headers -{ - /// - /// The NE header is a relatively large structure with multiple characteristics. - /// Because of the age of the format some items are unclear in meaning. - /// - /// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm - public class NewExecutableHeader - { - /// - /// Signature word. [00] - /// "N" is low-order byte. - /// "E" is high-order byte. - /// - public ushort Magic; - - /// - /// Version number of the linker. [02] - /// - public byte LinkerVersion; - - /// - /// Revision number of the linker. [03] - /// - public byte LinkerRevision; - - /// - /// Entry Table file offset, relative to the beginning of the segmented EXE header. [04] - /// - public ushort EntryTableOffset; - - /// - /// Number of bytes in the entry table. [06] - /// - public ushort EntryTableSize; - - /// - /// 32-bit CRC of entire contents of file. [08] - /// These words are taken as 00 during the calculation. - /// - public uint CrcChecksum; - - /// - /// Program flags, bitmapped [0C] - /// - public byte ProgramFlags; - - /// - /// Application flags, bitmapped [0D] - /// - public byte ApplicationFlags; - - /// - /// Automatic data segment number [0E] - /// - public ushort Autodata; - - /// - /// Initial heap allocation [10] - /// - public ushort InitialHeapAlloc; - - /// - /// Initial stack allocation [12] - /// - public ushort InitialStackAlloc; - - /// - /// CS:IP entry point, CS is index into segment table [14] - /// - public uint InitialCSIPSetting; - - /// - /// SS:SP inital stack pointer, SS is index into segment table [18] - /// - public uint InitialSSSPSetting; - - /// - /// Number of segments in segment table [1C] - /// - public ushort FileSegmentCount; - - /// - /// Entries in Module Reference Table [1E] - /// - public ushort ModuleReferenceTableSize; - - /// - /// Size of non-resident name table [20] - /// - public ushort NonResidentNameTableSize; - - /// - /// Offset of Segment Table [22] - /// - public ushort SegmentTableOffset; - - /// - /// Offset of Resource Table [24] - /// - public ushort ResourceTableOffset; - - /// - /// Offset of resident name table [26] - /// - public ushort ResidentNameTableOffset; - - /// - /// Offset of Module Reference Table [28] - /// - public ushort ModuleReferenceTableOffset; - - /// - /// Offset of Imported Names Table [2A] - /// - public ushort ImportedNamesTableOffset; - - /// - /// Offset of Non-resident Names Table [2C] - /// - public uint NonResidentNamesTableOffset; - - /// - /// Count of moveable entry points listed in entry table [30] - /// - public ushort MovableEntriesCount; - - /// - /// File allignment size shift count (0-9 (default 512 byte pages)) [32] - /// - public ushort SegmentAlignmentShiftCount; - - /// - /// Count of resource table entries [34] - /// - public ushort ResourceEntriesCount; - - /// - /// Target operating system [36] - /// - public byte TargetOperatingSystem; - - /// - /// Other OS/2 flags [37] - /// - public byte AdditionalFlags; - - /// - /// Offset to return thunks or start of gangload area [38] - /// - public ushort ReturnThunkOffset; - - /// - /// Offset to segment reference thunks or size of gangload area [3A] - /// - public ushort SegmentReferenceThunkOffset; - - /// - /// Minimum code swap area size [3C] - /// - public ushort MinCodeSwapAreaSize; - - /// - /// Windows SDK revison number [3E] - /// - public byte WindowsSDKRevision; - - /// - /// Windows SDK version number [3F] - /// - public byte WindowsSDKVersion; - - public static NewExecutableHeader Deserialize(Stream stream) - { - var neh = new NewExecutableHeader(); - - neh.Magic = stream.ReadUInt16(); - neh.LinkerVersion = stream.ReadByteValue(); - neh.LinkerRevision = stream.ReadByteValue(); - neh.EntryTableOffset = stream.ReadUInt16(); - neh.EntryTableSize = stream.ReadUInt16(); - neh.CrcChecksum = stream.ReadUInt32(); - neh.ProgramFlags = stream.ReadByteValue(); - neh.ApplicationFlags = stream.ReadByteValue(); - neh.Autodata = stream.ReadUInt16(); - neh.InitialHeapAlloc = stream.ReadUInt16(); - neh.InitialStackAlloc = stream.ReadUInt16(); - neh.InitialCSIPSetting = stream.ReadUInt32(); - neh.InitialSSSPSetting = stream.ReadUInt32(); - neh.FileSegmentCount = stream.ReadUInt16(); - neh.ModuleReferenceTableSize = stream.ReadUInt16(); - neh.NonResidentNameTableSize = stream.ReadUInt16(); - neh.SegmentTableOffset = stream.ReadUInt16(); - neh.ResourceTableOffset = stream.ReadUInt16(); - neh.ResidentNameTableOffset = stream.ReadUInt16(); - neh.ModuleReferenceTableOffset = stream.ReadUInt16(); - neh.ImportedNamesTableOffset = stream.ReadUInt16(); - neh.NonResidentNamesTableOffset = stream.ReadUInt32(); - neh.MovableEntriesCount = stream.ReadUInt16(); - neh.SegmentAlignmentShiftCount = stream.ReadUInt16(); - neh.ResourceEntriesCount = stream.ReadUInt16(); - neh.TargetOperatingSystem = stream.ReadByteValue(); - neh.AdditionalFlags = stream.ReadByteValue(); - neh.ReturnThunkOffset = stream.ReadUInt16(); - neh.SegmentReferenceThunkOffset = stream.ReadUInt16(); - neh.MinCodeSwapAreaSize = stream.ReadUInt16(); - neh.WindowsSDKRevision = stream.ReadByteValue(); - neh.WindowsSDKVersion = stream.ReadByteValue(); - - return neh; - } - - public static NewExecutableHeader Deserialize(byte[] content, ref int offset) - { - var neh = new NewExecutableHeader(); - - neh.Magic = content.ReadUInt16(ref offset); - neh.LinkerVersion = content.ReadByte(ref offset); - neh.LinkerRevision = content.ReadByte(ref offset); - neh.EntryTableOffset = content.ReadUInt16(ref offset); - neh.EntryTableSize = content.ReadUInt16(ref offset); - neh.CrcChecksum = content.ReadUInt32(ref offset); - neh.ProgramFlags = content.ReadByte(ref offset); - neh.ApplicationFlags = content.ReadByte(ref offset); - neh.Autodata = content.ReadUInt16(ref offset); - neh.InitialHeapAlloc = content.ReadUInt16(ref offset); - neh.InitialStackAlloc = content.ReadUInt16(ref offset); - neh.InitialCSIPSetting = content.ReadUInt32(ref offset); - neh.InitialSSSPSetting = content.ReadUInt32(ref offset); - neh.FileSegmentCount = content.ReadUInt16(ref offset); - neh.ModuleReferenceTableSize = content.ReadUInt16(ref offset); - neh.NonResidentNameTableSize = content.ReadUInt16(ref offset); - neh.SegmentTableOffset = content.ReadUInt16(ref offset); - neh.ResourceTableOffset = content.ReadUInt16(ref offset); - neh.ResidentNameTableOffset = content.ReadUInt16(ref offset); - neh.ModuleReferenceTableOffset = content.ReadUInt16(ref offset); - neh.ImportedNamesTableOffset = content.ReadUInt16(ref offset); - neh.NonResidentNamesTableOffset = content.ReadUInt32(ref offset); - neh.MovableEntriesCount = content.ReadUInt16(ref offset); - neh.SegmentAlignmentShiftCount = content.ReadUInt16(ref offset); - neh.ResourceEntriesCount = content.ReadUInt16(ref offset); - neh.TargetOperatingSystem = content.ReadByte(ref offset); - neh.AdditionalFlags = content.ReadByte(ref offset); - neh.ReturnThunkOffset = content.ReadUInt16(ref offset); - neh.SegmentReferenceThunkOffset = content.ReadUInt16(ref offset); - neh.MinCodeSwapAreaSize = content.ReadUInt16(ref offset); - neh.WindowsSDKRevision = content.ReadByte(ref offset); - neh.WindowsSDKVersion = content.ReadByte(ref offset); - - return neh; - } - } -} diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs deleted file mode 100644 index 52ad2b36..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.MZ.Headers; -using BurnOutSharp.ExecutableType.Microsoft.NE.Headers; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE -{ - /// - /// The WIN-NE executable format, designed for Windows 3.x, was the "NE", or "New Executable" format. - /// Again, a 16bit format, it alleviated the maximum size restrictions that the MZ format had. - /// - public class NewExecutable - { - /// - /// Value determining if the executable is initialized or not - /// - public bool Initialized { get; } = false; - - /// - /// Source array that the executable was parsed from - /// - private readonly byte[] _sourceArray = null; - - /// - /// Source stream that the executable was parsed from - /// - private readonly Stream _sourceStream = null; - - #region Headers - - /// - /// he DOS stub is a valid MZ exe. - /// This enables the develper to package both an MS-DOS and Win16 version of the program, - /// but normally just prints "This Program requires Microsoft Windows". - /// The e_lfanew field (offset 0x3C) points to the NE header. - // - public MSDOSExecutableHeader DOSStubHeader; - - /// - /// The NE header is a relatively large structure with multiple characteristics. - /// Because of the age of the format some items are unclear in meaning. - /// - public NewExecutableHeader NewExecutableHeader; - - #endregion - - #region Tables - - #endregion - - #region Constructors - - // TODO: Add more and more parts of a standard NE executable, not just the header - // TODO: Tables? What about the tables? - // TODO: Implement the rest of the structures found at http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm - // (Left off at RESIDENT-NAME TABLE) - - /// - /// Create a NewExecutable object from a stream - /// - /// Stream representing a file - /// - /// This constructor assumes that the stream is already in the correct position to start parsing - /// - public NewExecutable(Stream stream) - { - if (stream == null || !stream.CanRead || !stream.CanSeek) - return; - - this.Initialized = Deserialize(stream); - this._sourceStream = stream; - } - - /// - /// Create a NewExecutable object from a byte array - /// - /// Byte array representing a file - /// Positive offset representing the current position in the array - public NewExecutable(byte[] fileContent, int offset) - { - if (fileContent == null || fileContent.Length == 0 || offset < 0) - return; - - this.Initialized = Deserialize(fileContent, offset); - this._sourceArray = fileContent; - } - - /// - /// Deserialize a NewExecutable object from a stream - /// - /// Stream representing a file - private bool Deserialize(Stream stream) - { - try - { - // Attempt to read the DOS header first - this.DOSStubHeader = MSDOSExecutableHeader.Deserialize(stream); - stream.Seek(this.DOSStubHeader.NewExeHeaderAddr, SeekOrigin.Begin); - if (this.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE) - return false; - - // If the new header address is invalid for the file, it's not a NE - if (this.DOSStubHeader.NewExeHeaderAddr >= stream.Length) - return false; - - // Then attempt to read the NE header - this.NewExecutableHeader = NewExecutableHeader.Deserialize(stream); - if (this.NewExecutableHeader.Magic != Constants.IMAGE_OS2_SIGNATURE) - return false; - - } - catch (Exception ex) - { - //Console.WriteLine($"Errored out on a file: {ex}"); - return false; - } - - return true; - } - - /// - /// Deserialize a NewExecutable object from a byte array - /// - /// Byte array representing a file - /// Positive offset representing the current position in the array - private bool Deserialize(byte[] content, int offset) - { - try - { - // Attempt to read the DOS header first - this.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, ref offset); - offset = this.DOSStubHeader.NewExeHeaderAddr; - if (this.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE) - return false; - - // If the new header address is invalid for the file, it's not a PE - if (this.DOSStubHeader.NewExeHeaderAddr >= content.Length) - return false; - - // Then attempt to read the NE header - this.NewExecutableHeader = NewExecutableHeader.Deserialize(content, ref offset); - if (this.NewExecutableHeader.Magic != Constants.IMAGE_OS2_SIGNATURE) - return false; - } - catch (Exception ex) - { - //Console.WriteLine($"Errored out on a file: {ex}"); - return false; - } - - return true; - } - - #endregion - - #region Helpers - - /// - /// 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 - /// - public byte[] ReadArbitraryRange(int rangeStart = -1, int length = -1) - { - try - { - // If we have a source stream, use that - if (this._sourceStream != null) - return ReadArbitraryRangeFromSourceStream(rangeStart, length); - - // If we have a source array, use that - if (this._sourceArray != null) - return ReadArbitraryRangeFromSourceArray(rangeStart, length); - - // Otherwise, return null - return null; - } - catch (Exception ex) - { - // TODO: How to handle this differently? - return null; - } - } - - /// - /// Read an arbitrary range from the stream source, if possible - /// - /// The start of where to read data from, -1 means start of source - /// How many bytes to read, -1 means read until end - /// - private byte[] ReadArbitraryRangeFromSourceStream(int rangeStart, int length) - { - lock (this._sourceStream) - { - int startingIndex = (int)Math.Max(rangeStart, 0); - int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this._sourceStream.Length); - - long originalPosition = this._sourceStream.Position; - this._sourceStream.Seek(startingIndex, SeekOrigin.Begin); - byte[] sectionData = this._sourceStream.ReadBytes(readLength); - this._sourceStream.Seek(originalPosition, SeekOrigin.Begin); - return sectionData; - } - } - - /// - /// Read an arbitrary range from the array source, if possible - /// - /// The start of where to read data from, -1 means start of source - /// How many bytes to read, -1 means read until end - /// - private byte[] ReadArbitraryRangeFromSourceArray(int rangeStart, int length) - { - int startingIndex = (int)Math.Max(rangeStart, 0); - int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this._sourceArray.Length); - - try - { - return this._sourceArray.ReadBytes(ref startingIndex, readLength); - } - catch - { - // Just absorb errors for now - // TODO: Investigate why and when this would be hit - return null; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResidentNameTable.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResidentNameTable.cs deleted file mode 100644 index cd35384a..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResidentNameTable.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.NE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Tables -{ - /// - /// The resident-name table follows the resource table, and contains this - /// module's name string and resident exported procedure name strings. The - /// first string in this table is this module's name. These name strings - /// are case-sensitive and are not null-terminated. - /// - public class ResidentNameTable - { - /// - /// The first string in this table is this module's name. - /// These name strings are case-sensitive and are not null-terminated. - /// - public ResidentNameTableEntry[] NameTableEntries; - - public static ResidentNameTable Deserialize(Stream stream) - { - var rnt = new ResidentNameTable(); - - var nameTableEntries = new List(); - while (true) - { - var rnte = ResidentNameTableEntry.Deserialize(stream); - if (rnte == null || rnte.Length == 0) - break; - - nameTableEntries.Add(rnte); - } - - rnt.NameTableEntries = nameTableEntries.ToArray(); - - return rnt; - } - - public static ResidentNameTable Deserialize(byte[] content, ref int offset) - { - var rnt = new ResidentNameTable(); - - var nameTableEntries = new List(); - while (true) - { - var rnte = ResidentNameTableEntry.Deserialize(content, ref offset); - if (rnte == null || rnte.Length == 0) - break; - - nameTableEntries.Add(rnte); - } - - rnt.NameTableEntries = nameTableEntries.ToArray(); - - return rnt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResourceTable.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResourceTable.cs deleted file mode 100644 index 20997fac..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/Tables/ResourceTable.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.NE.Entries; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.NE.Tables -{ - /// - /// The resource table follows the segment table and contains entries for - /// each resource in the executable file. The resource table consists of - /// an alignment shift count, followed by a table of resource records. The - /// resource records define the type ID for a set of resources. Each - /// resource record contains a table of resource entries of the defined - /// type. The resource entry defines the resource ID or name ID for the - /// resource. It also defines the location and size of the resource. - /// - /// http://bytepointer.com/resources/win16_ne_exe_format_win3.0.htm - public class ResourceTable - { - /// - /// Alignment shift count for resource data. - /// - public ushort AlignmentShiftCount; - - /// - /// A table of resource type information blocks. - /// - public ResourceTypeInformationBlock[] TypeInformationBlocks; - - /// - /// Resource type and name strings are stored at the end of the - /// resource table. Note that these strings are NOT null terminated and - /// are case sensitive. - /// - public ResourceNameString[] TypeAndNameStrings; - - public static ResourceTable Deserialize(Stream stream) - { - var rt = new ResourceTable(); - - rt.AlignmentShiftCount = stream.ReadUInt16(); - var typeInformationBlocks = new List(); - while (true) - { - var block = ResourceTypeInformationBlock.Deserialize(stream); - if (block.TypeID == 0) - break; - - typeInformationBlocks.Add(block); - } - - rt.TypeInformationBlocks = typeInformationBlocks.ToArray(); - - var typeAndNameStrings = new List(); - while (true) - { - var str = ResourceNameString.Deserialize(stream); - if (str.Length == 0) - break; - - typeAndNameStrings.Add(str); - } - - rt.TypeAndNameStrings = typeAndNameStrings.ToArray(); - - return rt; - } - - public static ResourceTable Deserialize(byte[] content, ref int offset) - { - var rt = new ResourceTable(); - - rt.AlignmentShiftCount = content.ReadUInt16(ref offset); - var typeInformationBlocks = new List(); - while (true) - { - var block = ResourceTypeInformationBlock.Deserialize(content, ref offset); - if (block.TypeID == 0) - break; - - typeInformationBlocks.Add(block); - } - - rt.TypeInformationBlocks = typeInformationBlocks.ToArray(); - - var typeAndNameStrings = new List(); - while (true) - { - var str = ResourceNameString.Deserialize(content, ref offset); - if (str.Length == 0) - break; - - typeAndNameStrings.Add(str); - } - - rt.TypeAndNameStrings = typeAndNameStrings.ToArray(); - - return rt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs deleted file mode 100644 index fea04df5..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// The base relocation table is divided into blocks. - /// Each block represents the base relocations for a 4K page. - /// Each block must start on a 32-bit boundary. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-block - public class BaseRelocationBlock - { - /// - /// The image base plus the page RVA is added to each offset to create the VA where the base relocation must be applied. - /// - public uint PageRVA; - - /// - /// The total number of bytes in the base relocation block, including the Page RVA and Block Size fields and the Type/Offset fields that follow. - /// - public uint BlockSize; - - public static BaseRelocationBlock Deserialize(Stream stream) - { - var brb = new BaseRelocationBlock(); - - brb.PageRVA = stream.ReadUInt32(); - brb.BlockSize = stream.ReadUInt32(); - - // TODO: Read in the type/offset field entries - - return brb; - } - - public static BaseRelocationBlock Deserialize(byte[] content, ref int offset) - { - var brb = new BaseRelocationBlock(); - - brb.PageRVA = content.ReadUInt32(ref offset); - brb.BlockSize = content.ReadUInt32(ref offset); - - // TODO: Read in the type/offset field entries - - return brb; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ExportAddressTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ExportAddressTableEntry.cs deleted file mode 100644 index 21c7b99f..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ExportAddressTableEntry.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each entry in the export address table is a field that uses one of two formats in the following table. - /// If the address specified is not within the export section (as defined by the address and length that are indicated in the optional header), the field is an export RVA, which is an actual address in code or data. - /// Otherwise, the field is a forwarder RVA, which names a symbol in another DLL. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#export-address-table - public class ExportAddressTableEntry - { - /// - /// The address of the exported symbol when loaded into memory, relative to the image base. - /// For example, the address of an exported function. - /// - public uint ExportRVA; - - /// - /// The pointer to a null-terminated ASCII string in the export section. - /// This string must be within the range that is given by the export table data directory entry. - /// This string gives the DLL name and the name of the export (for example, "MYDLL.expfunc") or the DLL name and the ordinal number of the export (for example, "MYDLL.#27"). - /// - public uint ForwarderRVA; // TODO: Read this into a separate field - - /// - /// A null-terminated ASCII string in the export section. - /// This string must be within the range that is given by the export table data directory entry. - /// This string gives the DLL name and the name of the export (for example, "MYDLL.expfunc") or the DLL name and the ordinal number of the export (for example, "MYDLL.#27"). - /// - public string Forwarder; - - public static ExportAddressTableEntry Deserialize(Stream stream, SectionHeader[] sections) - { - var eate = new ExportAddressTableEntry(); - - eate.ExportRVA = stream.ReadUInt32(); - eate.ForwarderRVA = eate.ExportRVA; - - int forwarderAddress = (int)PortableExecutable.ConvertVirtualAddress(eate.ForwarderRVA, sections); - if (forwarderAddress > -1 && forwarderAddress < stream.Length) - { - long originalPosition = stream.Position; - stream.Seek(forwarderAddress, SeekOrigin.Begin); - eate.Forwarder = stream.ReadString(Encoding.ASCII); - stream.Seek(originalPosition, SeekOrigin.Begin); - } - - return eate; - } - - public static ExportAddressTableEntry Deserialize(byte[] content, ref int offset, SectionHeader[] sections) - { - var eate = new ExportAddressTableEntry(); - - eate.ExportRVA = content.ReadUInt32(ref offset); - eate.ForwarderRVA = eate.ExportRVA; - - int forwarderAddress = (int)PortableExecutable.ConvertVirtualAddress(eate.ForwarderRVA, sections); - if (forwarderAddress > -1 && forwarderAddress < content.Length) - eate.Forwarder = content.ReadString(ref forwarderAddress, Encoding.ASCII); - - return eate; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/FunctionTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/FunctionTableEntry.cs deleted file mode 100644 index bf7b0892..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/FunctionTableEntry.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each entry in the export address table is a field that uses one of two formats in the following table. - /// If the address specified is not within the export section (as defined by the address and length that are indicated in the optional header), the field is an export RVA, which is an actual address in code or data. - /// Otherwise, the field is a forwarder RVA, which names a symbol in another DLL. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-pdata-section - public class FunctionTableEntry - { - #region 32-bit MIPS - - /// - /// The VA of the corresponding function. - /// - public uint MIPSBeginAddress; - - /// - /// The VA of the end of the function. - /// - public uint MIPSEndAddress; - - /// - /// The pointer to the exception handler to be executed. - /// - public uint MIPSExceptionHandler; - - /// - /// The pointer to additional information to be passed to the handler. - /// - public uint MIPSHandlerData; - - /// - /// The VA of the end of the function's prolog. - /// - public uint MIPSPrologEndAddress; - - #endregion - - #region ARM, PowerPC, SH3 and SH4 Windows CE - - /// - /// The VA of the corresponding function. - /// - public uint ARMBeginAddress; - - /// - /// The VA of the end of the function. - /// - /// 8 bits Prolog Length The number of instructions in the function's prolog. - /// 22 bits Function Length The number of instructions in the function. - /// 1 bit 32-bit Flag If set, the function consists of 32-bit instructions. If clear, the function consists of 16-bit instructions. - /// 1 bit Exception Flag If set, an exception handler exists for the function. Otherwise, no exception handler exists. - /// - public uint ARMLengthsAndFlags; - - #endregion - - #region x64 and Itanium - - /// - /// The RVA of the corresponding function. - /// - public uint X64BeginAddress; - - /// - /// The RVA of the end of the function. - /// - public uint X64EndAddress; - - /// - /// The RVA of the unwind information. - /// - public uint X64UnwindInformation; - - #endregion - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/HintNameTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/HintNameTableEntry.cs deleted file mode 100644 index 93fd9211..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/HintNameTableEntry.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each entry in the hint/name table has the following format - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#hintname-table - public class HintNameTableEntry - { - /// - /// An index into the export name pointer table. - /// A match is attempted first with this value. - /// If it fails, a binary search is performed on the DLL's export name pointer table. - /// - public ushort Hint; - - /// - /// An ASCII string that contains the name to import. - /// This is the string that must be matched to the public name in the DLL. - /// This string is case sensitive and terminated by a null byte. - /// - public string Name; - - /// - /// A trailing zero-pad byte that appears after the trailing null byte, if necessary, to align the next entry on an even boundary. - /// - public byte Pad; - - public static HintNameTableEntry Deserialize(Stream stream) - { - var hnte = new HintNameTableEntry(); - - hnte.Hint = stream.ReadUInt16(); - hnte.Name = string.Empty; - while (true) - { - char c = stream.ReadChar(); - if (c == (char)0x00) - break; - - hnte.Name += c; - } - - // If the name length is not even, read and pad - if (hnte.Name.Length % 2 != 0) - { - stream.ReadByte(); - hnte.Pad = 1; - } - else - { - hnte.Pad = 0; - } - - return hnte; - } - - public static HintNameTableEntry Deserialize(byte[] content, ref int offset) - { - var hnte = new HintNameTableEntry(); - - hnte.Hint = content.ReadUInt16(ref offset); - hnte.Name = string.Empty; - while (true) - { - char c = (char)content[offset]; offset += 1; - if (c == (char)0x00) - break; - - hnte.Name += c; - } - - // If the name length is not even, read and pad - if (hnte.Name.Length % 2 != 0) - { - offset += 1; - hnte.Pad = 1; - } - else - { - hnte.Pad = 0; - } - - return hnte; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportAddressTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportAddressTableEntry.cs deleted file mode 100644 index e66f007d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportAddressTableEntry.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each import address entry has the following format - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table - public class ImportAddressTableEntry - { - /// - /// The RVA of the import lookup table. - /// This table contains a name or ordinal for each import. - /// (The name "Characteristics" is used in Winnt.h, but no longer describes this field.) - /// - public uint ImportLookupTableRVA; - - /// - /// The stamp that is set to zero until the image is bound. - /// After the image is bound, this field is set to the time/data stamp of the DLL. - /// - public uint TimeDateStamp; - - /// - /// The index of the first forwarder reference. - /// - public uint ForwarderChain; - - /// - /// The address of an ASCII string that contains the name of the DLL. - /// This address is relative to the image base. - /// - public uint NameRVA; - - /// - /// The RVA of the import address table. - /// The contents of this table are identical to the contents of the import lookup table until the image is bound. - /// - public uint ImportAddressTableRVA; - - /// - /// Determine if the entry is null or not - /// This indicates the last entry in a table - /// - public bool IsNull() - { - return ImportLookupTableRVA == 0 - && TimeDateStamp == 0 - && ForwarderChain == 0 - && NameRVA == 0 - && ImportAddressTableRVA == 0; - } - - public static ImportAddressTableEntry Deserialize(Stream stream) - { - var iate = new ImportAddressTableEntry(); - - iate.ImportLookupTableRVA = stream.ReadUInt32(); - iate.TimeDateStamp = stream.ReadUInt32(); - iate.ForwarderChain = stream.ReadUInt32(); - iate.NameRVA = stream.ReadUInt32(); - iate.ImportAddressTableRVA = stream.ReadUInt32(); - - return iate; - } - - public static ImportAddressTableEntry Deserialize(byte[] content, ref int offset) - { - var iate = new ImportAddressTableEntry(); - - iate.ImportLookupTableRVA = content.ReadUInt32(ref offset); - iate.TimeDateStamp = content.ReadUInt32(ref offset); - iate.ForwarderChain = content.ReadUInt32(ref offset); - iate.NameRVA = content.ReadUInt32(ref offset); - iate.ImportAddressTableRVA = content.ReadUInt32(ref offset); - - return iate; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportDirectoryTableEntry.cs deleted file mode 100644 index 43db684d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ImportDirectoryTableEntry.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each import directory entry has the following format - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-directory-table - public class ImportDirectoryTableEntry - { - /// - /// The RVA of the import lookup table. - /// This table contains a name or ordinal for each import. - /// (The name "Characteristics" is used in Winnt.h, but no longer describes this field.) - /// - public uint ImportLookupTableRVA; - - /// - /// The stamp that is set to zero until the image is bound. - /// After the image is bound, this field is set to the time/data stamp of the DLL. - /// - public uint TimeDateStamp; - - /// - /// The index of the first forwarder reference. - /// - public uint ForwarderChain; - - /// - /// The address of an ASCII string that contains the name of the DLL. - /// This address is relative to the image base. - /// - public uint NameRVA; - - /// - /// The RVA of the import address table. - /// The contents of this table are identical to the contents of the import lookup table until the image is bound. - /// - public uint ImportAddressTableRVA; - - /// - /// Determine if the entry is null or not - /// This indicates the last entry in a table - /// - public bool IsNull() - { - return ImportLookupTableRVA == 0 - && TimeDateStamp == 0 - && ForwarderChain == 0 - && NameRVA == 0 - && ImportAddressTableRVA == 0; - } - - public static ImportDirectoryTableEntry Deserialize(Stream stream) - { - var idte = new ImportDirectoryTableEntry(); - - idte.ImportLookupTableRVA = stream.ReadUInt32(); - idte.TimeDateStamp = stream.ReadUInt32(); - idte.ForwarderChain = stream.ReadUInt32(); - idte.NameRVA = stream.ReadUInt32(); - idte.ImportAddressTableRVA = stream.ReadUInt32(); - - return idte; - } - - public static ImportDirectoryTableEntry Deserialize(byte[] content, ref int offset) - { - var idte = new ImportDirectoryTableEntry(); - - idte.ImportLookupTableRVA = content.ReadUInt32(ref offset); - idte.TimeDateStamp = content.ReadUInt32(ref offset); - idte.ForwarderChain = content.ReadUInt32(ref offset); - idte.NameRVA = content.ReadUInt32(ref offset); - idte.ImportAddressTableRVA = content.ReadUInt32(ref offset); - - return idte; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDataEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDataEntry.cs deleted file mode 100644 index 82f863e0..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDataEntry.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// Each Resource Data entry describes an actual unit of raw data in the Resource Data area. - /// - public class ResourceDataEntry - { - /// - /// The address of a unit of resource data in the Resource Data area. - /// - public uint OffsetToData; - - /// - /// A unit of resource data in the Resource Data area. - /// - public byte[] Data; - - /// - /// A unit of resource data in the Resource Data area. - /// - public string DataAsUTF8String - { - get - { - int codePage = (int)CodePage; - if (Data == null || codePage < 0) - return string.Empty; - - // Try to convert to UTF-8 first - try - { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - var originalEncoding = Encoding.GetEncoding(codePage); - byte[] convertedData = Encoding.Convert(originalEncoding, Encoding.UTF8, Data); - return Encoding.UTF8.GetString(convertedData); - } - catch { } - - // Then try to read direct as ASCII - try - { - return Encoding.ASCII.GetString(Data); - } - catch { } - - // If both encodings fail, then just return an empty string - return string.Empty; - } - } - - /// - /// The size, in bytes, of the resource data that is pointed to by the Data RVA field. - /// - public uint Size; - - /// - /// The code page that is used to decode code point values within the resource data. - /// Typically, the code page would be the Unicode code page. - /// - public uint CodePage; - - /// - /// Reserved, must be 0. - /// - public uint Reserved; - - public static ResourceDataEntry Deserialize(Stream stream, SectionHeader[] sections) - { - var rde = new ResourceDataEntry(); - - rde.OffsetToData = stream.ReadUInt32(); - rde.Size = stream.ReadUInt32(); - rde.CodePage = stream.ReadUInt32(); - rde.Reserved = stream.ReadUInt32(); - - int realOffsetToData = (int)PortableExecutable.ConvertVirtualAddress(rde.OffsetToData, sections); - if (realOffsetToData > -1 && realOffsetToData < stream.Length && (int)rde.Size > 0 && realOffsetToData + (int)rde.Size < stream.Length) - { - long lastPosition = stream.Position; - stream.Seek(realOffsetToData, SeekOrigin.Begin); - rde.Data = stream.ReadBytes((int)rde.Size); - stream.Seek(lastPosition, SeekOrigin.Begin); - } - - return rde; - } - - public static ResourceDataEntry Deserialize(byte[] content, ref int offset, SectionHeader[] sections) - { - var rde = new ResourceDataEntry(); - - rde.OffsetToData = content.ReadUInt32(ref offset); - rde.Size = content.ReadUInt32(ref offset); - rde.CodePage = content.ReadUInt32(ref offset); - rde.Reserved = content.ReadUInt32(ref offset); - - int realOffsetToData = (int)PortableExecutable.ConvertVirtualAddress(rde.OffsetToData, sections); - if (realOffsetToData > -1 && realOffsetToData < content.Length && (int)rde.Size > 0 && realOffsetToData + (int)rde.Size < content.Length) - rde.Data = new ArraySegment(content, realOffsetToData, (int)rde.Size).ToArray(); - - return rde; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryString.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryString.cs deleted file mode 100644 index f47f506f..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryString.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// The resource directory string area consists of Unicode strings, which are word-aligned. - /// These strings are stored together after the last Resource Directory entry and before the first Resource Data entry. - /// This minimizes the impact of these variable-length strings on the alignment of the fixed-size directory entries. - /// - public class ResourceDirectoryString - { - /// - /// The size of the string, not including length field itself. - /// - public ushort Length; - - /// - /// The variable-length Unicode string data, word-aligned. - /// - public string UnicodeString; - - public static ResourceDirectoryString Deserialize(Stream stream) - { - var rds = new ResourceDirectoryString(); - - rds.Length = stream.ReadUInt16(); - if (rds.Length + stream.Position > stream.Length) - return null; - - rds.UnicodeString = new string(stream.ReadChars(rds.Length, Encoding.Unicode)); - - return rds; - } - - public static ResourceDirectoryString Deserialize(byte[] content, ref int offset) - { - var rds = new ResourceDirectoryString(); - - rds.Length = content.ReadUInt16(ref offset); - if (rds.Length + offset > content.Length) - return null; - - rds.UnicodeString = Encoding.Unicode.GetString(content, offset, rds.Length); offset += rds.Length; - - return rds; - } - } -} diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryTableEntry.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryTableEntry.cs deleted file mode 100644 index d1d8146f..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/ResourceDirectoryTableEntry.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Entries -{ - /// - /// The directory entries make up the rows of a table. - /// Each resource directory entry has the following format. - /// Whether the entry is a Name or ID entry is indicated by the - /// resource directory table, which indicates how many Name and - /// ID entries follow it (remember that all the Name entries - /// precede all the ID entries for the table). All entries for - /// the table are sorted in ascending order: the Name entries - /// by case-sensitive string and the ID entries by numeric value. - /// Offsets are relative to the address in the IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-directory-entries - public class ResourceDirectoryTableEntry - { - /// - /// The offset of a string that gives the Type, Name, or Language ID entry, depending on level of table. - /// - public uint NameOffset => (uint)(IntegerId ^ (1 << 31)); - - /// - /// The string that gives the Type, Name, or Language ID entry, depending on level of table pointed to by NameOffset - /// - public ResourceDirectoryString Name; - - /// - /// A 32-bit integer that identifies the Type, Name, or Language ID entry. - /// - public uint IntegerId; - - /// - /// High bit 0. Address of a Resource Data entry (a leaf). - /// - public uint DataEntryOffset; - - /// - /// High bit 1. The lower 31 bits are the address of another resource directory table (the next level down). - /// - public uint SubdirectoryOffset => (uint)(DataEntryOffset ^ (1 << 31)); - - /// - /// Resource Data entry (a leaf). - /// - public ResourceDataEntry DataEntry; - - /// - /// Another resource directory table (the next level down). - /// - public ResourceDirectoryTable Subdirectory; - - /// - /// Determine if an entry has a name or integer identifier - /// - public bool IsIntegerIDEntry() => (IntegerId & (1 << 31)) == 0; - - /// - /// Determine if an entry represents a leaf or another directory table - /// - public bool IsResourceDataEntry() => (DataEntryOffset & (1 << 31)) == 0; - - public static ResourceDirectoryTableEntry Deserialize(Stream stream, long sectionStart, SectionHeader[] sections) - { - var rdte = new ResourceDirectoryTableEntry(); - - rdte.IntegerId = stream.ReadUInt32(); - if (!rdte.IsIntegerIDEntry()) - { - int nameAddress = (int)(rdte.NameOffset + sectionStart); - if (nameAddress >= 0 && nameAddress < stream.Length) - { - long lastPosition = stream.Position; - stream.Seek(nameAddress, SeekOrigin.Begin); - rdte.Name = ResourceDirectoryString.Deserialize(stream); - stream.Seek(lastPosition, SeekOrigin.Begin); - } - } - - rdte.DataEntryOffset = stream.ReadUInt32(); - if (rdte.IsResourceDataEntry()) - { - int dataEntryAddress = (int)(rdte.DataEntryOffset + sectionStart); - if (dataEntryAddress > 0 && dataEntryAddress < stream.Length) - { - long lastPosition = stream.Position; - stream.Seek(dataEntryAddress, SeekOrigin.Begin); - rdte.DataEntry = ResourceDataEntry.Deserialize(stream, sections); - stream.Seek(lastPosition, SeekOrigin.Begin); - } - } - else - { - int subdirectoryAddress = (int)(rdte.SubdirectoryOffset + sectionStart); - if (subdirectoryAddress > 0 && subdirectoryAddress < stream.Length) - { - long lastPosition = stream.Position; - stream.Seek(subdirectoryAddress, SeekOrigin.Begin); - rdte.Subdirectory = ResourceDirectoryTable.Deserialize(stream, sectionStart, sections); - stream.Seek(lastPosition, SeekOrigin.Begin); - } - } - - return rdte; - } - - public static ResourceDirectoryTableEntry Deserialize(byte[] content, ref int offset, long sectionStart, SectionHeader[] sections) - { - var rdte = new ResourceDirectoryTableEntry(); - - rdte.IntegerId = content.ReadUInt32(ref offset); - if (!rdte.IsIntegerIDEntry()) - { - int nameAddress = (int)(rdte.NameOffset + sectionStart); - if (nameAddress >= 0 && nameAddress < content.Length) - rdte.Name = ResourceDirectoryString.Deserialize(content, ref nameAddress); - } - - rdte.DataEntryOffset = content.ReadUInt32(ref offset); - if (rdte.IsResourceDataEntry()) - { - int dataEntryAddress = (int)(rdte.DataEntryOffset + sectionStart); - if (dataEntryAddress > 0 && dataEntryAddress < content.Length) - rdte.DataEntry = ResourceDataEntry.Deserialize(content, ref dataEntryAddress, sections); - } - else - { - int subdirectoryAddress = (int)(rdte.SubdirectoryOffset + sectionStart); - if (subdirectoryAddress > 0 && subdirectoryAddress < content.Length) - rdte.Subdirectory = ResourceDirectoryTable.Deserialize(content, ref subdirectoryAddress, sectionStart, sections); - } - - return rdte; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/CommonObjectFileFormatHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/CommonObjectFileFormatHeader.cs deleted file mode 100644 index 800e221d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/CommonObjectFileFormatHeader.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Headers -{ - public class CommonObjectFileFormatHeader - { - /// - /// After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte signature that identifies the file as a PE format image file. - // This signature is "PE\0\0" (the letters "P" and "E" followed by two null bytes). - /// - public uint Signature; - - /// - /// The number that identifies the type of target machine. - /// - public MachineType Machine; - - /// - /// The number of sections. - /// This indicates the size of the section table, which immediately follows the headers. - /// - public ushort NumberOfSections; - - /// - /// The low 32 bits of the number of seconds since 00:00 January 1, 1970 (a C run-time time_t value), which indicates when the file was created. - /// - public uint TimeDateStamp; - - /// - /// The file offset of the COFF symbol table, or zero if no COFF symbol table is present. - /// This value should be zero for an image because COFF debugging information is deprecated. - /// - [Obsolete] - public uint PointerToSymbolTable; - - /// - /// The number of entries in the symbol table. This data can be used to locate the string table, which immediately follows the symbol table. - /// This value should be zero for an image because COFF debugging information is deprecated. - /// - [Obsolete] - public uint NumberOfSymbols; - - /// - /// The size of the optional header, which is required for executable files but not for object files. - // This value should be zero for an object file. - /// - public ushort SizeOfOptionalHeader; - - /// - /// The flags that indicate the attributes of the file. - /// - public ImageObjectCharacteristics Characteristics; - - public static CommonObjectFileFormatHeader Deserialize(Stream stream) - { - var ifh = new CommonObjectFileFormatHeader(); - - ifh.Signature = stream.ReadUInt32(); - ifh.Machine = (MachineType)stream.ReadUInt16(); - ifh.NumberOfSections = stream.ReadUInt16(); - ifh.TimeDateStamp = stream.ReadUInt32(); - ifh.PointerToSymbolTable = stream.ReadUInt32(); - ifh.NumberOfSymbols = stream.ReadUInt32(); - ifh.SizeOfOptionalHeader = stream.ReadUInt16(); - ifh.Characteristics = (ImageObjectCharacteristics)stream.ReadUInt16(); - - return ifh; - } - - public static CommonObjectFileFormatHeader Deserialize(byte[] content, ref int offset) - { - var ifh = new CommonObjectFileFormatHeader(); - - ifh.Signature = content.ReadUInt32(ref offset); - ifh.Machine = (MachineType)content.ReadUInt16(ref offset); - ifh.NumberOfSections = content.ReadUInt16(ref offset); - ifh.TimeDateStamp = content.ReadUInt32(ref offset); - ifh.PointerToSymbolTable = content.ReadUInt32(ref offset); - ifh.NumberOfSymbols = content.ReadUInt32(ref offset); - ifh.SizeOfOptionalHeader = content.ReadUInt16(ref offset); - ifh.Characteristics = (ImageObjectCharacteristics)content.ReadUInt16(ref offset); - - return ifh; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/DataDirectoryHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/DataDirectoryHeader.cs deleted file mode 100644 index 06a5c783..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/DataDirectoryHeader.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Headers -{ - public class DataDirectoryHeader - { - /// - /// The first field, VirtualAddress, is actually the RVA of the table. - /// The RVA is the address of the table relative to the base address of the image when the table is loaded. - /// - public uint VirtualAddress; - - /// - /// The second field gives the size in bytes. - /// - public uint Size; - - public static DataDirectoryHeader Deserialize(Stream stream) - { - var ddh = new DataDirectoryHeader(); - - ddh.VirtualAddress = stream.ReadUInt32(); - ddh.Size = stream.ReadUInt32(); - - return ddh; - } - - public static DataDirectoryHeader Deserialize(byte[] content, ref int offset) - { - var ddh = new DataDirectoryHeader(); - - ddh.VirtualAddress = content.ReadUInt32(ref offset); - ddh.Size = content.ReadUInt32(ref offset); - - return ddh; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/OptionalHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/OptionalHeader.cs deleted file mode 100644 index ec804513..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/OptionalHeader.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Headers -{ - /// - /// Every image file has an optional header that provides information to the loader. - /// This header is optional in the sense that some files (specifically, object files) do not have it. - /// For image files, this header is required. An object file can have an optional header, but generally - /// this header has no function in an object file except to increase its size. - /// - /// Note that the size of the optional header is not fixed. - /// The SizeOfOptionalHeader field in the COFF header must be used to validate that a probe into the file - /// for a particular data directory does not go beyond SizeOfOptionalHeader. - /// - /// The NumberOfRvaAndSizes field of the optional header should also be used to ensure that no probe for - /// a particular data directory entry goes beyond the optional header. - /// In addition, it is important to validate the optional header magic number for format compatibility. - /// - public class OptionalHeader - { - #region Standard Fields - - /// - /// The unsigned integer that identifies the state of the image file. - /// The most common number is 0x10B, which identifies it as a normal executable file. - /// 0x107 identifies it as a ROM image, and 0x20B identifies it as a PE32+ executable. - /// - public OptionalHeaderType Magic; - - /// - /// The linker major version number. - /// - public byte MajorLinkerVersion; - - /// - /// The linker minor version number. - /// - public byte MinorLinkerVersion; - - /// - /// The size of the code (text) section, or the sum of all code sections if there are multiple sections. - /// - public uint SizeOfCode; - - /// - /// The size of the initialized data section, or the sum of all such sections if there are multiple data sections. - /// - public uint SizeOfInitializedData; - - /// - /// The size of the uninitialized data section (BSS), or the sum of all such sections if there are multiple BSS sections. - /// - public uint SizeOfUninitializedData; - - /// - /// The address of the entry point relative to the image base when the executable file is loaded into memory. - /// For program images, this is the starting address. - /// For device drivers, this is the address of the initialization function. - /// An entry point is optional for DLLs. - /// When no entry point is present, this field must be zero. - /// - public uint AddressOfEntryPoint; - - /// - /// The address that is relative to the image base of the beginning-of-code section when it is loaded into memory. - /// - public uint BaseOfCode; - - /// - /// The address that is relative to the image base of the beginning-of-data section when it is loaded into memory. - /// - public uint BaseOfData; - - #endregion - - #region Windows-Specific Fields - - /// - /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. - /// The default for DLLs is 0x10000000. - /// The default for Windows CE EXEs is 0x00010000. - /// The default for Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. - /// - public uint ImageBasePE32; - - /// - /// The preferred address of the first byte of image when loaded into memory; must be a multiple of 64 K. - /// The default for DLLs is 0x10000000. - /// The default for Windows CE EXEs is 0x00010000. - /// The default for Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98, and Windows Me is 0x00400000. - /// - public ulong ImageBasePE32Plus; - - /// - /// The alignment (in bytes) of sections when they are loaded into memory. - /// It must be greater than or equal to FileAlignment. - /// The default is the page size for the architecture. - /// - public uint SectionAlignment; - - /// - /// The alignment factor (in bytes) that is used to align the raw data of sections in the image file. - /// The value should be a power of 2 between 512 and 64 K, inclusive. - /// The default is 512. - /// If the SectionAlignment is less than the architecture's page size, then FileAlignment must match SectionAlignment. - /// - public uint FileAlignment; - - /// - /// The major version number of the required operating system. - /// - public ushort MajorOperatingSystemVersion; - - /// - /// The minor version number of the required operating system. - /// - public ushort MinorOperatingSystemVersion; - - /// - /// The major version number of the image. - /// - public ushort MajorImageVersion; - - /// - /// The minor version number of the image. - /// - public ushort MinorImageVersion; - - /// - /// The major version number of the subsystem. - /// - public ushort MajorSubsystemVersion; - - /// - /// The minor version number of the subsystem. - /// - public ushort MinorSubsystemVersion; - - /// - /// Reserved, must be zero. - /// - public uint Reserved1; - - /// - /// The size (in bytes) of the image, including all headers, as the image is loaded in memory. - /// It must be a multiple of SectionAlignment. - /// - public uint SizeOfImage; - - /// - /// The combined size of an MS-DOS stub, PE header, and section headers rounded up to a multiple of FileAlignment. - /// - public uint SizeOfHeaders; - - /// - /// The image file checksum. - /// The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. - /// The following are checked for validation at load time: all drivers, any DLL loaded at boot time, and any DLL that is loaded into a critical Windows process. - /// - public uint CheckSum; - - /// - /// The subsystem that is required to run this image. - /// - public WindowsSubsystem Subsystem; - - /// - /// DLL Characteristics - /// - public DllCharacteristics DllCharacteristics; - - /// - /// The size of the stack to reserve. - /// Only SizeOfStackCommit is committed; the rest is made available one page at a time until the reserve size is reached. - /// - public uint SizeOfStackReservePE32; - - /// - /// The size of the stack to reserve. - /// Only SizeOfStackCommit is committed; the rest is made available one page at a time until the reserve size is reached. - /// - public ulong SizeOfStackReservePE32Plus; - - /// - /// The size of the stack to commit. - /// - public uint SizeOfStackCommitPE32; - - /// - /// The size of the stack to commit. - /// - public ulong SizeOfStackCommitPE32Plus; - - /// - /// The size of the local heap space to reserve. - /// Only SizeOfHeapCommit is committed; the rest is made available one page at a time until the reserve size is reached. - /// - public uint SizeOfHeapReservePE32; - - /// - /// The size of the local heap space to reserve. - /// Only SizeOfHeapCommit is committed; the rest is made available one page at a time until the reserve size is reached. - /// - public ulong SizeOfHeapReservePE32Plus; - - /// - /// The size of the local heap space to commit. - /// - public uint SizeOfHeapCommitPE32; - - /// - /// The size of the local heap space to commit. - /// - public ulong SizeOfHeapCommitPE32Plus; - - /// - /// Reserved, must be zero. - /// - public uint LoaderFlags; - - /// - /// The number of data-directory entries in the remainder of the optional header. - /// Each describes a location and size. - /// - public uint NumberOfRvaAndSizes; - - /// - /// Data-directory entries following the optional header - /// - public DataDirectoryHeader[] DataDirectories; - - #endregion - - public static OptionalHeader Deserialize(Stream stream) - { - var ioh = new OptionalHeader(); - - ioh.Magic = (OptionalHeaderType)stream.ReadUInt16(); - ioh.MajorLinkerVersion = stream.ReadByteValue(); - ioh.MinorLinkerVersion = stream.ReadByteValue(); - ioh.SizeOfCode = stream.ReadUInt32(); - ioh.SizeOfInitializedData = stream.ReadUInt32(); - ioh.SizeOfUninitializedData = stream.ReadUInt32(); - ioh.AddressOfEntryPoint = stream.ReadUInt32(); - ioh.BaseOfCode = stream.ReadUInt32(); - - // Only standard PE32 has this value - if (ioh.Magic == OptionalHeaderType.PE32) - ioh.BaseOfData = stream.ReadUInt32(); - - // PE32+ has an 8-byte value here - if (ioh.Magic == OptionalHeaderType.PE32Plus) - ioh.ImageBasePE32Plus = stream.ReadUInt64(); - else - ioh.ImageBasePE32 = stream.ReadUInt32(); - - ioh.SectionAlignment = stream.ReadUInt32(); - ioh.FileAlignment = stream.ReadUInt32(); - ioh.MajorOperatingSystemVersion = stream.ReadUInt16(); - ioh.MinorOperatingSystemVersion = stream.ReadUInt16(); - ioh.MajorImageVersion = stream.ReadUInt16(); - ioh.MinorImageVersion = stream.ReadUInt16(); - ioh.MajorSubsystemVersion = stream.ReadUInt16(); - ioh.MinorSubsystemVersion = stream.ReadUInt16(); - ioh.Reserved1 = stream.ReadUInt32(); - ioh.SizeOfImage = stream.ReadUInt32(); - ioh.SizeOfHeaders = stream.ReadUInt32(); - ioh.CheckSum = stream.ReadUInt32(); - ioh.Subsystem = (WindowsSubsystem)stream.ReadUInt16(); - ioh.DllCharacteristics = (DllCharacteristics)stream.ReadUInt16(); - - // PE32+ uses 8-byte values - if (ioh.Magic == OptionalHeaderType.PE32Plus) - { - ioh.SizeOfStackReservePE32Plus = stream.ReadUInt64(); - ioh.SizeOfStackCommitPE32Plus = stream.ReadUInt64(); - ioh.SizeOfHeapReservePE32Plus = stream.ReadUInt64(); - ioh.SizeOfHeapCommitPE32Plus = stream.ReadUInt64(); - } - else - { - ioh.SizeOfStackReservePE32 = stream.ReadUInt32(); - ioh.SizeOfStackCommitPE32 = stream.ReadUInt32(); - ioh.SizeOfHeapReservePE32 = stream.ReadUInt32(); - ioh.SizeOfHeapCommitPE32 = stream.ReadUInt32(); - } - - ioh.LoaderFlags = stream.ReadUInt32(); - ioh.NumberOfRvaAndSizes = stream.ReadUInt32(); - ioh.DataDirectories = new DataDirectoryHeader[Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - for (int i = 0; i < Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) - { - ioh.DataDirectories[i] = DataDirectoryHeader.Deserialize(stream); - } - - return ioh; - } - - public static OptionalHeader Deserialize(byte[] content, ref int offset) - { - var ioh = new OptionalHeader(); - - ioh.Magic = (OptionalHeaderType)content.ReadUInt16(ref offset); - ioh.MajorLinkerVersion = content[offset]; offset++; - ioh.MinorLinkerVersion = content[offset]; offset++; - ioh.SizeOfCode = content.ReadUInt32(ref offset); - ioh.SizeOfInitializedData = content.ReadUInt32(ref offset); - ioh.SizeOfUninitializedData = content.ReadUInt32(ref offset); - ioh.AddressOfEntryPoint = content.ReadUInt32(ref offset); - ioh.BaseOfCode = content.ReadUInt32(ref offset); - - // Only standard PE32 has this value - if (ioh.Magic == OptionalHeaderType.PE32) - ioh.BaseOfData = content.ReadUInt32(ref offset); - - // PE32+ has an 8-bit value here - if (ioh.Magic == OptionalHeaderType.PE32Plus) - { - ioh.ImageBasePE32Plus = content.ReadUInt64(ref offset); - } - else - { - ioh.ImageBasePE32 = content.ReadUInt32(ref offset); - } - - ioh.SectionAlignment = content.ReadUInt32(ref offset); - ioh.FileAlignment = content.ReadUInt32(ref offset); - ioh.MajorOperatingSystemVersion = content.ReadUInt16(ref offset); - ioh.MinorOperatingSystemVersion = content.ReadUInt16(ref offset); - ioh.MajorImageVersion = content.ReadUInt16(ref offset); - ioh.MinorImageVersion = content.ReadUInt16(ref offset); - ioh.MajorSubsystemVersion = content.ReadUInt16(ref offset); - ioh.MinorSubsystemVersion = content.ReadUInt16(ref offset); - ioh.Reserved1 = content.ReadUInt32(ref offset); - ioh.SizeOfImage = content.ReadUInt32(ref offset); - ioh.SizeOfHeaders = content.ReadUInt32(ref offset); - ioh.CheckSum = content.ReadUInt32(ref offset); - ioh.Subsystem = (WindowsSubsystem)content.ReadUInt16(ref offset); - ioh.DllCharacteristics = (DllCharacteristics)content.ReadUInt16(ref offset); - - // PE32+ uses 8-byte values - if (ioh.Magic == OptionalHeaderType.PE32Plus) - { - ioh.SizeOfStackReservePE32Plus = content.ReadUInt64(ref offset); - ioh.SizeOfStackCommitPE32Plus = content.ReadUInt64(ref offset); - ioh.SizeOfHeapReservePE32Plus = content.ReadUInt64(ref offset); - ioh.SizeOfHeapCommitPE32Plus = content.ReadUInt64(ref offset); - } - else - { - ioh.SizeOfStackReservePE32 = content.ReadUInt32(ref offset); - ioh.SizeOfStackCommitPE32 = content.ReadUInt32(ref offset); - ioh.SizeOfHeapReservePE32 = content.ReadUInt32(ref offset); - ioh.SizeOfHeapCommitPE32 = content.ReadUInt32(ref offset); - } - - ioh.LoaderFlags = content.ReadUInt32(ref offset); - ioh.NumberOfRvaAndSizes = content.ReadUInt32(ref offset); - ioh.DataDirectories = new DataDirectoryHeader[Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - for (int i = 0; i < Constants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) - { - ioh.DataDirectories[i] = DataDirectoryHeader.Deserialize(content, ref offset); - } - - return ioh; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/SectionHeader.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/SectionHeader.cs deleted file mode 100644 index 323818cf..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Headers/SectionHeader.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Headers -{ - /// - /// Each row of the section table is, in effect, a section header. - /// This table immediately follows the optional header, if any. - /// This positioning is required because the file header does not contain a direct pointer to the section table. - /// Instead, the location of the section table is determined by calculating the location of the first byte after the headers. - /// Make sure to use the size of the optional header as specified in the file header. - /// - public class SectionHeader - { - /// - /// An 8-byte, null-padded UTF-8 encoded string. - /// If the string is exactly 8 characters long, there is no terminating null. - /// For longer names, this field contains a slash (/) that is followed by an ASCII representation of a decimal number - /// that is an offset into the string table. - /// Executable images do not use a string table and do not support section names longer than 8 characters. - /// Long names in object files are truncated if they are emitted to an executable file. - /// - public byte[] Name; - - /// - /// Section name as a string, trimming any trailing null bytes - /// - public string NameString - { - get - { - if (this.Name == null || this.Name.Length == 0) - return null; - - // First try decoding as UTF-8 - try - { - return Encoding.UTF8.GetString(this.Name).TrimEnd('\0'); - } - catch { } - - // Then try decoding as ASCII - try - { - return Encoding.ASCII.GetString(this.Name).TrimEnd('\0'); - } - catch { } - - // If it fails, return null - return null; - } - } - - /// - /// The total size of the section when loaded into memory. - /// If this value is greater than SizeOfRawData, the section is zero-padded. - /// This field is valid only for executable images and should be set to zero for object files. - /// - public uint VirtualSize; - - /// - /// For executable images, the address of the first byte of the section relative to the image base when the section - /// is loaded into memory. - /// For object files, this field is the address of the first byte before relocation is applied; for simplicity, - /// compilers should set this to zero. - /// Otherwise, it is an arbitrary value that is subtracted from offsets during relocation. - /// - public uint VirtualAddress; - - /// - /// The size of the section (for object files) or the size of the initialized data on disk (for image files). - /// For executable images, this must be a multiple of FileAlignment from the optional header. - /// If this is less than VirtualSize, the remainder of the section is zero-filled. - /// Because the SizeOfRawData field is rounded but the VirtualSize field is not, it is possible for SizeOfRawData - /// to be greater than VirtualSize as well. - /// When a section contains only uninitialized data, this field should be zero. - /// - public uint SizeOfRawData; - - /// - /// The file pointer to the first page of the section within the COFF file. - /// For executable images, this must be a multiple of FileAlignment from the optional header. - /// For object files, the value should be aligned on a 4-byte boundary for best performance. - /// When a section contains only uninitialized data, this field should be zero. - /// - public uint PointerToRawData; - - /// - /// The file pointer to the beginning of relocation entries for the section. - /// This is set to zero for executable images or if there are no relocations. - /// - public uint PointerToRelocations; - - /// - /// The file pointer to the beginning of line-number entries for the section. - /// This is set to zero if there are no COFF line numbers. - /// This value should be zero for an image because COFF debugging information is deprecated. - /// - [Obsolete] - public uint PointerToLinenumbers; - - /// - /// The number of relocation entries for the section. - /// This is set to zero for executable images. - /// - public ushort NumberOfRelocations; - - /// - /// The number of line-number entries for the section. - /// This value should be zero for an image because COFF debugging information is deprecated. - /// - [Obsolete] - public ushort NumberOfLinenumbers; - - /// - /// The flags that describe the characteristics of the section. - /// - public SectionCharacteristics Characteristics; - - public static SectionHeader Deserialize(Stream stream) - { - var ish = new SectionHeader(); - - ish.Name = stream.ReadBytes(Constants.IMAGE_SIZEOF_SHORT_NAME); - ish.VirtualSize = stream.ReadUInt32(); - ish.VirtualAddress = stream.ReadUInt32(); - ish.SizeOfRawData = stream.ReadUInt32(); - ish.PointerToRawData = stream.ReadUInt32(); - ish.PointerToRelocations = stream.ReadUInt32(); - ish.PointerToLinenumbers = stream.ReadUInt32(); - ish.NumberOfRelocations = stream.ReadUInt16(); - ish.NumberOfLinenumbers = stream.ReadUInt16(); - ish.Characteristics = (SectionCharacteristics)stream.ReadUInt32(); - - return ish; - } - - public static SectionHeader Deserialize(byte[] content, ref int offset) - { - var ish = new SectionHeader(); - - ish.Name = new byte[Constants.IMAGE_SIZEOF_SHORT_NAME]; - Array.Copy(content, offset, ish.Name, 0, Constants.IMAGE_SIZEOF_SHORT_NAME); offset += Constants.IMAGE_SIZEOF_SHORT_NAME; - ish.VirtualSize = content.ReadUInt32(ref offset); - ish.VirtualAddress = content.ReadUInt32(ref offset); - ish.SizeOfRawData = content.ReadUInt32(ref offset); - ish.PointerToRawData = content.ReadUInt32(ref offset); - ish.PointerToRelocations = content.ReadUInt32(ref offset); - ish.PointerToLinenumbers = content.ReadUInt32(ref offset); - ish.NumberOfRelocations = content.ReadUInt16(ref offset); - ish.NumberOfLinenumbers = content.ReadUInt16(ref offset); - ish.Characteristics = (SectionCharacteristics)content.ReadUInt32(ref offset); - - return ish; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs deleted file mode 100644 index 295378ed..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs +++ /dev/null @@ -1,1054 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Xml; -using BurnOutSharp.ExecutableType.Microsoft.MZ.Headers; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.ExecutableType.Microsoft.PE.Sections; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; -using BurnOutSharp.ExecutableType.Microsoft.Resources; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE -{ - /// - /// The PE file header consists of a Microsoft MS-DOS stub, the PE signature, the COFF file header, and an optional header. - /// A COFF object file header consists of a COFF file header and an optional header. - /// In both cases, the file headers are followed immediately by section headers. - /// - public class PortableExecutable - { - /// - /// Value determining if the executable is initialized or not - /// - public bool Initialized { get; } = false; - - /// - /// Source array that the executable was parsed from - /// - private readonly byte[] _sourceArray = null; - - /// - /// Source stream that the executable was parsed from - /// - private readonly Stream _sourceStream = null; - - #region Headers - - /// - /// The MS-DOS stub is a valid application that runs under MS-DOS. - /// It is placed at the front of the EXE image. - /// The linker places a default stub here, which prints out the message "This program cannot be run in DOS mode" when the image is run in MS-DOS. - /// The user can specify a different stub by using the /STUB linker option. - /// At location 0x3c, the stub has the file offset to the PE signature. - /// This information enables Windows to properly execute the image file, even though it has an MS-DOS stub. - /// This file offset is placed at location 0x3c during linking. - /// - public MSDOSExecutableHeader DOSStubHeader; - - /// - /// At the beginning of an object file, or immediately after the signature of an image file, is a standard COFF file header in the following format. - /// Note that the Windows loader limits the number of sections to 96. - /// - public CommonObjectFileFormatHeader ImageFileHeader; - - /// - /// Every image file has an optional header that provides information to the loader. - /// This header is optional in the sense that some files (specifically, object files) do not have it. - /// For image files, this header is required. - /// An object file can have an optional header, but generally this header has no function in an object file except to increase its size. - /// - public OptionalHeader OptionalHeader; - - /// - /// Each row of the section table is, in effect, a section header. - /// This table immediately follows the optional header, if any. - /// This positioning is required because the file header does not contain a direct pointer to the section table. - /// Instead, the location of the section table is determined by calculating the location of the first byte after the headers. - /// Make sure to use the size of the optional header as specified in the file header. - /// - public SectionHeader[] SectionTable; - - #endregion - - #region Tables - - /// - /// The .debug section is used in object files to contain compiler-generated debug information and in image files to contain - /// all of the debug information that is generated. - /// This section describes the packaging of debug information in object and image files. - /// - public DebugSection DebugDirectory; - - /// - /// The export data section, named .edata, contains information about symbols that other images can access through dynamic linking. - /// Exported symbols are generally found in DLLs, but DLLs can also import symbols. - /// - public ExportDataSection ExportTable; - - /// - /// All image files that import symbols, including virtually all executable (EXE) files, have an .idata section. - /// - public ImportDataSection ImportTable; - - /// - /// The base relocation table contains entries for all base relocations in the image. - /// The Base Relocation Table field in the optional header data directories gives the number of bytes in the base relocation table. - /// - public RelocationSection RelocationTable; - - /// - /// Resources are indexed by a multiple-level binary-sorted tree structure. - /// The general design can incorporate 2**31 levels. - /// By convention, however, Windows uses three levels - /// - public ResourceSection ResourceSection; - - // TODO: Add more and more parts of a standard PE executable, not just the header - // TODO: Add data directory table information here instead of in IMAGE_OPTIONAL_HEADER - - #endregion - - #region Raw Section Data - - // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#special-sections - // Here is a list of standard sections that are used in various protections: - // Y - .bss *1 protection Uninitialized data (free format) - // X - .data 14 protections Initialized data (free format) - // X - .edata *1 protection Export tables - // X - .idata *1 protection Import tables - // X - .rdata 11 protections Read-only initialized data - // - .rsrc *1 protection Resource directory [TODO: Mostly taken care of, last protection needs research] - // X - .text 6 protections Executable code (free format) - // Y - .tls *1 protection Thread-local storage (object only) - // - // Here is a list of non-standard sections whose contents are read by various protections: - // X - CODE 2 protections SafeDisc, WTM CD Protect - // X - .dcrtext *1 protection JoWood - // X - .grand *1 protection CD-Cops / DVD-Cops - // X - .init *1 protection SolidShield - // - .pec2 *1 protection PE Compact [Unconfirmed] - // - .NOS0 *1 protection UPX (NOS Variant) - // - .NOS1 *1 protection UPX (NOS Variant) - // X - .txt2 *1 protection SafeDisc - // - .UPX0 *1 protection UPX - // - .UPX1 *1 protection UPX - // - // Here is a list of non-standard sections whose data is not read by various protections: - // - .brick 1 protection StarForce - // - .cenega 1 protection Cenega ProtectDVD - // - .ext 1 protection JoWood - // - HC09 1 protection JoWood - // - .icd* 1 protection CodeLock - // - .ldr 1 protection 3PLock - // - .ldt 1 protection 3PLock - // - .nicode 1 protection Armadillo - // - .pec1 1 protection PE Compact - // - .securom 1 protection SecuROM - // - .sforce 1 protection StarForce - // - stxt371 1 protection SafeDisc - // - stxt774 1 protection SafeDisc - // - .vob.pcd 1 protection VOB ProtectCD - // - _winzip_ 1 protection WinZip SFX - // - XPROT 1 protection JoWood - // - // * => Only used by 1 protection so it may be read in by that protection specifically - - /// - /// .data/DATA - Initialized data (free format) - /// - public byte[] DataSectionRaw; - - /// - /// .edata - Export tables - /// - /// Replace with ExportDataSection - public byte[] ExportDataSectionRaw; - - /// - /// .idata - Import tables - /// - /// Replace with ImportDataSection - public byte[] ImportDataSectionRaw; - - /// - /// .rdata - Read-only initialized data - /// - public byte[] ResourceDataSectionRaw; - - /// - /// .text - Executable code (free format) - /// - public byte[] TextSectionRaw; - - #endregion - - #region Raw Other Data - - /// - /// Data at the entry point of the application - /// - public byte[] EntryPointRaw; - - /// - /// Data from the overlay of the application - /// - public byte[] OverlayRaw; - - #endregion - - #region Resources - - /// - /// Company name resource string - /// - public string CompanyName { get; private set; } - - /// - /// File description resource string - /// - public string FileDescription { get; private set; } - - /// - /// File version resource string - /// - public string FileVersion { get; private set; } - - /// - /// Internal name resource string - /// - public string InternalName { get; private set; } - - /// - /// Legal copyright resource string - /// - public string LegalCopyright { get; private set; } - - /// - /// Legal trademarks resource string - /// - public string LegalTrademarks { get; private set; } - - /// - /// Description manifest string - /// - public string ManifestDescription { get; private set; } - - /// - /// Version manifest string - /// - public string ManifestVersion { get; private set; } - - /// - /// Original filename resource string - /// - public string OriginalFileName { get; private set; } - - /// - /// Product name resource string - /// - public string ProductName { get; private set; } - - /// - /// Product version resource string - /// - public string ProductVersion { get; private set; } - - #endregion - - #region Constructors - - /// - /// Create a PortableExecutable object from a stream - /// - /// Stream representing a file - /// - /// This constructor assumes that the stream is already in the correct position to start parsing - /// - public PortableExecutable(Stream stream) - { - if (stream == null || !stream.CanRead || !stream.CanSeek) - return; - - this._sourceStream = stream; - this.Initialized = Deserialize(stream); - } - - /// - /// Create a PortableExecutable object from a byte array - /// - /// Byte array representing a file - /// Positive offset representing the current position in the array - public PortableExecutable(byte[] fileContent, int offset) - { - if (fileContent == null || fileContent.Length == 0 || offset < 0) - return; - - this._sourceArray = fileContent; - this.Initialized = Deserialize(fileContent, offset); - } - - /// - /// Deserialize a PortableExecutable object from a stream - /// - /// Stream representing a file - private bool Deserialize(Stream stream) - { - try - { - // Attempt to read the DOS header first - this.DOSStubHeader = MSDOSExecutableHeader.Deserialize(stream); stream.Seek(this.DOSStubHeader.NewExeHeaderAddr, SeekOrigin.Begin); - if (this.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE) - return false; - - // If the new header address is invalid for the file, it's not a PE - if (this.DOSStubHeader.NewExeHeaderAddr >= stream.Length) - return false; - - // Then attempt to read the PE header - this.ImageFileHeader = CommonObjectFileFormatHeader.Deserialize(stream); - if (this.ImageFileHeader.Signature != Constants.IMAGE_NT_SIGNATURE) - return false; - - // If the optional header is supposed to exist, read that as well - if (this.ImageFileHeader.SizeOfOptionalHeader > 0) - this.OptionalHeader = OptionalHeader.Deserialize(stream); - - // Then read in the section table - this.SectionTable = new SectionHeader[this.ImageFileHeader.NumberOfSections]; - for (int i = 0; i < this.ImageFileHeader.NumberOfSections; i++) - { - this.SectionTable[i] = SectionHeader.Deserialize(stream); - } - - #region Structured Tables - - // // Debug Section - // var table = this.GetLastSection(".debug", true); - // if (table != null && table.VirtualSize > 0) - // { - // stream.Seek((int)table.PointerToRawData, SeekOrigin.Begin); - // this.DebugSection = DebugSection.Deserialize(stream, this.SectionTable); - // } - - // // Export Table - // var table = this.GetLastSection(".edata", true); - // if (table != null && table.VirtualSize > 0) - // { - // stream.Seek((int)table.PointerToRawData, SeekOrigin.Begin); - // this.ExportTable = ExportDataSection.Deserialize(stream, this.SectionTable); - // } - - // // Import Table - // table = this.GetSection(".idata", true); - // if (table != null && table.VirtualSize > 0) - // { - // stream.Seek((int)table.PointerToRawData, SeekOrigin.Begin); - // this.ImportTable = ImportDataSection.Deserialize(stream, this.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0); - // } - - // // Relocation Section - // var table = this.GetLastSection(".reloc", true); - // if (table != null && table.VirtualSize > 0) - // { - // stream.Seek((int)table.PointerToRawData, SeekOrigin.Begin); - // this.RelocationTable = RelocationSection.Deserialize(stream); - // } - - // Resource Table - var table = this.GetLastSection(".rsrc", true); - if (table != null && table.VirtualSize > 0) - { - stream.Seek((int)table.PointerToRawData, SeekOrigin.Begin); - this.ResourceSection = ResourceSection.Deserialize(stream, this.SectionTable); - } - - #endregion - - #region Freeform Sections - - // Data Section - this.DataSectionRaw = this.ReadRawSection(".data", force: true, first: false) ?? this.ReadRawSection("DATA", force: true, first: false); - - // Export Table - this.ExportDataSectionRaw = this.ReadRawSection(".edata", force: true, first: false); - - // Import Table - this.ImportDataSectionRaw = this.ReadRawSection(".idata", force: true, first: false); - - // Resource Data Section - this.ResourceDataSectionRaw = this.ReadRawSection(".rdata", force: true, first: false); - - // Text Section - this.TextSectionRaw = this.ReadRawSection(".text", force: true, first: false); - - #endregion - - #region Freeform Data - - // Entry Point Data - if (this.OptionalHeader != null && this.OptionalHeader.AddressOfEntryPoint != 0) - { - int entryPointAddress = (int)ConvertVirtualAddress(this.OptionalHeader.AddressOfEntryPoint, SectionTable); - this.EntryPointRaw = this.ReadArbitraryRange(entryPointAddress, 1024); - } - - // Overlay Data - if (this.SectionTable != null && this.SectionTable.Length > 0) - { - // TODO: Read certificate data separately - int overlayOffset = this.SectionTable - .Select(sh => (int)(sh.PointerToRawData + sh.VirtualSize)) - .OrderByDescending(o => o) - .First(); - - if (overlayOffset < stream.Length) - this.OverlayRaw = this.ReadArbitraryRange(rangeStart: overlayOffset); - } - - #endregion - - // Populate resources, if possible - PopulateResourceStrings(); - } - catch (Exception ex) - { - //Console.WriteLine($"Errored out on a file: {ex}"); - return false; - } - - return true; - } - - /// - /// Deserialize a PortableExecutable object from a byte array - /// - /// Byte array representing a file - /// Positive offset representing the current position in the array - private bool Deserialize(byte[] content, int offset) - { - try - { - // Attempt to read the DOS header first - this.DOSStubHeader = MSDOSExecutableHeader.Deserialize(content, ref offset); - offset = this.DOSStubHeader.NewExeHeaderAddr; - if (this.DOSStubHeader.Magic != Constants.IMAGE_DOS_SIGNATURE) - return false; - - // If the new header address is invalid for the file, it's not a PE - if (this.DOSStubHeader.NewExeHeaderAddr >= content.Length) - return false; - - // Then attempt to read the PE header - this.ImageFileHeader = CommonObjectFileFormatHeader.Deserialize(content, ref offset); - if (this.ImageFileHeader.Signature != Constants.IMAGE_NT_SIGNATURE) - return false; - - // If the optional header is supposed to exist, read that as well - if (this.ImageFileHeader.SizeOfOptionalHeader > 0) - this.OptionalHeader = OptionalHeader.Deserialize(content, ref offset); - - // Then read in the section table - this.SectionTable = new SectionHeader[this.ImageFileHeader.NumberOfSections]; - for (int i = 0; i < this.ImageFileHeader.NumberOfSections; i++) - { - this.SectionTable[i] = SectionHeader.Deserialize(content, ref offset); - } - - #region Structured Tables - - // // Debug Section - // var table = this.GetLastSection(".debug", true); - // if (table != null && table.VirtualSize > 0) - // { - // int tableAddress = (int)table.PointerToRawData; - // this.DebugSection = DebugSection.Deserialize(content, ref tableAddress, this.SectionTable); - // } - - // // Export Table - // var table = this.GetLastSection(".edata", true); - // if (table != null && table.VirtualSize > 0) - // { - // int tableAddress = (int)table.PointerToRawData; - // this.ExportTable = ExportDataSection.Deserialize(content, ref tableAddress, this.SectionTable); - // } - - // // Import Table - // table = this.GetSection(".idata", true); - // if (table != null && table.VirtualSize > 0) - // { - // int tableAddress = (int)table.PointerToRawData; - // this.ImportTable = ImportDataSection.Deserialize(content, ref tableAddress, this.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0); - // } - - // // Relocation Section - // var table = this.GetLastSection(".reloc", true); - // if (table != null && table.VirtualSize > 0) - // { - // int tableAddress = (int)table.PointerToRawData; - // this.RelocationTable = RelocationSection.Deserialize(content, ref tableAddress); - // } - - // Resource Table - var table = this.GetLastSection(".rsrc", true); - if (table != null && table.VirtualSize > 0) - { - int tableAddress = (int)table.PointerToRawData; - this.ResourceSection = ResourceSection.Deserialize(content, ref tableAddress, this.SectionTable); - } - - #endregion - - #region Freeform Sections - - // Data Section - this.DataSectionRaw = this.ReadRawSection(".data", force: true, first: false) ?? this.ReadRawSection("DATA", force: true, first: false); - - // Export Table - this.ExportDataSectionRaw = this.ReadRawSection(".edata", force: true, first: false); - - // Import Table - this.ImportDataSectionRaw = this.ReadRawSection(".idata", force: true, first: false); - - // Resource Data Section - this.ResourceDataSectionRaw = this.ReadRawSection(".rdata", force: true, first: false); - - // Text Section - this.TextSectionRaw = this.ReadRawSection(".text", force: true, first: false); - - #endregion - - #region Freeform Data - - // Entry Point Data - if (this.OptionalHeader != null && this.OptionalHeader.AddressOfEntryPoint != 0) - { - int entryPointAddress = (int)ConvertVirtualAddress(this.OptionalHeader.AddressOfEntryPoint, SectionTable); - this.EntryPointRaw = this.ReadArbitraryRange(entryPointAddress, 1024); - } - - // Overlay Data - if (this.SectionTable != null && this.SectionTable.Length > 0) - { - // TODO: Read certificate data separately - int overlayOffset = this.SectionTable - .Select(sh => (int)(sh.PointerToRawData + sh.VirtualSize)) - .OrderByDescending(o => o) - .First(); - - if (overlayOffset < content.Length) - this.OverlayRaw = this.ReadArbitraryRange(rangeStart: overlayOffset); - } - - #endregion - - // Populate resources, if possible - PopulateResourceStrings(); - } - catch (Exception ex) - { - //Console.WriteLine($"Errored out on a file: {ex}"); - return false; - } - - return true; - } - - #endregion - - #region Resource Helpers - - /// - /// Find resource data in a ResourceSection, if possible - /// - /// String to use if checking for data starting with a string - /// String to use if checking for data contains a string - /// String to use if checking for data ending with a string - /// Full encoded resource data, null on error - public ResourceDataEntry FindResource(string dataStart = null, string dataContains = null, string dataEnd = null) - { - if (this.ResourceSection == null) - return null; - - return FindResourceInTable(this.ResourceSection.ResourceDirectoryTable, dataStart, dataContains, dataEnd); - } - - /// - /// Get the assembly identity node from an embedded manifest - /// - /// String representing the XML document - /// Assembly identity node, if possible - private XmlElement GetAssemblyNode(string manifestString) - { - // An invalid string means we can't read it - if (string.IsNullOrWhiteSpace(manifestString)) - return null; - - try - { - // Load the XML string as a document - var manifestDoc = new XmlDocument(); - manifestDoc.LoadXml(manifestString); - - // If the XML has no children, it's invalid - if (!manifestDoc.HasChildNodes) - return null; - - // Try to read the assembly node - return manifestDoc["assembly"]; - } - catch (Exception ex) - { - return null; - } - } - - /// - /// Find the assembly manifest from a resource section, if possible - /// - /// Full assembly manifest, null on error - private string FindAssemblyManifest() => FindResource(dataContains: " - /// Find resource data in a ResourceDirectoryTable, if possible - /// - /// ResourceDirectoryTable representing a layer - /// String to use if checking for data starting with a string - /// String to use if checking for data contains a string - /// String to use if checking for data ending with a string - /// Full encoded resource data, null on error - private ResourceDataEntry FindResourceInTable(ResourceDirectoryTable rdt, string dataStart, string dataContains, string dataEnd) - { - if (rdt == null) - return null; - - try - { - foreach (var rdte in rdt.NamedEntries) - { - if (rdte.IsResourceDataEntry() && rdte.DataEntry != null) - { - // Ignore if we have a nested executable - // TODO: Support nested executables - if (rdte.DataEntry.DataAsUTF8String.StartsWith("MZ")) - return null; - - if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart)) - return rdte.DataEntry; - else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains)) - return rdte.DataEntry; - else if (dataEnd != null && rdte.DataEntry.DataAsUTF8String.EndsWith(dataStart)) - return rdte.DataEntry; - } - else - { - var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains, dataEnd); - if (manifest != null) - return manifest; - } - } - - foreach (var rdte in rdt.IdEntries) - { - if (rdte.IsResourceDataEntry() && rdte.DataEntry != null) - { - // Ignore if we have a nested executable - // TODO: Support nested executables - if (rdte.DataEntry.DataAsUTF8String.StartsWith("MZ")) - return null; - - if (dataStart != null && rdte.DataEntry.DataAsUTF8String.StartsWith(dataStart)) - return rdte.DataEntry; - else if (dataContains != null && rdte.DataEntry.DataAsUTF8String.Contains(dataContains)) - return rdte.DataEntry; - else if (dataEnd != null && rdte.DataEntry.DataAsUTF8String.EndsWith(dataStart)) - return rdte.DataEntry; - } - else - { - var manifest = FindResourceInTable(rdte.Subdirectory, dataStart, dataContains, dataEnd); - if (manifest != null) - return manifest; - } - } - } - catch { } - - return null; - } - - /// - /// Get the assembly version as determined by an embedded assembly manifest - /// - /// Description string, null on error - private string GetManifestDescription() - { - // If we don't have a complete PE executable, just return null - if (this.ResourceSection == null) - return null; - - // Read in the manifest to a string - string manifestString = FindAssemblyManifest(); - if (string.IsNullOrWhiteSpace(manifestString)) - return null; - - // Try to read the XML in from the string - try - { - // Try to read the assembly - var assemblyNode = GetAssemblyNode(manifestString); - if (assemblyNode == null) - return null; - - // Return the content of the description node, if possible - var descriptionNode = assemblyNode["description"]; - if (descriptionNode == null) - return null; - - return descriptionNode.InnerXml; - } - catch - { - return null; - } - } - - /// - /// Get the assembly version as determined by an embedded assembly manifest - /// - /// Version string, null on error - private string GetManifestVersion() - { - // If we don't have a complete PE executable, just return null - if (this.ResourceSection == null) - return null; - - // Read in the manifest to a string - string manifestString = FindAssemblyManifest(); - if (string.IsNullOrWhiteSpace(manifestString)) - return null; - - // Try to read the XML in from the string - try - { - // Try to read the assembly - var assemblyNode = GetAssemblyNode(manifestString); - if (assemblyNode == null) - return null; - - // Try to read the assemblyIdentity - var assemblyIdentityNode = assemblyNode["assemblyIdentity"]; - if (assemblyIdentityNode == null) - return null; - - // Return the version attribute, if possible - return assemblyIdentityNode.GetAttribute("version"); - } - catch - { - return null; - } - } - - /// - /// Get a resource string from the version info - /// - /// Original filename string, null on error - private string GetResourceString(string key) - { - var resourceStrings = GetVersionInfo()?.ChildrenStringFileInfo?.Children?.Children; - if (resourceStrings == null) - return null; - - var value = resourceStrings.FirstOrDefault(s => s.Key == key); - if (!string.IsNullOrWhiteSpace(value?.Value)) - return value.Value.Trim(' ', '\0'); - - return null; - } - - /// - /// Get the version info object related to file contents, if possible - /// - /// VersionInfo object on success, null on error - private VersionInfo GetVersionInfo() - { - // If we don't have a complete PE executable, just return null - if (this.ResourceSection == null) - return null; - - // Try to get the matching resource - var resource = FindResource(dataContains: "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0"); - if (resource?.Data == null) - return null; - - try - { - int index = 0; - return VersionInfo.Deserialize(resource.Data, ref index); - } - catch (Exception ex) - { - // Console.WriteLine(ex); - return null; - } - } - - /// - /// Populate all resource strings - /// - private void PopulateResourceStrings() - { - // Standalone resource strings - this.CompanyName = GetResourceString("CompanyName"); - this.FileDescription = GetResourceString("FileDescription"); - this.FileVersion = GetResourceString("FileVersion")?.Replace(", ", "."); - this.InternalName = GetResourceString("InternalName"); - this.LegalCopyright = GetResourceString("LegalCopyright"); - this.LegalTrademarks = GetResourceString("LegalTrademarks"); - this.OriginalFileName = GetResourceString("OriginalFileName"); - this.ProductName = GetResourceString("ProductName"); - this.ProductVersion = GetResourceString("ProductVersion")?.Replace(", ", "."); - - // TODO: Make these combined calls more efficient - // Manifest resource strings - this.ManifestDescription = GetManifestDescription(); - this.ManifestVersion = GetManifestVersion(); - } - - #endregion - - #region Section Helpers - - /// - /// Determine if a section is contained within the section table - /// - /// Name of the section to check for - /// True to enable exact matching of names, false for starts-with - /// True if the section is in the executable, false otherwise - public bool ContainsSection(string sectionName, bool exact = false) - { - // Get all section names first - string[] sectionNames = GetSectionNames(); - if (sectionNames == null) - return false; - - // If we're checking exactly, return only exact matches - if (exact) - return sectionNames.Any(n => n.Equals(sectionName)); - - // Otherwise, check if section name starts with the value - else - return sectionNames.Any(n => n.StartsWith(sectionName)); - } - - /// - /// Convert a virtual address to a physical one - /// - /// Virtual address to convert - /// Array of sections to check against - /// Physical address, 0 on error - public static uint ConvertVirtualAddress(uint virtualAddress, SectionHeader[] sections) - { - // Loop through all of the sections - for (int i = 0; i < sections.Length; i++) - { - // If the section is invalid, just skip it - if (sections[i] == null) - continue; - - // If the section "starts" at 0, just skip it - if (sections[i].PointerToRawData == 0) - continue; - - // Attempt to derive the physical address from the current section - var section = sections[i]; - if (virtualAddress >= section.VirtualAddress && virtualAddress <= section.VirtualAddress + section.VirtualSize) - return section.PointerToRawData + virtualAddress - section.VirtualAddress; - } - - return 0; - } - - /// - /// Get the first section based on name, if possible - /// - /// Name of the section to check for - /// True to enable exact matching of names, false for starts-with - /// Section data on success, null on error - public SectionHeader GetFirstSection(string sectionName, bool exact = false) - { - // If we have no sections, we can't do anything - if (SectionTable == null || !SectionTable.Any()) - return null; - - // If we're checking exactly, return only exact matches - if (exact) - return SectionTable.FirstOrDefault(s => s.NameString.Equals(sectionName)); - - // Otherwise, check if section name starts with the value - else - return SectionTable.FirstOrDefault(s => s.NameString.StartsWith(sectionName)); - } - - /// - /// Get the last section based on name, if possible - /// - /// Name of the section to check for - /// True to enable exact matching of names, false for starts-with - /// Section data on success, null on error - public SectionHeader GetLastSection(string sectionName, bool exact = false) - { - // If we have no sections, we can't do anything - if (SectionTable == null || !SectionTable.Any()) - return null; - - // If we're checking exactly, return only exact matches (with nulls trimmed) - if (exact) - return SectionTable.LastOrDefault(s => s.NameString.Equals(sectionName)); - - // Otherwise, check if section name starts with the value - else - return SectionTable.LastOrDefault(s => s.NameString.StartsWith(sectionName)); - } - - /// - /// Get the list of section names - /// - public string[] GetSectionNames() - { - // Invalid table means no names are accessible - if (SectionTable == null || SectionTable.Length == 0) - return null; - - return SectionTable.Select(s => s.NameString).ToArray(); - } - - /// - /// Print all sections, including their start and end addresses - /// - public void PrintAllSections() - { - foreach (var section in SectionTable) - { - string sectionName = section.NameString; - int sectionAddr = (int)section.PointerToRawData; - int sectionEnd = sectionAddr + (int)section.VirtualSize; - Console.WriteLine($"{sectionName}: {sectionAddr} -> {sectionEnd}"); - } - } - - /// - /// 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 - /// - public byte[] ReadArbitraryRange(int rangeStart = -1, int length = -1) - { - try - { - // If we have a source stream, use that - if (this._sourceStream != null) - return ReadArbitraryRangeFromSourceStream(rangeStart, length); - - // If we have a source array, use that - if (this._sourceArray != null) - return ReadArbitraryRangeFromSourceArray(rangeStart, length); - - // Otherwise, return null - return null; - } - catch (Exception ex) - { - // TODO: How to handle this differently? - return null; - } - } - - /// - /// Read an arbitrary range from the stream source, if possible - /// - /// The start of where to read data from, -1 means start of source - /// How many bytes to read, -1 means read until end - /// - private byte[] ReadArbitraryRangeFromSourceStream(int rangeStart, int length) - { - lock (this._sourceStream) - { - int startingIndex = (int)Math.Max(rangeStart, 0); - int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this._sourceStream.Length); - - long originalPosition = this._sourceStream.Position; - this._sourceStream.Seek(startingIndex, SeekOrigin.Begin); - byte[] sectionData = this._sourceStream.ReadBytes(readLength); - this._sourceStream.Seek(originalPosition, SeekOrigin.Begin); - return sectionData; - } - } - - /// - /// Read an arbitrary range from the array source, if possible - /// - /// The start of where to read data from, -1 means start of source - /// How many bytes to read, -1 means read until end - /// - private byte[] ReadArbitraryRangeFromSourceArray(int rangeStart, int length) - { - int startingIndex = (int)Math.Max(rangeStart, 0); - int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this._sourceArray.Length); - - try - { - return this._sourceArray.ReadBytes(ref startingIndex, readLength); - } - catch - { - // Just absorb errors for now - // TODO: Investigate why and when this would be hit - return null; - } - } - - /// - /// Get the raw bytes from a section, if possible - /// - /// The name of the section to attempt to read - /// True to force reading the section from the underlying source, false to use cached values, if possible - /// True to use the first section with a matching name, false to use the last section - /// Offset to start reading at, default is 0 - public byte[] ReadRawSection(string sectionName, bool force = false, bool first = true, int offset = 0) - { - // Special cases for non-forced, non-offset data - if (!force && offset == 0) - { - switch (sectionName) - { - case ".data": - return DataSectionRaw; - case ".edata": - return ExportDataSectionRaw; - case ".idata": - return ImportDataSectionRaw; - case ".rdata": - return ResourceDataSectionRaw; - case ".text": - return TextSectionRaw; - } - } - - // Get the section, if possible - var section = first ? GetFirstSection(sectionName, true) : GetLastSection(sectionName, true); - if (section == null) - return null; - - // Return the raw data from that section - int rangeStart = (int)(section.PointerToRawData + offset); - int rangeEnd = (int)(section.VirtualSize - offset); - return ReadArbitraryRange(rangeStart, rangeEnd); - } - - #endregion - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs deleted file mode 100644 index f63bef74..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// The .debug section is used in object files to contain compiler-generated debug information and in image files to contain - /// all of the debug information that is generated. - /// This section describes the packaging of debug information in object and image files. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-debug-section - public class DebugSection - { - /// - /// Image files contain an optional debug directory that indicates what form of debug information is present and where it is. - /// This directory consists of an array of debug directory entries whose location and size are indicated in the image optional header. - /// - public DebugDirectory DebugDirectory; - - public static DebugSection Deserialize(Stream stream) - { - long originalPosition = stream.Position; - var ds = new DebugSection(); - - ds.DebugDirectory = DebugDirectory.Deserialize(stream); - - // TODO: Read in raw debug data - - stream.Seek(originalPosition, SeekOrigin.Begin); - return ds; - } - - public static DebugSection Deserialize(byte[] content, ref int offset) - { - int originalPosition = offset; - var ds = new DebugSection(); - - ds.DebugDirectory = DebugDirectory.Deserialize(content, ref offset); - - // TODO: Read in raw debug data - - offset = originalPosition; - return ds; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExceptionHandlingSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExceptionHandlingSection.cs deleted file mode 100644 index 379a3df4..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExceptionHandlingSection.cs +++ /dev/null @@ -1,19 +0,0 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// The .pdata section contains an array of function table entries that are used for exception handling. - /// It is pointed to by the exception table entry in the image data directory. - /// The entries must be sorted according to the function addresses (the first field in each structure) before being emitted into the final image. - /// The target platform determines which of the three function table entry format variations described below is used. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-edata-section-image-only - public class ExceptionHandlingSection - { - /// - /// Array of function table entries that are used for exception handling - /// - public FunctionTable FunctionTable; - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExportDataSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExportDataSection.cs deleted file mode 100644 index f1ffbd97..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ExportDataSection.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// The export data section, named .edata, contains information about symbols that other images can access through dynamic linking. - /// Exported symbols are generally found in DLLs, but DLLs can also import symbols. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-edata-section-image-only - public class ExportDataSection - { - /// - /// A table with just one row (unlike the debug directory). - /// This table indicates the locations and sizes of the other export tables. - /// - public ExportDirectoryTable ExportDirectoryTable; - - /// - /// An array of RVAs of exported symbols. - /// These are the actual addresses of the exported functions and data within the executable code and data sections. - /// Other image files can import a symbol by using an index to this table (an ordinal) or, optionally, by using the public name that corresponds to the ordinal if a public name is defined. - /// - public ExportAddressTableEntry[] ExportAddressTable; - - /// - /// An array of pointers to the public export names, sorted in ascending order. - /// - public uint[] ExportNamePointerTable; - - /// - /// An array of the ordinals that correspond to members of the name pointer table. - /// The correspondence is by position; therefore, the name pointer table and the ordinal table must have the same number of members. - /// Each ordinal is an index into the export address table. - /// - public ExportOrdinalTable OrdinalTable; - - public static ExportDataSection Deserialize(Stream stream, SectionHeader[] sections) - { - long originalPosition = stream.Position; - var eds = new ExportDataSection(); - - eds.ExportDirectoryTable = ExportDirectoryTable.Deserialize(stream); - - stream.Seek((int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.ExportAddressTableRVA, sections), SeekOrigin.Begin); - eds.ExportAddressTable = new ExportAddressTableEntry[(int)eds.ExportDirectoryTable.AddressTableEntries]; - for (int i = 0; i < eds.ExportAddressTable.Length; i++) - { - eds.ExportAddressTable[i] = ExportAddressTableEntry.Deserialize(stream, sections); - } - - stream.Seek((int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.NamePointerRVA, sections), SeekOrigin.Begin); - eds.ExportNamePointerTable = new uint[(int)eds.ExportDirectoryTable.NumberOfNamePointers]; - for (int i = 0; i < eds.ExportNamePointerTable.Length; i++) - { - eds.ExportNamePointerTable[i] = stream.ReadUInt32(); - } - - stream.Seek((int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.OrdinalTableRVA, sections), SeekOrigin.Begin); - // eds.OrdinalTable = ExportOrdinalTable.Deserialize(stream, count: 0); // TODO: Figure out where this count comes from - - return eds; - } - - public static ExportDataSection Deserialize(byte[] content, ref int offset, SectionHeader[] sections) - { - int originalPosition = offset; - var eds = new ExportDataSection(); - - eds.ExportDirectoryTable = ExportDirectoryTable.Deserialize(content, ref offset); - - offset = (int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.ExportAddressTableRVA, sections); - eds.ExportAddressTable = new ExportAddressTableEntry[(int)eds.ExportDirectoryTable.AddressTableEntries]; - for (int i = 0; i < eds.ExportAddressTable.Length; i++) - { - eds.ExportAddressTable[i] = ExportAddressTableEntry.Deserialize(content, ref offset, sections); - } - - offset = (int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.NamePointerRVA, sections); - eds.ExportNamePointerTable = new uint[(int)eds.ExportDirectoryTable.NumberOfNamePointers]; - for (int i = 0; i < eds.ExportNamePointerTable.Length; i++) - { - eds.ExportNamePointerTable[i] = content.ReadUInt32(ref offset); - } - - offset = (int)PortableExecutable.ConvertVirtualAddress(eds.ExportDirectoryTable.OrdinalTableRVA, sections); - // eds.OrdinalTable = ExportOrdinalTable.Deserialize(content, ref offset, count: 0); // TODO: Figure out where this count comes from - - return eds; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ImportDataSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ImportDataSection.cs deleted file mode 100644 index 180b74c4..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ImportDataSection.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// All image files that import symbols, including virtually all executable (EXE) files, have an .idata section. - /// A typical file layout for the import information follows: - /// Directory Table - /// Null Directory Entry - /// DLL1 Import Lookup Table - /// Null - /// DLL2 Import Lookup Table - /// Null - /// DLL3 Import Lookup Table - /// Null - /// Hint-Name Table - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-idata-section - public class ImportDataSection - { - /// - /// Import directory table - /// - public ImportDirectoryTable ImportDirectoryTable; - - /// - /// Import lookup tables - /// - public ImportLookupTable[] ImportLookupTables; - - /// - /// Hint/Name table - /// - public HintNameTable HintNameTable; - - public static ImportDataSection Deserialize(Stream stream, bool pe32plus, int hintCount) - { - var ids = new ImportDataSection(); - - ids.ImportDirectoryTable = ImportDirectoryTable.Deserialize(stream); - - List tempLookupTables = new List(); - while (true) - { - var tempLookupTable = ImportLookupTable.Deserialize(stream, pe32plus); - if (tempLookupTable.EntriesPE32 == null && tempLookupTable.EntriesPE32Plus == null) - break; - - tempLookupTables.Add(tempLookupTable); - } - - ids.HintNameTable = HintNameTable.Deserialize(stream, hintCount); - - return ids; - } - - public static ImportDataSection Deserialize(byte[] content, ref int offset, bool pe32plus, int hintCount) - { - var ids = new ImportDataSection(); - - ids.ImportDirectoryTable = ImportDirectoryTable.Deserialize(content, ref offset); - - List tempLookupTables = new List(); - while (true) - { - var tempLookupTable = ImportLookupTable.Deserialize(content, ref offset, pe32plus); - if (tempLookupTable.EntriesPE32 == null && tempLookupTable.EntriesPE32Plus == null) - break; - - tempLookupTables.Add(tempLookupTable); - } - - ids.HintNameTable = HintNameTable.Deserialize(content, ref offset, hintCount); - - return ids; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs deleted file mode 100644 index bd7e82b6..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// The base relocation table contains entries for all base relocations in the image. - /// The Base Relocation Table field in the optional header data directories gives the number of bytes in the base relocation table. - /// The base relocation table is divided into blocks. - /// Each block represents the base relocations for a 4K page. - /// Each block must start on a 32-bit boundary. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-reloc-section-image-only - public class RelocationSection - { - /// - /// The base relocation table is divided into blocks. - /// - public BaseRelocationBlock[] BaseRelocationTable; - - public static RelocationSection Deserialize(Stream stream, int blockCount) - { - long originalPosition = stream.Position; - - var rs = new RelocationSection(); - rs.BaseRelocationTable = new BaseRelocationBlock[blockCount]; - for (int i = 0; i < blockCount; i++) - { - rs.BaseRelocationTable[i] = BaseRelocationBlock.Deserialize(stream); - } - - stream.Seek(originalPosition, SeekOrigin.Begin); - return rs; - } - - public static RelocationSection Deserialize(byte[] content, ref int offset, int blockCount) - { - int originalPosition = offset; - - var rs = new RelocationSection(); - rs.BaseRelocationTable = new BaseRelocationBlock[blockCount]; - for (int i = 0; i < blockCount; i++) - { - rs.BaseRelocationTable[i] = BaseRelocationBlock.Deserialize(content, ref offset); - } - - offset = originalPosition; - return rs; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ResourceSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ResourceSection.cs deleted file mode 100644 index 0c5bc7aa..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/ResourceSection.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.ExecutableType.Microsoft.PE.Tables; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections -{ - /// - /// A series of resource directory tables relates all of the levels in the following way: - // Each directory table is followed by a series of directory entries that give the name or - // identifier (ID) for that level (Type, Name, or Language level) and an address of either - // a data description or another directory table. If the address points to a data description, - // then the data is a leaf in the tree. If the address points to another directory table, - // then that table lists directory entries at the next level down - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-rsrc-section - public class ResourceSection - { - /// - /// A table with just one row (unlike the debug directory). - /// This table indicates the locations and sizes of the other export tables. - /// - public ResourceDirectoryTable ResourceDirectoryTable; - - public static ResourceSection Deserialize(Stream stream, SectionHeader[] sections) - { - var rs = new ResourceSection(); - - long sectionStart = stream.Position; - rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(stream, sectionStart, sections); - - return rs; - } - - public static ResourceSection Deserialize(byte[] content, ref int offset, SectionHeader[] sections) - { - var rs = new ResourceSection(); - - long sectionStart = offset; - rs.ResourceDirectoryTable = ResourceDirectoryTable.Deserialize(content, ref offset, sectionStart, sections); - - return rs; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/DebugDirectory.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/DebugDirectory.cs deleted file mode 100644 index 8809202d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/DebugDirectory.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// Image files contain an optional debug directory that indicates what form of debug information is present and where it is. - /// This directory consists of an array of debug directory entries whose location and size are indicated in the image optional header. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#debug-directory-image-only - public class DebugDirectory - { - /// - /// Reserved, must be 0. - /// - public uint Characteristics; - - /// - /// The time and date that the debug data was created. - /// - public uint TimeDateStamp; - - /// - /// The major version number of the debug data format. - /// - public ushort MajorVersion; - - /// - /// The minor version number of the debug data format. - /// - public ushort MinorVersion; - - /// - /// The format of debugging information. This field enables support of multiple debuggers. - /// - public DebugType DebugType; - - /// - /// The size of the debug data (not including the debug directory itself). - /// - public uint SizeOfData; - - /// - /// The address of the debug data when loaded, relative to the image base. - /// - public uint AddressOfRawData; - - /// - /// The file pointer to the debug data. - /// - public uint PointerToRawData; - - public static DebugDirectory Deserialize(Stream stream) - { - var dd = new DebugDirectory(); - - dd.Characteristics = stream.ReadUInt32(); - dd.TimeDateStamp = stream.ReadUInt32(); - dd.MajorVersion = stream.ReadUInt16(); - dd.MinorVersion = stream.ReadUInt16(); - dd.DebugType = (DebugType)stream.ReadUInt32(); - dd.SizeOfData = stream.ReadUInt32(); - dd.AddressOfRawData = stream.ReadUInt32(); - dd.PointerToRawData = stream.ReadUInt32(); - - return dd; - } - - public static DebugDirectory Deserialize(byte[] content, ref int offset) - { - var dd = new DebugDirectory(); - - dd.Characteristics = content.ReadUInt32(ref offset); - dd.TimeDateStamp = content.ReadUInt32(ref offset); - dd.MajorVersion = content.ReadUInt16(ref offset); - dd.MinorVersion = content.ReadUInt16(ref offset); - dd.DebugType = (DebugType)content.ReadUInt32(ref offset); - dd.SizeOfData = content.ReadUInt32(ref offset); - dd.AddressOfRawData = content.ReadUInt32(ref offset); - dd.PointerToRawData = content.ReadUInt32(ref offset); - - return dd; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportDirectoryTable.cs deleted file mode 100644 index e9880e6a..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportDirectoryTable.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// The export symbol information begins with the export directory table, which describes the remainder of the export symbol information. - /// The export directory table contains address information that is used to resolve imports to the entry points within this image. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#export-directory-table - public class ExportDirectoryTable - { - /// - /// Reserved, must be 0. - /// - public uint ExportFlags; - - /// - /// The time and date that the export data was created. - /// - public uint TimeDateStamp; - - /// - /// The major version number. The major and minor version numbers can be set by the user. - /// - public ushort MajorVersion; - - /// - /// The minor version number. - /// - public ushort MinorVersion; - - /// - /// The address of the ASCII string that contains the name of the DLL. - /// This address is relative to the image base. - /// - public uint NameRVA; // TODO: Read this into a separate field - - /// - /// The starting ordinal number for exports in this image. - /// This field specifies the starting ordinal number for the export address table. - /// It is usually set to 1. - /// - public uint OrdinalBase; - - /// - /// The number of entries in the export address table. - /// - public uint AddressTableEntries; - - /// - /// The number of entries in the name pointer table. - /// This is also the number of entries in the ordinal table. - /// - public uint NumberOfNamePointers; - - /// - /// The address of the export address table, relative to the image base. - /// - public uint ExportAddressTableRVA; - - /// - /// The address of the export name pointer table, relative to the image base. - /// The table size is given by the Number of Name Pointers field. - /// - public uint NamePointerRVA; - - /// - /// The address of the ordinal table, relative to the image base. - /// - public uint OrdinalTableRVA; - - public static ExportDirectoryTable Deserialize(Stream stream) - { - var edt = new ExportDirectoryTable(); - - edt.ExportFlags = stream.ReadUInt32(); - edt.TimeDateStamp = stream.ReadUInt32(); - edt.MajorVersion = stream.ReadUInt16(); - edt.MinorVersion = stream.ReadUInt16(); - edt.NameRVA = stream.ReadUInt32(); - edt.OrdinalBase = stream.ReadUInt32(); - edt.AddressTableEntries = stream.ReadUInt32(); - edt.NumberOfNamePointers = stream.ReadUInt32(); - edt.ExportAddressTableRVA = stream.ReadUInt32(); - edt.NamePointerRVA = stream.ReadUInt32(); - edt.OrdinalTableRVA = stream.ReadUInt32(); - - return edt; - } - - public static ExportDirectoryTable Deserialize(byte[] content, ref int offset) - { - var edt = new ExportDirectoryTable(); - - edt.ExportFlags = content.ReadUInt32(ref offset); - edt.TimeDateStamp = content.ReadUInt32(ref offset); - edt.MajorVersion = content.ReadUInt16(ref offset); - edt.MinorVersion = content.ReadUInt16(ref offset); - edt.NameRVA = content.ReadUInt32(ref offset); - edt.OrdinalBase = content.ReadUInt32(ref offset); - edt.AddressTableEntries = content.ReadUInt32(ref offset); - edt.NumberOfNamePointers = content.ReadUInt32(ref offset); - edt.ExportAddressTableRVA = content.ReadUInt32(ref offset); - edt.NamePointerRVA = content.ReadUInt32(ref offset); - edt.OrdinalTableRVA = content.ReadUInt32(ref offset); - - return edt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportOrdinalTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportOrdinalTable.cs deleted file mode 100644 index ee0fa62d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ExportOrdinalTable.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// The export ordinal table is an array of 16-bit unbiased indexes into the export address table. - /// Ordinals are biased by the Ordinal Base field of the export directory table. - /// In other words, the ordinal base must be subtracted from the ordinals to obtain true indexes into the export address table. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#export-ordinal-table - public class ExportOrdinalTable - { - /// Number of entries is defined externally - public ushort[] Entries; - - public static ExportOrdinalTable Deserialize(Stream stream, int count) - { - var edt = new ExportOrdinalTable(); - - edt.Entries = new ushort[count]; - for (int i = 0; i < count; i++) - { - edt.Entries[i] = stream.ReadUInt16(); - } - - return edt; - } - - public static ExportOrdinalTable Deserialize(byte[] content, ref int offset, int count) - { - var edt = new ExportOrdinalTable(); - - edt.Entries = new ushort[count]; - for (int i = 0; i < count; i++) - { - edt.Entries[i] = content.ReadUInt16(ref offset); - } - - return edt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/FunctionTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/FunctionTable.cs deleted file mode 100644 index 1439272d..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/FunctionTable.cs +++ /dev/null @@ -1,17 +0,0 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// The .pdata section contains an array of function table entries that are used for exception handling. - /// It is pointed to by the exception table entry in the image data directory. - /// The entries must be sorted according to the function addresses (the first field in each structure) before being emitted into the final image. - /// The target platform determines which of the three function table entry format variations described below is used. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-pdata-section - public class FunctionTable - { - /// Number of entries is defined externally - public FunctionTableEntry[] Entries; - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/HintNameTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/HintNameTable.cs deleted file mode 100644 index caa2b9a4..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/HintNameTable.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// One hint/name table suffices for the entire import section. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#hintname-table - public class HintNameTable - { - /// Number of entries is defined externally - public HintNameTableEntry[] Entries; - - public static HintNameTable Deserialize(Stream stream, int count) - { - var hnt = new HintNameTable(); - - hnt.Entries = new HintNameTableEntry[count]; - for (int i = 0; i < count; i++) - { - hnt.Entries[i] = HintNameTableEntry.Deserialize(stream); - } - - return hnt; - } - - public static HintNameTable Deserialize(byte[] content, ref int offset, int count) - { - var hnt = new HintNameTable(); - - hnt.Entries = new HintNameTableEntry[count]; - for (int i = 0; i < count; i++) - { - hnt.Entries[i] = HintNameTableEntry.Deserialize(content, ref offset); - offset += 2 + hnt.Entries[i].Name.Length + hnt.Entries[i].Pad; - } - - return hnt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportAddressTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportAddressTable.cs deleted file mode 100644 index 87923c33..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportAddressTable.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// The structure and content of the import address table are identical to those of the import lookup table, until the file is bound. - /// During binding, the entries in the import address table are overwritten with the 32-bit (for PE32) or 64-bit (for PE32+) addresses of the symbols that are being imported. - /// These addresses are the actual memory addresses of the symbols, although technically they are still called "virtual addresses." - /// The loader typically processes the binding. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table - public class ImportAddressTable - { - /// Number of entries is known after parsing - public ImportAddressTableEntry[] Entries; - - public static ImportAddressTable Deserialize(Stream stream) - { - var iat = new ImportAddressTable(); - - List tempEntries = new List(); - while (true) - { - var entry = ImportAddressTableEntry.Deserialize(stream); - tempEntries.Add(entry); - if (entry.IsNull()) - break; - } - - iat.Entries = tempEntries.ToArray(); - return iat; - } - - public static ImportAddressTable Deserialize(byte[] content, ref int offset) - { - var iat = new ImportAddressTable(); - - List tempEntries = new List(); - while (true) - { - var entry = ImportAddressTableEntry.Deserialize(content, ref offset); - tempEntries.Add(entry); - if (entry.IsNull()) - break; - } - - iat.Entries = tempEntries.ToArray(); - return iat; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportDirectoryTable.cs deleted file mode 100644 index dcf862b9..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportDirectoryTable.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// The import information begins with the import directory table, which describes the remainder of the import information. - /// The import directory table contains address information that is used to resolve fixup references to the entry points within a DLL image. - /// The import directory table consists of an array of import directory entries, one entry for each DLL to which the image refers. - /// The last directory entry is empty (filled with null values), which indicates the end of the directory table. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-directory-table - public class ImportDirectoryTable - { - /// Number of entries is known after parsing - public ImportDirectoryTableEntry[] Entries; - - public static ImportDirectoryTable Deserialize(Stream stream) - { - var idt = new ImportDirectoryTable(); - - List tempEntries = new List(); - while (true) - { - var entry = ImportDirectoryTableEntry.Deserialize(stream); - tempEntries.Add(entry); - if (entry.IsNull()) - break; - } - - idt.Entries = tempEntries.ToArray(); - return idt; - } - - public static ImportDirectoryTable Deserialize(byte[] content, ref int offset) - { - var idt = new ImportDirectoryTable(); - - List tempEntries = new List(); - while (true) - { - var entry = ImportDirectoryTableEntry.Deserialize(content, ref offset); - tempEntries.Add(entry); - if (entry.IsNull()) - break; - } - - idt.Entries = tempEntries.ToArray(); - return idt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportLookupTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportLookupTable.cs deleted file mode 100644 index aa0c4c65..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ImportLookupTable.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// An import lookup table is an array of 32-bit numbers for PE32 or an array of 64-bit numbers for PE32+. - /// Each entry uses the bit-field format that is described in the following table. - /// In this format, bit 31 is the most significant bit for PE32 and bit 63 is the most significant bit for PE32+. - /// The collection of these entries describes all imports from a given DLL. - /// The last entry is set to zero (NULL) to indicate the end of the table. - /// - /// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-lookup-table - public class ImportLookupTable - { - /// Number of entries is known after parsing - public uint[] EntriesPE32; - - /// Number of entries is known after parsing - public ulong[] EntriesPE32Plus; - - public static ImportLookupTable Deserialize(Stream stream, bool pe32plus) - { - var ilt = new ImportLookupTable(); - - // PE32+ has 8-byte values - if (pe32plus) - { - List tempEntries = new List(); - while (true) - { - ulong bitfield = stream.ReadUInt64(); - tempEntries.Add(bitfield); - if (bitfield == 0) - break; - } - - if (tempEntries.Count > 0) - ilt.EntriesPE32Plus = tempEntries.ToArray(); - } - else - { - List tempEntries = new List(); - while (true) - { - uint bitfield = stream.ReadUInt32(); - tempEntries.Add(bitfield); - if (bitfield == 0) - break; - } - - if (tempEntries.Count > 0) - ilt.EntriesPE32 = tempEntries.ToArray(); - } - - return ilt; - } - - public static ImportLookupTable Deserialize(byte[] content, ref int offset, bool pe32plus) - { - var ilt = new ImportLookupTable(); - - // PE32+ has 8-byte values - if (pe32plus) - { - List tempEntries = new List(); - while (true) - { - ulong bitfield = content.ReadUInt64(ref offset); - tempEntries.Add(bitfield); - if (bitfield == 0) - break; - } - - if (tempEntries.Count > 0) - ilt.EntriesPE32Plus = tempEntries.ToArray(); - } - else - { - List tempEntries = new List(); - while (true) - { - uint bitfield = content.ReadUInt32(ref offset); - tempEntries.Add(bitfield); - if (bitfield == 0) - break; - } - - if (tempEntries.Count > 0) - ilt.EntriesPE32 = tempEntries.ToArray(); - } - - return ilt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ResourceDirectoryTable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ResourceDirectoryTable.cs deleted file mode 100644 index e3a0e650..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/PE/Tables/ResourceDirectoryTable.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE.Entries; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.PE.Tables -{ - /// - /// Each resource directory table has the following format. - /// This data structure should be considered the heading of a table - /// because the table actually consists of directory entries and this structure - /// - public class ResourceDirectoryTable - { - /// - /// Resource flags. - /// This field is reserved for future use. - /// It is currently set to zero. - /// - public uint Characteristics; - - /// - /// The time that the resource data was created by the resource compiler. - /// - public uint TimeDateStamp; - - /// - /// The major version number, set by the user. - /// - public ushort MajorVersion; - - /// - /// The minor version number, set by the user. - /// - public ushort MinorVersion; - - /// - /// The number of directory entries immediately following - /// the table that use strings to identify Type, Name, or - /// Language entries (depending on the level of the table). - /// - public ushort NumberOfNamedEntries; - - /// - /// The number of directory entries immediately following - /// the Name entries that use numeric IDs for Type, Name, - /// or Language entries. - /// - public ushort NumberOfIdEntries; - - /// - /// The directory entries immediately following - /// the table that use strings to identify Type, Name, or - /// Language entries (depending on the level of the table). - /// - public ResourceDirectoryTableEntry[] NamedEntries; - - /// - /// The directory entries immediately following - /// the Name entries that use numeric IDs for Type, Name, - /// or Language entries. - /// - public ResourceDirectoryTableEntry[] IdEntries; - - public static ResourceDirectoryTable Deserialize(Stream stream, long sectionStart, SectionHeader[] sections) - { - var rdt = new ResourceDirectoryTable(); - - rdt.Characteristics = stream.ReadUInt32(); - rdt.TimeDateStamp = stream.ReadUInt32(); - rdt.MajorVersion = stream.ReadUInt16(); - rdt.MinorVersion = stream.ReadUInt16(); - rdt.NumberOfNamedEntries = stream.ReadUInt16(); - rdt.NumberOfIdEntries = stream.ReadUInt16(); - - rdt.NamedEntries = new ResourceDirectoryTableEntry[rdt.NumberOfNamedEntries]; - for (int i = 0; i < rdt.NumberOfNamedEntries; i++) - { - rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream, sectionStart, sections); - } - - rdt.IdEntries = new ResourceDirectoryTableEntry[rdt.NumberOfIdEntries]; - for (int i = 0; i < rdt.NumberOfIdEntries; i++) - { - rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(stream, sectionStart, sections); - } - - return rdt; - } - - public static ResourceDirectoryTable Deserialize(byte[] content, ref int offset, long sectionStart, SectionHeader[] sections) - { - var rdt = new ResourceDirectoryTable(); - - rdt.Characteristics = content.ReadUInt32(ref offset); - rdt.TimeDateStamp = content.ReadUInt32(ref offset); - rdt.MajorVersion = content.ReadUInt16(ref offset); - rdt.MinorVersion = content.ReadUInt16(ref offset); - rdt.NumberOfNamedEntries = content.ReadUInt16(ref offset); - rdt.NumberOfIdEntries = content.ReadUInt16(ref offset); - - rdt.NamedEntries = new ResourceDirectoryTableEntry[rdt.NumberOfNamedEntries]; - for (int i = 0; i < rdt.NumberOfNamedEntries; i++) - { - rdt.NamedEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, ref offset, sectionStart, sections); - } - - rdt.IdEntries = new ResourceDirectoryTableEntry[rdt.NumberOfIdEntries]; - for (int i = 0; i < rdt.NumberOfIdEntries; i++) - { - rdt.IdEntries[i] = ResourceDirectoryTableEntry.Deserialize(content, ref offset, sectionStart, sections); - } - - return rdt; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs deleted file mode 100644 index 04225e8a..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/FixedFileInfo.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class FixedFileInfo - { - /// - /// Contains the value 0xFEEF04BD. - /// This is used with the szKey member of the VS_VERSIONINFO structure when searching a file for the VS_FIXEDFILEINFO structure. - /// - public uint Signature; - - /// - /// The binary version number of this structure. - /// The high-order word of this member contains the major version number, and the low-order word contains the minor version number. - /// - public uint StrucVersion; - - /// - /// The most significant 32 bits of the file's binary version number. - /// This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons. - /// - public uint FileVersionMS; - - /// - /// The least significant 32 bits of the file's binary version number. - /// This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons. - /// - public uint FileVersionLS; - - /// - /// The most significant 32 bits of the binary version number of the product with which this file was distributed. - /// This member is used with dwProductVersionLS to form a 64-bit value used for numeric comparisons. - /// - public uint ProductVersionMS; - - /// - /// The least significant 32 bits of the binary version number of the product with which this file was distributed. - /// This member is used with dwProductVersionMS to form a 64-bit value used for numeric comparisons. - /// - public uint ProductVersionLS; - - /// - /// Contains a bitmask that specifies the valid bits in dwFileFlags. - /// A bit is valid only if it was defined when the file was created. - /// - public uint FileFlagsMask; - - /// - /// Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values. - /// - public FileInfoFileFlags FileFlags; - - /// - /// The operating system for which this file was designed. This member can be one of the following values. - /// - /// An application can combine these values to indicate that the file was designed for one operating system running on another. - /// The following dwFileOS values are examples of this, but are not a complete list. - /// - public FileInfoOS FileOS; - - /// - /// The general type of file. This member can be one of the following values. All other values are reserved. - /// - public FileInfoFileType FileType; - - /// - /// The function of the file. The possible values depend on the value of dwFileType. - /// For all values of dwFileType not described in the following list, dwFileSubtype is zero. - /// - /// If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values. - /// - /// If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values. - /// - /// If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block. - /// All dwFileSubtype values not listed here are reserved. - /// - public FileInfoFileSubtype FileSubtype; - - /// - /// The most significant 32 bits of the file's 64-bit binary creation date and time stamp. - /// - public uint FileDateMS; - - /// - /// The least significant 32 bits of the file's 64-bit binary creation date and time stamp. - /// - public uint FileDateLS; - - public static FixedFileInfo Deserialize(Stream stream) - { - FixedFileInfo ffi = new FixedFileInfo(); - - ushort temp; - while ((temp = stream.ReadUInt16()) == 0x0000); - stream.Seek(-2, SeekOrigin.Current); - - ffi.Signature = stream.ReadUInt32(); - ffi.StrucVersion = stream.ReadUInt32(); - ffi.FileVersionMS = stream.ReadUInt32(); - ffi.FileVersionLS = stream.ReadUInt32(); - ffi.ProductVersionMS = stream.ReadUInt32(); - ffi.ProductVersionLS = stream.ReadUInt32(); - ffi.FileFlagsMask = stream.ReadUInt32(); - ffi.FileFlags = (FileInfoFileFlags)stream.ReadUInt32(); - ffi.FileOS = (FileInfoOS)stream.ReadUInt32(); - ffi.FileType = (FileInfoFileType)stream.ReadUInt32(); - ffi.FileSubtype = (FileInfoFileSubtype)stream.ReadUInt32(); - ffi.FileDateMS = stream.ReadUInt32(); - ffi.FileDateLS = stream.ReadUInt32(); - - return ffi; - } - - public static FixedFileInfo Deserialize(byte[] content, ref int offset) - { - FixedFileInfo ffi = new FixedFileInfo(); - - ushort temp; - bool padded = false; - while ((temp = content.ReadUInt16(ref offset)) == 0x0000) - { - padded = true; - } - - if (padded) - offset -= 2; - - ffi.Signature = content.ReadUInt32(ref offset); - ffi.StrucVersion = content.ReadUInt32(ref offset); - ffi.FileVersionMS = content.ReadUInt32(ref offset); - ffi.FileVersionLS = content.ReadUInt32(ref offset); - ffi.ProductVersionMS = content.ReadUInt32(ref offset); - ffi.ProductVersionLS = content.ReadUInt32(ref offset); - ffi.FileFlagsMask = content.ReadUInt32(ref offset); - ffi.FileFlags = (FileInfoFileFlags)content.ReadUInt32(ref offset); - ffi.FileOS = (FileInfoOS)content.ReadUInt32(ref offset); - ffi.FileType = (FileInfoFileType)content.ReadUInt32(ref offset); - ffi.FileSubtype = (FileInfoFileSubtype)content.ReadUInt32(ref offset); - ffi.FileDateMS = content.ReadUInt32(ref offset); - ffi.FileDateLS = content.ReadUInt32(ref offset); - - return ffi; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs deleted file mode 100644 index 85385793..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/LanguageCodePage.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.IO; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - /// - /// If you use the Var structure to list the languages your application or DLL supports instead of using multiple version resources, - /// use the Value member to contain an array of DWORD values indicating the language and code page combinations supported by this file. - /// The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM code page number. - /// Either high-order or low-order word can be zero, indicating that the file is language or code page independent. - /// If the Var structure is omitted, the file will be interpreted as both language and code page independent. - /// - public class LanguageCodePage - { - /// - /// The low-order word of each DWORD must contain a Microsoft language identifier - /// - public ushort MicrosoftLanguageIdentifier; - - /// - /// The high-order word must contain the IBM code page number - /// - public ushort IBMCodePageNumber; - - public static LanguageCodePage Deserialize(Stream stream) - { - LanguageCodePage lcp = new LanguageCodePage(); - - lcp.MicrosoftLanguageIdentifier = stream.ReadUInt16(); - lcp.IBMCodePageNumber = stream.ReadUInt16(); - - return lcp; - } - - public static LanguageCodePage Deserialize(byte[] content, ref int offset) - { - LanguageCodePage lcp = new LanguageCodePage(); - - lcp.MicrosoftLanguageIdentifier = content.ReadUInt16(ref offset); - lcp.IBMCodePageNumber = content.ReadUInt16(ref offset); - - return lcp; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs deleted file mode 100644 index 2dc8fdf8..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/Resource.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class Resource - { - /// - /// The length, in bytes, of the resource structure. - /// This length does not include any padding that aligns any subsequent version resource data on a 32-bit boundary. - /// - public ushort Length; - - /// - /// The length, in bytes, of the Value member. - /// This value is zero if there is no Value member associated with the current version structure. - /// - public ushort ValueLength; - - /// - /// The type of data in the version resource. - /// This member is 1 if the version resource contains text data and 0 if the version resource contains binary data. - /// - public ushort Type; - - /// - /// A Unicode string representing the key - /// - public string Key; - - public static Resource Deserialize(Stream stream) - { - Resource r = new Resource(); - - while ((r.Length = stream.ReadUInt16()) == 0x0000); - - r.ValueLength = stream.ReadUInt16(); - r.Type = stream.ReadUInt16(); - r.Key = stream.ReadString(Encoding.Unicode); - - return r; - } - - public static Resource Deserialize(byte[] content, ref int offset) - { - Resource r = new Resource(); - - while ((r.Length = content.ReadUInt16(ref offset)) == 0x0000); - - r.ValueLength = content.ReadUInt16(ref offset); - r.Type = content.ReadUInt16(ref offset); - r.Key = content.ReadString(ref offset, Encoding.Unicode); - - return r; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs deleted file mode 100644 index e1ac39a6..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringFileInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.IO; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class StringFileInfo : Resource - { - /// - /// An array of one or more StringTable structures. - /// Each StringTable structure's szKey member indicates the appropriate language and code page for displaying the text in that StringTable structure. - /// - public StringTable Children; - - public StringFileInfo(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key?.TrimStart('\u0001') ?? default; - } - - public static new StringFileInfo Deserialize(Stream stream) - { - Resource resource = Resource.Deserialize(stream); - if (resource.Key != "StringFileInfo" && resource.Key != "\u0001StringFileInfo") - return null; - - StringFileInfo sfi = new StringFileInfo(resource); - sfi.Children = StringTable.Deserialize(stream); - - return sfi; - } - - public static new StringFileInfo Deserialize(byte[] content, ref int offset) - { - Resource resource = Resource.Deserialize(content, ref offset); - if (resource.Key != "StringFileInfo" && resource.Key != "\u0001StringFileInfo") - return null; - - StringFileInfo sfi = new StringFileInfo(resource); - sfi.Children = StringTable.Deserialize(content, ref offset); - - return sfi; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs deleted file mode 100644 index ce4c16dd..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringStruct.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.IO; -using System.Text; -using BurnOutSharp.Tools; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class StringStruct : Resource - { - /// - /// Typically contains a list of languages that the application or DLL supports. - /// - public string Value; - - public StringStruct(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key ?? default; - } - - public static new StringStruct Deserialize(Stream stream) - { - Resource resource = Resource.Deserialize(stream); - StringStruct s = new StringStruct(resource); - stream.Seek(stream.Position % 4 == 0 ? 0 : 4 - (stream.Position % 4), SeekOrigin.Current); - s.Value = new string(stream.ReadChars(s.ValueLength)); - - return s; - } - - public static new StringStruct Deserialize(byte[] content, ref int offset) - { - Resource resource = Resource.Deserialize(content, ref offset); - StringStruct s = new StringStruct(resource); - offset += offset % 4 == 0 ? 0 : 4 - (offset % 4); - s.Value = Encoding.Unicode.GetString(content, offset, s.ValueLength * 2); offset += s.ValueLength * 2; - - return s; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs deleted file mode 100644 index 7facdc24..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/StringTable.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class StringTable : Resource - { - /// - /// An array of one or more String structures. - /// - public StringStruct[] Children; - - public StringTable(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key ?? default; - } - - public static new StringTable Deserialize(Stream stream) - { - long originalPosition = stream.Position; - Resource resource = Resource.Deserialize(stream); - if (resource.Key.Length != 8) - return null; - - StringTable st = new StringTable(resource); - - var tempValue = new List(); - while (stream.Position - originalPosition < st.Length) - { - tempValue.Add(StringStruct.Deserialize(stream)); - } - - st.Children = tempValue.ToArray(); - - return st; - } - - public static new StringTable Deserialize(byte[] content, ref int offset) - { - int originalPosition = offset; - Resource resource = Resource.Deserialize(content, ref offset); - if (resource.Key.Length != 8) - return null; - - StringTable st = new StringTable(resource); - - var tempValue = new List(); - while (offset - originalPosition < st.Length) - { - tempValue.Add(StringStruct.Deserialize(content, ref offset)); - } - - st.Children = tempValue.ToArray(); - - return st; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs deleted file mode 100644 index 02de3861..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/Var.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class Var : Resource - { - /// - /// An array of one or more values that are language and code page identifier pairs. - /// - /// If you use the Var structure to list the languages your application or DLL supports instead of using multiple version resources, - /// use the Value member to contain an array of DWORD values indicating the language and code page combinations supported by this file. - /// The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM code page number. - /// Either high-order or low-order word can be zero, indicating that the file is language or code page independent. - /// If the Var structure is omitted, the file will be interpreted as both language and code page independent. - /// - public LanguageCodePage[] Value; - - public Var(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key ?? default; - } - - public static new Var Deserialize(Stream stream) - { - long originalPosition = stream.Position; - Resource resource = Resource.Deserialize(stream); - if (resource.Key != "Translation") - return null; - - Var v = new Var(resource); - - var tempValue = new List(); - while (stream.Position - originalPosition < v.Length) - { - tempValue.Add(LanguageCodePage.Deserialize(stream)); - } - - v.Value = tempValue.ToArray(); - - return v; - } - - public static new Var Deserialize(byte[] content, ref int offset) - { - int originalPosition = offset; - Resource resource = Resource.Deserialize(content, ref offset); - if (resource.Key != "Translation") - return null; - - Var v = new Var(resource); - - var tempValue = new List(); - while (offset - originalPosition < v.Length) - { - tempValue.Add(LanguageCodePage.Deserialize(content, ref offset)); - } - - v.Value = tempValue.ToArray(); - - return v; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs deleted file mode 100644 index 36395204..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/VarFileInfo.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class VarFileInfo : Resource - { - /// - /// Typically contains a list of languages that the application or DLL supports. - /// - public Var Children; - - public VarFileInfo(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key ?? default; - } - - public static new VarFileInfo Deserialize(Stream stream) - { - Resource resource = Resource.Deserialize(stream); - if (resource.Key != "VarFileInfo") - return null; - - VarFileInfo vfi = new VarFileInfo(resource); - vfi.Children = Var.Deserialize(stream); - - return vfi; - } - - public static new VarFileInfo Deserialize(byte[] content, ref int offset) - { - Resource resource = Resource.Deserialize(content, ref offset); - if (resource.Key != "VarFileInfo") - return null; - - VarFileInfo vfi = new VarFileInfo(resource); - vfi.Children = Var.Deserialize(content, ref offset); - - return vfi; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs b/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs deleted file mode 100644 index f5974eb9..00000000 --- a/BurnOutSharp/ExecutableType/Microsoft/Resources/VersionInfo.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.IO; - -namespace BurnOutSharp.ExecutableType.Microsoft.Resources -{ - public class VersionInfo : Resource - { - /// - /// Arbitrary data associated with this VS_VERSIONINFO structure. - /// The wValueLength member specifies the length of this member; - /// if wValueLength is zero, this member does not exist. - /// - public FixedFileInfo Value; - - /// - /// An array of zero or one StringFileInfo structures, and zero or one VarFileInfo structures - /// that are children of the current VS_VERSIONINFO structure. - /// - public StringFileInfo ChildrenStringFileInfo; - - /// - /// An array of zero or one StringFileInfo structures, and zero or one VarFileInfo structures - /// that are children of the current VS_VERSIONINFO structure. - /// - public VarFileInfo ChildrenVarFileInfo; - - public VersionInfo(Resource resource) - { - this.Length = resource?.Length ?? default; - this.ValueLength = resource?.ValueLength ?? default; - this.Type = resource?.Type ?? default; - this.Key = resource?.Key ?? default; - } - - public static new VersionInfo Deserialize(Stream stream) - { - long originalPosition = stream.Position; - Resource resource = Resource.Deserialize(stream); - if (resource.Key != "VS_VERSION_INFO") - return null; - - VersionInfo vi = new VersionInfo(resource); - - if (vi.ValueLength > 0) - vi.Value = FixedFileInfo.Deserialize(stream); - - if (stream.Position - originalPosition > vi.Length) - return vi; - - long preChildOffset = stream.Position; - Resource firstChild = Resource.Deserialize(stream); - if (firstChild.Key == "StringFileInfo" || firstChild.Key == "\u0001StringFileInfo") - { - stream.Seek(preChildOffset, SeekOrigin.Begin); - vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream); - } - else if (firstChild.Key == "VarFileInfo" || firstChild.Key == "\u0001VarFileInfo") - { - stream.Seek(preChildOffset, SeekOrigin.Begin); - vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream); - } - - if (stream.Position - originalPosition > vi.Length) - return vi; - - preChildOffset = stream.Position; - Resource secondChild = Resource.Deserialize(stream); - if (secondChild.Key == "StringFileInfo" || secondChild.Key == "\u0001StringFileInfo") - { - stream.Seek(preChildOffset, SeekOrigin.Begin); - vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(stream); - } - else if (secondChild.Key == "VarFileInfo" || secondChild.Key == "\u0001VarFileInfo") - { - stream.Seek(preChildOffset, SeekOrigin.Begin); - vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(stream); - } - - return vi; - } - - public static new VersionInfo Deserialize(byte[] content, ref int offset) - { - int originalOffset = offset; - Resource resource = Resource.Deserialize(content, ref offset); - if (resource.Key != "VS_VERSION_INFO") - return null; - - VersionInfo vi = new VersionInfo(resource); - - if (vi.ValueLength > 0) - vi.Value = FixedFileInfo.Deserialize(content, ref offset); - - if (offset - originalOffset > vi.Length) - return vi; - - int preChildOffset = offset; - Resource firstChild = Resource.Deserialize(content, ref offset); - if (firstChild.Key == "StringFileInfo" || firstChild.Key == "\u0001StringFileInfo") - { - offset = preChildOffset; - vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset); - } - else if (firstChild.Key == "VarFileInfo" || firstChild.Key == "\u0001VarFileInfo") - { - offset = preChildOffset; - vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset); - } - - if (offset - originalOffset > vi.Length) - return vi; - - - preChildOffset = offset; - Resource secondChild = Resource.Deserialize(content, ref offset); - if (secondChild.Key == "StringFileInfo" || secondChild.Key == "\u0001StringFileInfo") - { - offset = preChildOffset; - vi.ChildrenStringFileInfo = StringFileInfo.Deserialize(content, ref offset); - } - else if (secondChild.Key == "VarFileInfo" || secondChild.Key == "\u0001VarFileInfo") - { - offset = preChildOffset; - vi.ChildrenVarFileInfo = VarFileInfo.Deserialize(content, ref offset); - } - - return vi; - } - } -} \ No newline at end of file diff --git a/BurnOutSharp/FileType/Executable.cs b/BurnOutSharp/FileType/Executable.cs index 78197583..1e5aada6 100644 --- a/BurnOutSharp/FileType/Executable.cs +++ b/BurnOutSharp/FileType/Executable.cs @@ -3,10 +3,9 @@ using System.Collections.Concurrent; using System.IO; using System.Text; using System.Threading.Tasks; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.FileType { @@ -86,9 +85,9 @@ namespace BurnOutSharp.FileType // Create PortableExecutable and NewExecutable objects for use in the checks stream.Seek(0, SeekOrigin.Begin); - PortableExecutable pex = new PortableExecutable(stream); + PortableExecutable pex = PortableExecutable.Create(stream); stream.Seek(0, SeekOrigin.Begin); - NewExecutable nex = new NewExecutable(stream); + NewExecutable nex = NewExecutable.Create(stream); stream.Seek(0, SeekOrigin.Begin); // Iterate through all generic content checks @@ -114,7 +113,7 @@ namespace BurnOutSharp.FileType } // If we have a NE executable, iterate through all NE content checks - if (nex?.Initialized == true) + if (nex != null) { Parallel.ForEach(ScanningClasses.NewExecutableCheckClasses, contentCheckClass => { @@ -137,7 +136,7 @@ namespace BurnOutSharp.FileType } // If we have a PE executable, iterate through all PE content checks - if (pex?.Initialized == true) + if (pex != null) { // Print the section table for debug if (scanner.IncludeDebug && pex.SectionTable != null) diff --git a/BurnOutSharp/Interfaces/ILinearExecutableCheck.cs b/BurnOutSharp/Interfaces/ILinearExecutableCheck.cs index 09ef94ce..c4894eaa 100644 --- a/BurnOutSharp/Interfaces/ILinearExecutableCheck.cs +++ b/BurnOutSharp/Interfaces/ILinearExecutableCheck.cs @@ -1,4 +1,4 @@ -using BurnOutSharp.ExecutableType.Microsoft.LE; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.Interfaces { diff --git a/BurnOutSharp/Interfaces/INewExecutableCheck.cs b/BurnOutSharp/Interfaces/INewExecutableCheck.cs index 75888f6c..7c48d0d8 100644 --- a/BurnOutSharp/Interfaces/INewExecutableCheck.cs +++ b/BurnOutSharp/Interfaces/INewExecutableCheck.cs @@ -1,4 +1,4 @@ -using BurnOutSharp.ExecutableType.Microsoft.NE; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.Interfaces { diff --git a/BurnOutSharp/Interfaces/IPortableExecutableCheck.cs b/BurnOutSharp/Interfaces/IPortableExecutableCheck.cs index 2f7f73c6..a382bf70 100644 --- a/BurnOutSharp/Interfaces/IPortableExecutableCheck.cs +++ b/BurnOutSharp/Interfaces/IPortableExecutableCheck.cs @@ -1,4 +1,4 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.Interfaces { diff --git a/BurnOutSharp/PackerType/ASPack.cs b/BurnOutSharp/PackerType/ASPack.cs index b9bd4d96..a8d38152 100644 --- a/BurnOutSharp/PackerType/ASPack.cs +++ b/BurnOutSharp/PackerType/ASPack.cs @@ -1,9 +1,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Text; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -26,20 +27,21 @@ namespace BurnOutSharp.PackerType if (aspackSection) return "ASPack 2.29"; + // TODO: Re-enable all Entry Point checks after implementing // Use the entry point data, if it exists - if (pex.EntryPointRaw != null) - { - var matchers = GenerateMatchers(); - string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + // if (pex.EntryPointRaw != null) + // { + // var matchers = GenerateMatchers(); + // string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); + // if (!string.IsNullOrWhiteSpace(match)) + // return match; + // } // Get the .adata* section, if it exists var adataSection = pex.GetFirstSection(".adata", exact: false); if (adataSection != null) { - var adataSectionRaw = pex.ReadRawSection(adataSection.NameString); + var adataSectionRaw = pex.GetFirstSectionData(Encoding.UTF8.GetString(adataSection.Name)); if (adataSectionRaw != null) { var matchers = GenerateMatchers(); diff --git a/BurnOutSharp/PackerType/AdvancedInstaller.cs b/BurnOutSharp/PackerType/AdvancedInstaller.cs index fdf7f967..5c91ca4d 100644 --- a/BurnOutSharp/PackerType/AdvancedInstaller.cs +++ b/BurnOutSharp/PackerType/AdvancedInstaller.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -23,7 +23,7 @@ namespace BurnOutSharp.PackerType return null; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -38,7 +38,7 @@ namespace BurnOutSharp.PackerType }, "Caphyon Advanced Installer"), }; - return MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + return MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); } return null; diff --git a/BurnOutSharp/PackerType/Armadillo.cs b/BurnOutSharp/PackerType/Armadillo.cs index 0eaf458b..a4effae9 100644 --- a/BurnOutSharp/PackerType/Armadillo.cs +++ b/BurnOutSharp/PackerType/Armadillo.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -30,9 +30,9 @@ namespace BurnOutSharp.PackerType return "Armadillo"; // Loop through all "extension" sections -- usually .data1 or .text1 - foreach (var section in sections.Where(s => s != null && s.NameString.EndsWith("1"))) + foreach (var sectionName in pex.SectionNames.Where(s => s != null && s.EndsWith("1"))) { - var sectionRaw = pex.ReadRawSection(section.NameString); + var sectionRaw = pex.GetFirstSectionData(sectionName); if (sectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/PackerType/AutoPlayMediaStudio.cs b/BurnOutSharp/PackerType/AutoPlayMediaStudio.cs index 535da9cb..7f655e94 100644 --- a/BurnOutSharp/PackerType/AutoPlayMediaStudio.cs +++ b/BurnOutSharp/PackerType/AutoPlayMediaStudio.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { diff --git a/BurnOutSharp/PackerType/CExe.cs b/BurnOutSharp/PackerType/CExe.cs index dc69a1d8..20e156d2 100644 --- a/BurnOutSharp/PackerType/CExe.cs +++ b/BurnOutSharp/PackerType/CExe.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -20,8 +20,8 @@ namespace BurnOutSharp.PackerType public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible - var stub = pex?.DOSStubHeader; - if (stub == null) + var sections = pex?.SectionTable; + if (sections == null) return null; var matchers = new List @@ -37,7 +37,7 @@ namespace BurnOutSharp.PackerType }, "CExe") }; - string match = MatchUtil.GetFirstMatch(file, pex.DOSStubHeader.ExecutableData, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.StubExecutableData, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; diff --git a/BurnOutSharp/PackerType/EXEStealth.cs b/BurnOutSharp/PackerType/EXEStealth.cs index d0f45c63..1acd5787 100644 --- a/BurnOutSharp/PackerType/EXEStealth.cs +++ b/BurnOutSharp/PackerType/EXEStealth.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { diff --git a/BurnOutSharp/PackerType/GenteeInstaller.cs b/BurnOutSharp/PackerType/GenteeInstaller.cs index 7874c797..bd7cce79 100644 --- a/BurnOutSharp/PackerType/GenteeInstaller.cs +++ b/BurnOutSharp/PackerType/GenteeInstaller.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -22,8 +22,9 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -42,7 +43,7 @@ namespace BurnOutSharp.PackerType }, "Gentee Installer"), }; - return MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + return MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); } return null; diff --git a/BurnOutSharp/PackerType/InnoSetup.cs b/BurnOutSharp/PackerType/InnoSetup.cs index 0166cd96..b2bb50f3 100644 --- a/BurnOutSharp/PackerType/InnoSetup.cs +++ b/BurnOutSharp/PackerType/InnoSetup.cs @@ -4,10 +4,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -21,13 +20,12 @@ namespace BurnOutSharp.PackerType /// public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; // Check for "Inno" in the reserved words - if (stub.Reserved2[4] == 0x6E49 && stub.Reserved2[5] == 0x6F6E) + if (nex.Stub_Reserved2[4] == 0x6E49 && nex.Stub_Reserved2[5] == 0x6F6E) { string version = GetOldVersion(file, nex); if (!string.IsNullOrWhiteSpace(version)) @@ -46,9 +44,10 @@ namespace BurnOutSharp.PackerType var sections = pex?.SectionTable; if (sections == null) return null; - - // Get the DATA/.data section, if it exists - if (pex.DataSectionRaw != null) + + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -61,7 +60,7 @@ namespace BurnOutSharp.PackerType }, GetVersion, "Inno Setup"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } @@ -102,7 +101,7 @@ namespace BurnOutSharp.PackerType string version = Encoding.ASCII.GetString(onlyVersion); if (unicodeBytes.SequenceEqual(new byte[] { 0x28, 0x75, 0x29 })) - return (version + " (Unicode)"); + return version + " (Unicode)"; return version; } diff --git a/BurnOutSharp/PackerType/InstallAnywhere.cs b/BurnOutSharp/PackerType/InstallAnywhere.cs index 3fdbc236..2746c9c5 100644 --- a/BurnOutSharp/PackerType/InstallAnywhere.cs +++ b/BurnOutSharp/PackerType/InstallAnywhere.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { diff --git a/BurnOutSharp/PackerType/InstallerVISE.cs b/BurnOutSharp/PackerType/InstallerVISE.cs index 1484bd8c..bf3af477 100644 --- a/BurnOutSharp/PackerType/InstallerVISE.cs +++ b/BurnOutSharp/PackerType/InstallerVISE.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -23,8 +23,9 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - // Get the DATA/.data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -32,7 +33,7 @@ namespace BurnOutSharp.PackerType new ContentMatchSet(new byte?[] { 0x56, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Installer VISE"), }; - return MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + return MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); } return null; diff --git a/BurnOutSharp/PackerType/IntelInstallationFramework.cs b/BurnOutSharp/PackerType/IntelInstallationFramework.cs index c12870ee..a36674a4 100644 --- a/BurnOutSharp/PackerType/IntelInstallationFramework.cs +++ b/BurnOutSharp/PackerType/IntelInstallationFramework.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -22,17 +22,15 @@ namespace BurnOutSharp.PackerType return null; string name = pex.FileDescription; - if (!string.IsNullOrWhiteSpace(name) - && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) - || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) + if (name?.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true + || name?.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true) { return $"Intel Installation Framework {Utilities.GetInternalVersion(pex)}"; } name = pex.ProductName; - if (!string.IsNullOrWhiteSpace(name) - && (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) - || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase))) + if (name.Equals("Intel(R) Installation Framework", StringComparison.OrdinalIgnoreCase) == true + || name.Equals("Intel Installation Framework", StringComparison.OrdinalIgnoreCase) == true) { return $"Intel Installation Framework {Utilities.GetInternalVersion(pex)}"; } diff --git a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs index 4baf4651..7b90ef93 100644 --- a/BurnOutSharp/PackerType/MicrosoftCABSFX.cs +++ b/BurnOutSharp/PackerType/MicrosoftCABSFX.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -28,12 +28,13 @@ namespace BurnOutSharp.PackerType if (name?.Equals("Wextract", StringComparison.OrdinalIgnoreCase) == true) return $"Microsoft CAB SFX {GetVersion(pex)}"; - name = pex.OriginalFileName; + name = pex.OriginalFilename; if (name?.Equals("WEXTRACT.EXE", StringComparison.OrdinalIgnoreCase) == true) return $"Microsoft CAB SFX {GetVersion(pex)}"; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -45,13 +46,13 @@ namespace BurnOutSharp.PackerType }, "Microsoft CAB SFX"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return $"Microsoft CAB SFX {GetVersion(pex)}"; } // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -61,7 +62,7 @@ namespace BurnOutSharp.PackerType new ContentMatchSet(new byte?[] { 0x4D, 0x53, 0x43, 0x46, 0x75 }, "Microsoft CAB SFX"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return $"Microsoft CAB SFX {GetVersion(pex)}"; } diff --git a/BurnOutSharp/PackerType/NSIS.cs b/BurnOutSharp/PackerType/NSIS.cs index 8f718f16..01ad520b 100644 --- a/BurnOutSharp/PackerType/NSIS.cs +++ b/BurnOutSharp/PackerType/NSIS.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -21,12 +21,13 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - string description = pex.ManifestDescription; + string description = pex.AssemblyDescription; if (!string.IsNullOrWhiteSpace(description) && description.StartsWith("Nullsoft Install System")) return $"NSIS {description.Substring("Nullsoft Install System".Length).Trim()}"; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -38,7 +39,7 @@ namespace BurnOutSharp.PackerType }, "NSIS"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/PackerType/PECompact.cs b/BurnOutSharp/PackerType/PECompact.cs index 42cd4189..2ebc81a0 100644 --- a/BurnOutSharp/PackerType/PECompact.cs +++ b/BurnOutSharp/PackerType/PECompact.cs @@ -1,7 +1,7 @@ using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -21,7 +21,7 @@ namespace BurnOutSharp.PackerType return null; // 0x4F434550 is "PECO" - if (pex.ImageFileHeader.PointerToSymbolTable == 0x4F434550) + if (pex.PointerToSymbolTable == 0x4F434550) return "PE Compact v1.x"; // TODO: Get more granular version detection. PiD is somehow able to detect version ranges based diff --git a/BurnOutSharp/PackerType/Petite.cs b/BurnOutSharp/PackerType/Petite.cs index 3e98d8ea..9f56d994 100644 --- a/BurnOutSharp/PackerType/Petite.cs +++ b/BurnOutSharp/PackerType/Petite.cs @@ -1,7 +1,7 @@ using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -21,8 +21,8 @@ namespace BurnOutSharp.PackerType return null; // Get the .petite section, if it exists -- TODO: Is there a version number that can be found? - bool nicodeSection = pex.ContainsSection(".petite", exact: true); - if (nicodeSection) + bool petiteSection = pex.ContainsSection(".petite", exact: true); + if (petiteSection) return "PEtite"; return null; diff --git a/BurnOutSharp/PackerType/SetupFactory.cs b/BurnOutSharp/PackerType/SetupFactory.cs index f759cd88..c99365c9 100644 --- a/BurnOutSharp/PackerType/SetupFactory.cs +++ b/BurnOutSharp/PackerType/SetupFactory.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { diff --git a/BurnOutSharp/PackerType/Shrinker.cs b/BurnOutSharp/PackerType/Shrinker.cs index d72abde5..9add60ff 100644 --- a/BurnOutSharp/PackerType/Shrinker.cs +++ b/BurnOutSharp/PackerType/Shrinker.cs @@ -1,7 +1,7 @@ using System.Collections.Concurrent; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { diff --git a/BurnOutSharp/PackerType/UPX.cs b/BurnOutSharp/PackerType/UPX.cs index 47e2c807..ad191011 100644 --- a/BurnOutSharp/PackerType/UPX.cs +++ b/BurnOutSharp/PackerType/UPX.cs @@ -2,9 +2,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Text; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -116,7 +116,7 @@ namespace BurnOutSharp.PackerType return null; // This subtract is needed because the version is before the section - return pex.ReadRawSection($"{sectionPrefix}0", first: true, offset: -128); + return pex.GetFirstSectionDataWithOffset($"{sectionPrefix}0", offset: -128); } } } \ No newline at end of file diff --git a/BurnOutSharp/PackerType/WinRARSFX.cs b/BurnOutSharp/PackerType/WinRARSFX.cs index dcbf45b2..ba8ecae7 100644 --- a/BurnOutSharp/PackerType/WinRARSFX.cs +++ b/BurnOutSharp/PackerType/WinRARSFX.cs @@ -2,10 +2,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; using SharpCompress.Archives; using SharpCompress.Archives.Rar; @@ -24,8 +24,9 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -38,7 +39,7 @@ namespace BurnOutSharp.PackerType }, "WinRAR SFX"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/PackerType/WinZipSFX.cs b/BurnOutSharp/PackerType/WinZipSFX.cs index 7dfe7419..5884f372 100644 --- a/BurnOutSharp/PackerType/WinZipSFX.cs +++ b/BurnOutSharp/PackerType/WinZipSFX.cs @@ -2,12 +2,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; using SharpCompress.Archives; using SharpCompress.Archives.Zip; @@ -21,9 +19,8 @@ namespace BurnOutSharp.PackerType /// public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; string version = GetNEHeaderVersion(nex); @@ -46,16 +43,15 @@ namespace BurnOutSharp.PackerType return null; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { - string version = GetSFXSectionDataVersion(file, pex.ResourceDataSectionRaw, includeDebug); + string version = GetSFXSectionDataVersion(file, pex.GetFirstSectionData(".rdata"), includeDebug); if (!string.IsNullOrWhiteSpace(version)) return $"WinZip SFX {version}"; } // Get the _winzip_ section, if it exists - bool winzipSection = pex.ContainsSection("_winzip_", exact: true); - if (winzipSection) + if (pex.ContainsSection("_winzip_", exact: true)) { string version = GetPEHeaderVersion(pex); if (!string.IsNullOrWhiteSpace(version)) @@ -71,15 +67,16 @@ namespace BurnOutSharp.PackerType #region Unknown Version checks // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { - string version = GetSFXSectionDataUnknownVersion(file, pex.ResourceDataSectionRaw, includeDebug); + string version = GetSFXSectionDataUnknownVersion(file, pex.GetFirstSectionData(".rdata"), includeDebug); if (!string.IsNullOrWhiteSpace(version)) return $"WinZip SFX {version}"; } - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -103,7 +100,7 @@ namespace BurnOutSharp.PackerType }, "Unknown Version (32-bit)"), }; - string version = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, false); + string version = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".data"), matchers, false); if (!string.IsNullOrWhiteSpace(version)) { // Try to grab the value from the manifest, if possible @@ -197,8 +194,8 @@ namespace BurnOutSharp.PackerType private static string GetAdjustedManifestVersion(PortableExecutable pex) { // Get the manifest information, if possible - string description = pex.ManifestDescription; - string version = pex.ManifestVersion; + string description = pex.AssemblyDescription; + string version = pex.AssemblyVersion; // Either an incorrect description or empty version mean we can't match if (description != "WinZip Self-Extractor") @@ -245,144 +242,149 @@ namespace BurnOutSharp.PackerType /// TODO: Research to see if the versions are embedded elsewhere in these files private string GetNEHeaderVersion(NewExecutable nex) { - var neh = nex.NewExecutableHeader; - #region 2.0 Variants // 2.0 (MS-DOS/16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0086 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x00012BE6 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006C - && neh.NonResidentNamesTableOffset == 0x000044B8 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0086 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x00012BE6 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006C + && nex.NonResidentNamesTableOffset == 0x000044B8 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.0 (MS-DOS/16-bit)"; // 2.0 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0086 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x00013174 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006C - && neh.NonResidentNamesTableOffset == 0x00000198 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0086 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x00013174 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006C + && nex.NonResidentNamesTableOffset == 0x00000198 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.0 (16-bit)"; // Compact 2.0 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0080 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x000124A0 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0003 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006A - && neh.NonResidentNamesTableOffset == 0x00000192 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0080 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x000124A0 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0003 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006A + && nex.NonResidentNamesTableOffset == 0x00000192 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Compact 2.0 (16-bit)"; // Software Installation 2.0 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00CD - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x000136FA - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0005 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0097 - && neh.ModuleReferenceTableOffset == 0x00A3 - && neh.ImportedNamesTableOffset == 0x00AD - && neh.NonResidentNamesTableOffset == 0x000001DF - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00CD + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x000136FA + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0005 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0097 + && nex.ModuleReferenceTableOffset == 0x00A3 + && nex.ImportedNamesTableOffset == 0x00AD + && nex.NonResidentNamesTableOffset == 0x000001DF + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Software Installation 2.0 (16-bit)"; #endregion @@ -390,139 +392,145 @@ namespace BurnOutSharp.PackerType #region 2.1 RC2 Variants // 2.1 RC2 (MS-DOS/16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0086 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x00013386 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006C - && neh.NonResidentNamesTableOffset == 0x000043C8 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0086 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x00013386 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006C + && nex.NonResidentNamesTableOffset == 0x000043C8 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.1 RC2 (MS-DOS/16-bit)"; // 2.1 RC2 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00BE - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x00013E56 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A4 - && neh.NonResidentNamesTableOffset == 0x000001D0 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00BE + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x00013E56 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A4 + && nex.NonResidentNamesTableOffset == 0x000001D0 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.1 RC2 (16-bit)"; // Compact 2.1 RC2 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0080 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x00012B84 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0003 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006A - && neh.NonResidentNamesTableOffset == 0x00000192 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0080 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x00012B84 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0003 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006A + && nex.NonResidentNamesTableOffset == 0x00000192 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Compact 2.1 RC2 (16-bit)"; // Software Installation 2.1 RC2 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00BE - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x000143AC - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A4 - && neh.NonResidentNamesTableOffset == 0x000001D0 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00BE + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x000143AC + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A4 + && nex.NonResidentNamesTableOffset == 0x000001D0 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Software Installation 2.1 RC2 (16-bit)"; #endregion @@ -530,139 +538,145 @@ namespace BurnOutSharp.PackerType #region 2.1 Variants // 2.1 (MS-DOS/16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0086 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x3A00 - && neh.InitialCSIPSetting == 0x00013396 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006C - && neh.NonResidentNamesTableOffset == 0x000043C8 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0086 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x3A00 + && nex.InitialCSIPSetting == 0x00013396 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006C + && nex.NonResidentNamesTableOffset == 0x000043C8 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.1 (MS-DOS/16-bit)"; // 2.1 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00BE - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x3A00 - && neh.InitialCSIPSetting == 0x00013E7E - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A4 - && neh.NonResidentNamesTableOffset == 0x000001D0 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00BE + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x3A00 + && nex.InitialCSIPSetting == 0x00013E7E + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A4 + && nex.NonResidentNamesTableOffset == 0x000001D0 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "2.1 (16-bit)"; // Compact 2.1 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0080 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x3A00 - && neh.InitialCSIPSetting == 0x00012B90 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0003 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006A - && neh.NonResidentNamesTableOffset == 0x00000192 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0080 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x3A00 + && nex.InitialCSIPSetting == 0x00012B90 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0003 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006A + && nex.NonResidentNamesTableOffset == 0x00000192 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Compact 2.1 (16-bit)"; // Software Installation 2.1 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00BE - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x3A00 - && neh.InitialCSIPSetting == 0x00014408 - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A4 - && neh.NonResidentNamesTableOffset == 0x000001D0 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00BE + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x3A00 + && nex.InitialCSIPSetting == 0x00014408 + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A4 + && nex.NonResidentNamesTableOffset == 0x000001D0 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Software Installation 2.1 (16-bit)"; #endregion @@ -670,105 +684,109 @@ namespace BurnOutSharp.PackerType #region Misc. Variants // Personal Edition (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x0086 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x0A - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x4000 - && neh.InitialCSIPSetting == 0x0001317C - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0058 - && neh.ModuleReferenceTableOffset == 0x0064 - && neh.ImportedNamesTableOffset == 0x006C - && neh.NonResidentNamesTableOffset == 0x00000198 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x0086 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.ProtectedModeOnly + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x4000 + && nex.InitialCSIPSetting == 0x0001317C + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0058 + && nex.ModuleReferenceTableOffset == 0x0064 + && nex.ImportedNamesTableOffset == 0x006C + && nex.NonResidentNamesTableOffset == 0x00000198 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Personal Edition (16-bit)"; // Personal Edition 32-bit (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00BE - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x2000 - && neh.InitialStackAlloc == 0x3C00 - && neh.InitialCSIPSetting == 0x00013E7C - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0004 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A4 - && neh.NonResidentNamesTableOffset == 0x000001D0 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00BE + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x2000 + && nex.InitialStackAlloc == 0x3C00 + && nex.InitialCSIPSetting == 0x00013E7C + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0004 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A4 + && nex.NonResidentNamesTableOffset == 0x000001D0 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Personal Edition 32-bit (16-bit)"; // Personal Edition 32-bit Build 1260/1285 (16-bit) - if (neh.LinkerVersion == 0x11 - && neh.LinkerRevision == 0x20 - && neh.EntryTableOffset == 0x00C6 - && neh.EntryTableSize == 0x0002 - && neh.CrcChecksum == 0x00000000 - && neh.ProgramFlags == 0x02 - && neh.ApplicationFlags == 0x03 - && neh.Autodata == 0x0003 - && neh.InitialHeapAlloc == 0x43DC - && neh.InitialStackAlloc == 0x2708 - && neh.InitialCSIPSetting == 0x00014ADC - && neh.InitialSSSPSetting == 0x00030000 - && neh.FileSegmentCount == 0x0003 - && neh.ModuleReferenceTableSize == 0x0005 - && neh.NonResidentNameTableSize == 0x004B - && neh.SegmentTableOffset == 0x0040 - && neh.ResourceTableOffset == 0x0058 - && neh.ResidentNameTableOffset == 0x0090 - && neh.ModuleReferenceTableOffset == 0x009C - && neh.ImportedNamesTableOffset == 0x00A6 - && neh.NonResidentNamesTableOffset == 0x000001D8 - && neh.MovableEntriesCount == 0x0000 - && neh.SegmentAlignmentShiftCount == 0x0001 - && neh.ResourceEntriesCount == 0x0000 - && neh.TargetOperatingSystem == 0x02 - && neh.AdditionalFlags == 0x00 - && neh.ReturnThunkOffset == 0x0000 - && neh.SegmentReferenceThunkOffset == 0x0000 - && neh.MinCodeSwapAreaSize == 0x0000 - && neh.WindowsSDKRevision == 0x00 - && neh.WindowsSDKVersion == 0x03) + if (nex.LinkerVersion == 0x11 + && nex.LinkerRevision == 0x20 + && nex.EntryTableOffset == 0x00C6 + && nex.EntryTableSize == 0x0002 + && nex.CrcChecksum == 0x00000000 + && nex.FlagWord == (Models.NewExecutable.HeaderFlag.MULTIPLEDATA + | Models.NewExecutable.HeaderFlag.FullScreen + | Models.NewExecutable.HeaderFlag.WindowsPMCompatible) + && nex.AutomaticDataSegmentNumber == 0x0003 + && nex.InitialHeapAlloc == 0x43DC + && nex.InitialStackAlloc == 0x2708 + && nex.InitialCSIPSetting == 0x00014ADC + && nex.InitialSSSPSetting == 0x00030000 + && nex.FileSegmentCount == 0x0003 + && nex.ModuleReferenceTableSize == 0x0005 + && nex.NonResidentNameTableSize == 0x004B + && nex.SegmentTableOffset == 0x0040 + && nex.ResourceTableOffset == 0x0058 + && nex.ResidentNameTableOffset == 0x0090 + && nex.ModuleReferenceTableOffset == 0x009C + && nex.ImportedNamesTableOffset == 0x00A6 + && nex.NonResidentNamesTableOffset == 0x000001D8 + && nex.MovableEntriesCount == 0x0000 + && nex.SegmentAlignmentShiftCount == 0x0001 + && nex.ResourceEntriesCount == 0x0000 + && nex.TargetOperatingSystem == Models.NewExecutable.OperatingSystem.WINDOWS + && nex.AdditionalFlags == 0x00 + && nex.ReturnThunkOffset == 0x0000 + && nex.SegmentReferenceThunkOffset == 0x0000 + && nex.MinCodeSwapAreaSize == 0x0000 + && nex.WindowsSDKRevision == 0x00 + && nex.WindowsSDKVersion == 0x03) return "Personal Edition 32-bit Build 1260/1285 (16-bit)"; #endregion @@ -782,8 +800,8 @@ namespace BurnOutSharp.PackerType private string GetNEUnknownHeaderVersion(NewExecutable nex, string file, bool includeDebug) { // TODO: Like with PE, convert this into a preread in the header code - int resourceStart = nex.DOSStubHeader.NewExeHeaderAddr + nex.NewExecutableHeader.ResourceTableOffset; - int resourceEnd = nex.DOSStubHeader.NewExeHeaderAddr + nex.NewExecutableHeader.ModuleReferenceTableOffset; + int resourceStart = (int)(nex.Stub_NewExeHeaderAddr + nex.ResourceTableOffset); + int resourceEnd = (int)(nex.Stub_NewExeHeaderAddr + nex.ModuleReferenceTableOffset); int resourceLength = resourceEnd - resourceStart; var resourceData = nex.ReadArbitraryRange(resourceStart, resourceLength); @@ -813,137 +831,134 @@ namespace BurnOutSharp.PackerType /// TODO: Research to see if the versions are embedded elsewhere in these files private string GetPEHeaderVersion(PortableExecutable pex) { - var ifh = pex.ImageFileHeader; - var ioh = pex.OptionalHeader; - // 2.2.3063 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x38BE7AC9 - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x38BE7AC9 + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x05 - && ioh.MinorLinkerVersion == 0x0A - && ioh.SizeOfCode == 0x00005C00 - && ioh.SizeOfInitializedData == 0x00004C00 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x00003E71 - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00007000 - && ioh.ImageBasePE32 == 0x00400000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x05 + && pex.OH_MinorLinkerVersion == 0x0A + && pex.OH_SizeOfCode == 0x00005C00 + && pex.OH_SizeOfInitializedData == 0x00004C00 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x00003E71 + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00007000 + && pex.OH_ImageBase == 0x00400000) return "2.2.3063"; // 2.2.4003 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x3A5B1B69 - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x3A5B1B69 + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x05 - && ioh.MinorLinkerVersion == 0x0A - && ioh.SizeOfCode == 0x00004A00 - && ioh.SizeOfInitializedData == 0x00002A00 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x000039D8 - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00006000 - && ioh.ImageBasePE32 == 0x00400000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x05 + && pex.OH_MinorLinkerVersion == 0x0A + && pex.OH_SizeOfCode == 0x00004A00 + && pex.OH_SizeOfInitializedData == 0x00002A00 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x000039D8 + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00006000 + && pex.OH_ImageBase == 0x00400000) return "2.2.4003"; // Software Installation 2.2.4003 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x3A5B1B81 - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x3A5B1B81 + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x05 - && ioh.MinorLinkerVersion == 0x0A - && ioh.SizeOfCode == 0x00005600 - && ioh.SizeOfInitializedData == 0x00002A00 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x00003F8F - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00007000 - && ioh.ImageBasePE32 == 0x00400000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x05 + && pex.OH_MinorLinkerVersion == 0x0A + && pex.OH_SizeOfCode == 0x00005600 + && pex.OH_SizeOfInitializedData == 0x00002A00 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x00003F8F + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00007000 + && pex.OH_ImageBase == 0x00400000) return "Software Installation 2.2.4003"; // 2.2.4325 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x3BFBB8FA - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x3BFBB8FA + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x06 - && ioh.MinorLinkerVersion == 0x00 - && ioh.SizeOfCode == 0x00006000 - && ioh.SizeOfInitializedData == 0x0000F000 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x00003EF0 - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00007000 - && ioh.ImageBasePE32 == 0x00400000 - && ioh.SectionAlignment == 0x00001000 - && ioh.FileAlignment == 0x00001000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x06 + && pex.OH_MinorLinkerVersion == 0x00 + && pex.OH_SizeOfCode == 0x00006000 + && pex.OH_SizeOfInitializedData == 0x0000F000 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x00003EF0 + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00007000 + && pex.OH_ImageBase == 0x00400000 + && pex.OH_SectionAlignment == 0x00001000 + && pex.OH_FileAlignment == 0x00001000) return "2.2.4325"; // 2.2.5196 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x3D2AFCAD - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x3D2AFCAD + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x07 - && ioh.MinorLinkerVersion == 0x00 - && ioh.SizeOfCode == 0x00007000 - && ioh.SizeOfInitializedData == 0x00010000 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x00004554 - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00008000 - && ioh.ImageBasePE32 == 0x00400000 - && ioh.SectionAlignment == 0x00001000 - && ioh.FileAlignment == 0x00001000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x07 + && pex.OH_MinorLinkerVersion == 0x00 + && pex.OH_SizeOfCode == 0x00007000 + && pex.OH_SizeOfInitializedData == 0x00010000 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x00004554 + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00008000 + && pex.OH_ImageBase == 0x00400000 + && pex.OH_SectionAlignment == 0x00001000 + && pex.OH_FileAlignment == 0x00001000) return "2.2.5196"; // 2.2.6202 - if (ifh.Machine == MachineType.IMAGE_FILE_MACHINE_I386 - && ifh.NumberOfSections == 0x0005 - && ifh.TimeDateStamp == 0x4100F776 - && ifh.PointerToSymbolTable == 0x00000000 - && ifh.NumberOfSymbols == 0x00000000 - && ifh.SizeOfOptionalHeader == 0x00E0 - && (ushort)ifh.Characteristics == 0x010F + if (pex.Machine == Models.PortableExecutable.MachineType.IMAGE_FILE_MACHINE_I386 + && pex.NumberOfSections == 0x0005 + && pex.TimeDateStamp == 0x4100F776 + && pex.PointerToSymbolTable == 0x00000000 + && pex.NumberOfSymbols == 0x00000000 + && pex.SizeOfOptionalHeader == 0x00E0 + && (ushort)pex.Characteristics == 0x010F - && ioh.Magic == OptionalHeaderType.PE32 - && ioh.MajorLinkerVersion == 0x07 - && ioh.MinorLinkerVersion == 0x00 - && ioh.SizeOfCode == 0x00007000 - && ioh.SizeOfInitializedData == 0x00010000 - && ioh.SizeOfUninitializedData == 0x00000000 - && ioh.AddressOfEntryPoint == 0x00004603 - && ioh.BaseOfCode == 0x00001000 - && ioh.BaseOfData == 0x00008000 - && ioh.ImageBasePE32 == 0x00400000) + && pex.OH_Magic == Models.PortableExecutable.OptionalHeaderMagicNumber.PE32 + && pex.OH_MajorLinkerVersion == 0x07 + && pex.OH_MinorLinkerVersion == 0x00 + && pex.OH_SizeOfCode == 0x00007000 + && pex.OH_SizeOfInitializedData == 0x00010000 + && pex.OH_SizeOfUninitializedData == 0x00000000 + && pex.OH_AddressOfEntryPoint == 0x00004603 + && pex.OH_BaseOfCode == 0x00001000 + && pex.OH_BaseOfData == 0x00008000 + && pex.OH_ImageBase == 0x00400000) return "2.2.6202"; return null; diff --git a/BurnOutSharp/PackerType/WiseInstaller.cs b/BurnOutSharp/PackerType/WiseInstaller.cs index 4ad0aaad..060e6de5 100644 --- a/BurnOutSharp/PackerType/WiseInstaller.cs +++ b/BurnOutSharp/PackerType/WiseInstaller.cs @@ -2,11 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; using Wise = WiseUnpacker.WiseUnpacker; namespace BurnOutSharp.PackerType @@ -20,9 +19,8 @@ namespace BurnOutSharp.PackerType /// public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + /// Check we have a valid executable + if (nex == null) return null; // TODO: Don't read entire file @@ -49,8 +47,9 @@ namespace BurnOutSharp.PackerType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -58,13 +57,13 @@ namespace BurnOutSharp.PackerType new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Wise Installation Wizard Module"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -72,7 +71,7 @@ namespace BurnOutSharp.PackerType new ContentMatchSet(new byte?[] { 0x57, 0x69, 0x73, 0x65, 0x4D, 0x61, 0x69, 0x6E }, "Wise Installation Wizard Module"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/PackerType/dotFuscator.cs b/BurnOutSharp/PackerType/dotFuscator.cs index d149937c..beaf7dd0 100644 --- a/BurnOutSharp/PackerType/dotFuscator.cs +++ b/BurnOutSharp/PackerType/dotFuscator.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.PackerType { @@ -22,7 +22,7 @@ namespace BurnOutSharp.PackerType return null; // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -35,7 +35,7 @@ namespace BurnOutSharp.PackerType }, "dotFuscator"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/ActiveMARK.cs b/BurnOutSharp/ProtectionType/ActiveMARK.cs index 09e0df7e..14a85638 100644 --- a/BurnOutSharp/ProtectionType/ActiveMARK.cs +++ b/BurnOutSharp/ProtectionType/ActiveMARK.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -39,134 +39,135 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; + // TODO: Re-enable all Entry Point checks after implementing // Get the entry point data, if it exists - if (pex.EntryPointRaw != null) - { - var matchers = new List - { - // Checks sourced from https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt - new ContentMatchSet(new byte?[] - { - 0x79, 0x11, 0x7F, 0xAB, 0x9A, 0x4A, 0x83, 0xB5, - 0xC9, 0x6B, 0x1A, 0x48, 0xF9, 0x27, 0xB4, 0x25, - }, "ActiveMARK"), + // if (pex.EntryPointRaw != null) + // { + // var matchers = new List + // { + // // Checks sourced from https://raw.githubusercontent.com/wolfram77web/app-peid/master/userdb.txt + // new ContentMatchSet(new byte?[] + // { + // 0x79, 0x11, 0x7F, 0xAB, 0x9A, 0x4A, 0x83, 0xB5, + // 0xC9, 0x6B, 0x1A, 0x48, 0xF9, 0x27, 0xB4, 0x25, + // }, "ActiveMARK"), - new ContentMatchSet(new byte?[] - { - 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, - 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, - 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, - 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, - 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, - 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, - 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, - 0x64, 0x65, 0x62, 0x75, 0x67, - }, "ActiveMARK 5.x -> Trymedia Systems Inc. (h)"), + // new ContentMatchSet(new byte?[] + // { + // 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, + // 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, + // 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, + // 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + // 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, + // 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, + // 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, + // 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, + // 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, + // 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, + // 0x64, 0x65, 0x62, 0x75, 0x67, + // }, "ActiveMARK 5.x -> Trymedia Systems Inc. (h)"), - new ContentMatchSet(new byte?[] - { - 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, - 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, - 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, - 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, - 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, - 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, - 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, - 0x20, 0x69, 0x6E, 0x20, 0x6D, 0x65, 0x6D, 0x6F, - 0x72, 0x79, 0x2E, 0x0D, 0x0A, 0x50, 0x6C, 0x65, - 0x61, 0x73, 0x65, 0x20, 0x75, 0x6E, 0x6C, 0x6F, - 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x20, - 0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6F, 0x6E, 0x2E, 0x00, 0x57, 0x61, 0x72, - 0x6E, 0x69, 0x6E, 0x67, - }, "ActiveMARK 5.x -> Trymedia Systems,Inc."), + // new ContentMatchSet(new byte?[] + // { + // 0x20, 0x2D, 0x2D, 0x4D, 0x50, 0x52, 0x4D, 0x4D, + // 0x47, 0x56, 0x41, 0x2D, 0x2D, 0x00, 0x75, 0x73, + // 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, + // 0x00, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + // 0x42, 0x6F, 0x78, 0x41, 0x00, 0x54, 0x68, 0x69, + // 0x73, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, + // 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x63, 0x61, + // 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x72, 0x75, 0x6E, + // 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6E, + // 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, + // 0x64, 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, + // 0x20, 0x69, 0x6E, 0x20, 0x6D, 0x65, 0x6D, 0x6F, + // 0x72, 0x79, 0x2E, 0x0D, 0x0A, 0x50, 0x6C, 0x65, + // 0x61, 0x73, 0x65, 0x20, 0x75, 0x6E, 0x6C, 0x6F, + // 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, + // 0x65, 0x62, 0x75, 0x67, 0x67, 0x65, 0x72, 0x20, + // 0x61, 0x6E, 0x64, 0x20, 0x72, 0x65, 0x73, 0x74, + // 0x61, 0x72, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, + // 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, + // 0x69, 0x6F, 0x6E, 0x2E, 0x00, 0x57, 0x61, 0x72, + // 0x6E, 0x69, 0x6E, 0x67, + // }, "ActiveMARK 5.x -> Trymedia Systems,Inc."), - new ContentMatchSet(new byte?[] - { - 0xBE, 0x48, 0x01, 0x40, 0x00, 0xAD, 0x8B, 0xF8, - 0x95, 0xA5, 0x33, 0xC0, 0x33, 0xC9, 0xAB, 0x48, - 0xAB, 0xF7, 0xD8, 0xB1, 0x04, 0xF3, 0xAB, 0xC1, - 0xE0, 0x0A, 0xB5, 0x1C, 0xF3, 0xAB, 0xAD, 0x50, - 0x97, 0x51, 0xAD, 0x87, 0xF5, 0x58, 0x8D, 0x54, - 0x86, 0x5C, 0xFF, 0xD5, 0x72, 0x5A, 0x2C, 0x03, - 0x73, 0x02, 0xB0, 0x00, 0x3C, 0x07, 0x72, 0x02, - 0x2C, 0x03, 0x50, 0x0F, 0xB6, 0x5F, 0xFF, 0xC1, - 0xE3, 0x03, 0xB3, 0x00, 0x8D, 0x1C, 0x5B, 0x8D, - 0x9C, 0x9E, 0x0C, 0x10, 0x00, 0x00, 0xB0, 0x01, - 0x67, 0xE3, 0x29, 0x8B, 0xD7, 0x2B, 0x56, 0x0C, - 0x8A, 0x2A, 0x33, 0xD2, 0x84, 0xE9, 0x0F, 0x95, - 0xC6, 0x52, 0xFE, 0xC6, 0x8A, 0xD0, 0x8D, 0x14, - 0x93, 0xFF, 0xD5, 0x5A, 0x9F, 0x12, 0xC0, 0xD0, - 0xE9, 0x74, 0x0E, 0x9E, 0x1A, 0xF2, 0x74, 0xE4, - 0xB4, 0x00, 0x33, 0xC9, 0xB5, 0x01, 0xFF, 0x55, - 0xCC, 0x33, 0xC9, 0xE9, 0xDF, 0x00, 0x00, 0x00, - 0x8B, 0x5E, 0x0C, 0x83, 0xC2, 0x30, 0xFF, 0xD5, - 0x73, 0x50, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, - 0x1B, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, 0x2B, - 0x3C, 0x07, 0xB0, 0x09, 0x72, 0x02, 0xB0, 0x0B, - 0x50, 0x8B, 0xC7, 0x2B, 0x46, 0x0C, 0xB1, 0x80, - 0x8A, 0x00, 0xEB, 0xCF, 0x83, 0xC2, 0x60, 0xFF, - 0xD5, 0x87, 0x5E, 0x10, 0x73, 0x0D, 0x83, 0xC2, - 0x30, 0xFF, 0xD5, 0x87, 0x5E, 0x14, 0x73, 0x03, - 0x87, 0x5E, 0x18, 0x3C, 0x07, 0xB0, 0x08, 0x72, - 0x02, 0xB0, 0x0B, 0x50, 0x53, 0x8D, 0x96, 0x7C, - 0x07, 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x5B, 0x91, - 0xEB, 0x77, 0x3C, 0x07, 0xB0, 0x07, 0x72, 0x02, - 0xB0, 0x0A, 0x50, 0x87, 0x5E, 0x10, 0x87, 0x5E, - 0x14, 0x89, 0x5E, 0x18, 0x8D, 0x96, 0xC4, 0x0B, - 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x50, 0x48, - }, "ActiveMARK 5.x -> Trymedia Systems,Inc. (h)"), + // new ContentMatchSet(new byte?[] + // { + // 0xBE, 0x48, 0x01, 0x40, 0x00, 0xAD, 0x8B, 0xF8, + // 0x95, 0xA5, 0x33, 0xC0, 0x33, 0xC9, 0xAB, 0x48, + // 0xAB, 0xF7, 0xD8, 0xB1, 0x04, 0xF3, 0xAB, 0xC1, + // 0xE0, 0x0A, 0xB5, 0x1C, 0xF3, 0xAB, 0xAD, 0x50, + // 0x97, 0x51, 0xAD, 0x87, 0xF5, 0x58, 0x8D, 0x54, + // 0x86, 0x5C, 0xFF, 0xD5, 0x72, 0x5A, 0x2C, 0x03, + // 0x73, 0x02, 0xB0, 0x00, 0x3C, 0x07, 0x72, 0x02, + // 0x2C, 0x03, 0x50, 0x0F, 0xB6, 0x5F, 0xFF, 0xC1, + // 0xE3, 0x03, 0xB3, 0x00, 0x8D, 0x1C, 0x5B, 0x8D, + // 0x9C, 0x9E, 0x0C, 0x10, 0x00, 0x00, 0xB0, 0x01, + // 0x67, 0xE3, 0x29, 0x8B, 0xD7, 0x2B, 0x56, 0x0C, + // 0x8A, 0x2A, 0x33, 0xD2, 0x84, 0xE9, 0x0F, 0x95, + // 0xC6, 0x52, 0xFE, 0xC6, 0x8A, 0xD0, 0x8D, 0x14, + // 0x93, 0xFF, 0xD5, 0x5A, 0x9F, 0x12, 0xC0, 0xD0, + // 0xE9, 0x74, 0x0E, 0x9E, 0x1A, 0xF2, 0x74, 0xE4, + // 0xB4, 0x00, 0x33, 0xC9, 0xB5, 0x01, 0xFF, 0x55, + // 0xCC, 0x33, 0xC9, 0xE9, 0xDF, 0x00, 0x00, 0x00, + // 0x8B, 0x5E, 0x0C, 0x83, 0xC2, 0x30, 0xFF, 0xD5, + // 0x73, 0x50, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, + // 0x1B, 0x83, 0xC2, 0x30, 0xFF, 0xD5, 0x72, 0x2B, + // 0x3C, 0x07, 0xB0, 0x09, 0x72, 0x02, 0xB0, 0x0B, + // 0x50, 0x8B, 0xC7, 0x2B, 0x46, 0x0C, 0xB1, 0x80, + // 0x8A, 0x00, 0xEB, 0xCF, 0x83, 0xC2, 0x60, 0xFF, + // 0xD5, 0x87, 0x5E, 0x10, 0x73, 0x0D, 0x83, 0xC2, + // 0x30, 0xFF, 0xD5, 0x87, 0x5E, 0x14, 0x73, 0x03, + // 0x87, 0x5E, 0x18, 0x3C, 0x07, 0xB0, 0x08, 0x72, + // 0x02, 0xB0, 0x0B, 0x50, 0x53, 0x8D, 0x96, 0x7C, + // 0x07, 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x5B, 0x91, + // 0xEB, 0x77, 0x3C, 0x07, 0xB0, 0x07, 0x72, 0x02, + // 0xB0, 0x0A, 0x50, 0x87, 0x5E, 0x10, 0x87, 0x5E, + // 0x14, 0x89, 0x5E, 0x18, 0x8D, 0x96, 0xC4, 0x0B, + // 0x00, 0x00, 0xFF, 0x55, 0xD0, 0x50, 0x48, + // }, "ActiveMARK 5.x -> Trymedia Systems,Inc. (h)"), - new ContentMatchSet(new byte?[] - { - 0x79, 0x07, 0x0F, 0xB7, 0x07, 0x47, 0x50, 0x47, - 0xB9, 0x57, 0x48, 0xF2, 0xAE, 0x55, 0xFF, 0x96, - 0x84, null, 0x00, 0x00, 0x09, 0xC0, 0x74, 0x07, - 0x89, 0x03, 0x83, 0xC3, 0x04, 0xEB, 0xD8, 0xFF, - 0x96, 0x88, null, 0x00, 0x00, 0x61, 0xE9, null, - null, null, 0xFF, - }, "ActiveMARK R5.31.1140 -> Trymedia"), + // new ContentMatchSet(new byte?[] + // { + // 0x79, 0x07, 0x0F, 0xB7, 0x07, 0x47, 0x50, 0x47, + // 0xB9, 0x57, 0x48, 0xF2, 0xAE, 0x55, 0xFF, 0x96, + // 0x84, null, 0x00, 0x00, 0x09, 0xC0, 0x74, 0x07, + // 0x89, 0x03, 0x83, 0xC3, 0x04, 0xEB, 0xD8, 0xFF, + // 0x96, 0x88, null, 0x00, 0x00, 0x61, 0xE9, null, + // null, null, 0xFF, + // }, "ActiveMARK R5.31.1140 -> Trymedia"), - new ContentMatchSet(new byte?[] - { - 0x89, 0x25, null, null, null, null, null, null, - null, null, 0xEB, - }, "ActiveMark -> Trymedia Systems Inc."), + // new ContentMatchSet(new byte?[] + // { + // 0x89, 0x25, null, null, null, null, null, null, + // null, null, 0xEB, + // }, "ActiveMark -> Trymedia Systems Inc."), - new ContentMatchSet(new byte?[] - { - 0x89, 0x25, null, null, null, null, 0x33, 0xED, - 0x55, 0x8B, 0xEC, 0xE8, null, null, null, null, - 0x8B, 0xD0, 0x81, 0xE2, 0xFF, 0x00, 0x00, 0x00, - 0x89, 0x15, null, null, null, null, 0x8B, 0xD0, - 0xC1, 0xEA, 0x08, 0x81, 0xE2, 0xFF, 0x00, 0x00, - 0x00, 0xA3, null, null, null, null, 0xD1, 0xE0, - 0x0F, 0x93, 0xC3, 0x33, 0xC0, 0x8A, 0xC3, 0xA3, - null, null, null, null, 0x68, 0xFF, 0x00, 0x00, - 0x00, 0xE8, null, null, null, null, 0x6A, 0x00, - 0xE8, null, null, null, null, 0xA3, null, null, - null, null, 0xBB, null, null, null, null, 0xC7, - 0x03, 0x44, 0x00, 0x00, 0x00, - }, "ActiveMark -> Trymedia Systems Inc."), - }; + // new ContentMatchSet(new byte?[] + // { + // 0x89, 0x25, null, null, null, null, 0x33, 0xED, + // 0x55, 0x8B, 0xEC, 0xE8, null, null, null, null, + // 0x8B, 0xD0, 0x81, 0xE2, 0xFF, 0x00, 0x00, 0x00, + // 0x89, 0x15, null, null, null, null, 0x8B, 0xD0, + // 0xC1, 0xEA, 0x08, 0x81, 0xE2, 0xFF, 0x00, 0x00, + // 0x00, 0xA3, null, null, null, null, 0xD1, 0xE0, + // 0x0F, 0x93, 0xC3, 0x33, 0xC0, 0x8A, 0xC3, 0xA3, + // null, null, null, null, 0x68, 0xFF, 0x00, 0x00, + // 0x00, 0xE8, null, null, null, null, 0x6A, 0x00, + // 0xE8, null, null, null, null, 0xA3, null, null, + // null, null, 0xBB, null, null, null, null, 0xC7, + // 0x03, 0x44, 0x00, 0x00, 0x00, + // }, "ActiveMark -> Trymedia Systems Inc."), + // }; - string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } + // string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); + // if (!string.IsNullOrWhiteSpace(match)) + // return match; + // } // Get the overlay data, if it exists - if (pex.OverlayRaw != null) + if (pex.Overlay != null) { var matchers = new List { @@ -174,13 +175,13 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x00, 0x54, 0x4D, 0x53, 0x41, 0x4D, 0x56, 0x4F, 0x48, }, "ActiveMARK"), }; - string match = MatchUtil.GetFirstMatch(file, pex.OverlayRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.Overlay, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the last .bss section, if it exists - var bssSectionRaw = pex.ReadRawSection(".bss", first: false); + var bssSectionRaw = pex.GetLastSectionData(".bss"); if (bssSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/AegiSoft.cs b/BurnOutSharp/ProtectionType/AegiSoft.cs index c89fdc6c..a59bff56 100644 --- a/BurnOutSharp/ProtectionType/AegiSoft.cs +++ b/BurnOutSharp/ProtectionType/AegiSoft.cs @@ -1,8 +1,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -33,8 +33,9 @@ namespace BurnOutSharp.ProtectionType // "Asc005.dll" has the Product Name "OrderWizard Dynamic Link Library". // "Asc006.exe" has the Product Name "AGENT Application". - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -47,7 +48,7 @@ namespace BurnOutSharp.ProtectionType }, "AegiSoft License Manager"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/AlphaROM.cs b/BurnOutSharp/ProtectionType/AlphaROM.cs index 5bac72eb..05c31c48 100644 --- a/BurnOutSharp/ProtectionType/AlphaROM.cs +++ b/BurnOutSharp/ProtectionType/AlphaROM.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -54,8 +54,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -68,13 +69,13 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x53, 0x45, 0x54, 0x54, 0x45, 0x43, 0x30, 0x30, 0x30, 0x30 }, "Alpha-ROM"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -112,13 +113,13 @@ namespace BurnOutSharp.ProtectionType }, "Alpha-ROM"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the overlay data, if it exists - if (pex.OverlayRaw != null) + if (pex.Overlay != null) { var matchers = new List { @@ -127,7 +128,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x53, 0x45, 0x54, 0x54, 0x45, 0x43, 0x30, 0x30, 0x30, 0x30 }, "Alpha-ROM"), }; - string match = MatchUtil.GetFirstMatch(file, pex.OverlayRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.Overlay, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/CDCheck.cs b/BurnOutSharp/ProtectionType/CDCheck.cs index 093173f6..a01e5932 100644 --- a/BurnOutSharp/ProtectionType/CDCheck.cs +++ b/BurnOutSharp/ProtectionType/CDCheck.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -16,7 +16,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -28,7 +28,7 @@ namespace BurnOutSharp.ProtectionType }, "Microsoft Game Studios CD Check"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/CDDVDCops.cs b/BurnOutSharp/ProtectionType/CDDVDCops.cs index 9b390d6e..04cd64d5 100644 --- a/BurnOutSharp/ProtectionType/CDDVDCops.cs +++ b/BurnOutSharp/ProtectionType/CDDVDCops.cs @@ -2,10 +2,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -45,9 +44,8 @@ namespace BurnOutSharp.ProtectionType /// public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; // TODO: Don't read entire file diff --git a/BurnOutSharp/ProtectionType/CDKey.cs b/BurnOutSharp/ProtectionType/CDKey.cs index 41015d1f..6dc58724 100644 --- a/BurnOutSharp/ProtectionType/CDKey.cs +++ b/BurnOutSharp/ProtectionType/CDKey.cs @@ -1,6 +1,6 @@ using System; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/CDLock.cs b/BurnOutSharp/ProtectionType/CDLock.cs index d31b62e0..797da301 100644 --- a/BurnOutSharp/ProtectionType/CDLock.cs +++ b/BurnOutSharp/ProtectionType/CDLock.cs @@ -1,8 +1,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -34,8 +34,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -51,7 +52,7 @@ namespace BurnOutSharp.ProtectionType }, "CD-Lock"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/CDSHiELDSE.cs b/BurnOutSharp/ProtectionType/CDSHiELDSE.cs index 736e7ad7..7ef63ba1 100644 --- a/BurnOutSharp/ProtectionType/CDSHiELDSE.cs +++ b/BurnOutSharp/ProtectionType/CDSHiELDSE.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -16,7 +16,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the code/CODE section, if it exists - var codeSectionRaw = pex.ReadRawSection("code", first: true) ?? pex.ReadRawSection("CODE", first: true); + var codeSectionRaw = pex.GetFirstSectionData("code") ?? pex.GetFirstSectionData("CODE"); if (codeSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CactusDataShield.cs b/BurnOutSharp/ProtectionType/CactusDataShield.cs index 0f0e8181..11334744 100644 --- a/BurnOutSharp/ProtectionType/CactusDataShield.cs +++ b/BurnOutSharp/ProtectionType/CactusDataShield.cs @@ -4,9 +4,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -62,8 +62,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -74,28 +75,17 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x44, 0x41, 0x54, 0x41, 0x2E, 0x43, 0x44, 0x53 }, "Cactus Data Shield 200"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } - // Get the .rsrc section, if it exists - var rsrcSectionRaw = pex.ReadRawSection(".rsrc", first: false); - if (rsrcSectionRaw != null) - { - var matchers = new List - { - // CactusPJ - // Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]). - // Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable. - new ContentMatchSet(new byte?[] { 0x43, 0x61, 0x63, 0x74, 0x75, 0x73, 0x50, 0x4A }, "PlayJ Music Player (Cactus Data Shield 200)"), - }; + // Found in "Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427]). + // Modified version of the PlayJ Music Player specificaly for CDS, as indicated by the About page present when running the executable. + var resources = pex.FindGenericResource("CactusPJ"); + if (resources.Any()) + return "PlayJ Music Player (Cactus Data Shield 200)"; - string match = MatchUtil.GetFirstMatch(file, rsrcSectionRaw, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } - return null; } diff --git a/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs b/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs index 73ddef46..5ce3ca08 100644 --- a/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs +++ b/BurnOutSharp/ProtectionType/CenegaProtectDVD.cs @@ -1,8 +1,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs b/BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs index aae4bccd..501a16d1 100644 --- a/BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs +++ b/BurnOutSharp/ProtectionType/ChosenBytesCode-Lock.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -59,7 +59,7 @@ namespace BurnOutSharp.ProtectionType return $"ChosenBytes Code-Lock {pex.ProductVersion}"; // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -72,7 +72,7 @@ namespace BurnOutSharp.ProtectionType }, "ChosenBytes Code-Lock"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/CopyLok.cs b/BurnOutSharp/ProtectionType/CopyLok.cs index 3a370a09..bf3aba28 100644 --- a/BurnOutSharp/ProtectionType/CopyLok.cs +++ b/BurnOutSharp/ProtectionType/CopyLok.cs @@ -1,6 +1,6 @@ using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -33,7 +33,7 @@ namespace BurnOutSharp.ProtectionType // If there are more than 2 icd-prefixed sections, then we have a match // Though this is the same name that SafeDisc uses for protected executables, this seems to be a coincidence. // Found in Redump entries 31557, 31674, 31675, 31708, 38239, 44210, and 53929. - int icdSectionCount = pex.GetSectionNames().Count(s => s.StartsWith("icd")); + int icdSectionCount = pex.SectionNames.Count(s => s.StartsWith("icd")); if (icdSectionCount >= 2) return "CopyLok / CodeLok"; diff --git a/BurnOutSharp/ProtectionType/Cucko.cs b/BurnOutSharp/ProtectionType/Cucko.cs index c498cd6d..34c70672 100644 --- a/BurnOutSharp/ProtectionType/Cucko.cs +++ b/BurnOutSharp/ProtectionType/Cucko.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -20,7 +20,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the .text section, if it exists - if (pex.TextSectionRaw == null) + if (!pex.ContainsSection(".text")) return null; var matchers = new List @@ -35,7 +35,7 @@ namespace BurnOutSharp.ProtectionType }, "Cucko (EA Custom)") }; - return MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + return MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); } } } diff --git a/BurnOutSharp/ProtectionType/Denuvo.cs b/BurnOutSharp/ProtectionType/Denuvo.cs index 224e2e5a..213eab47 100644 --- a/BurnOutSharp/ProtectionType/Denuvo.cs +++ b/BurnOutSharp/ProtectionType/Denuvo.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -66,19 +65,20 @@ namespace BurnOutSharp.ProtectionType // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Denuvo%20protector.2.sg // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/_denuvoComplete.2.sg + // TODO: Re-enable all Entry Point checks after implementing // Denuvo Protector - if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus && pex.EntryPointRaw != null) - { - byte?[] denuvoProtector = new byte?[] - { - 0x48, 0x8D, 0x0D, null, null, null, null, null, - null, null, null, 0xE9, null, null, null, null, - 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; + // if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus && pex.EntryPointRaw != null) + // { + // byte?[] denuvoProtector = new byte?[] + // { + // 0x48, 0x8D, 0x0D, null, null, null, null, null, + // null, null, null, 0xE9, null, null, null, null, + // 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // }; - if (pex.EntryPointRaw.StartsWith(denuvoProtector)) - return "Denuvo Protector"; - } + // if (pex.EntryPointRaw.StartsWith(denuvoProtector)) + // return "Denuvo Protector"; + // } // Denuvo var timingMatchers = new List @@ -92,171 +92,172 @@ namespace BurnOutSharp.ProtectionType }, "Denuvo") }; - if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrWhiteSpace(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug))) - { - if (pex.OptionalHeader.Magic == OptionalHeaderType.PE32Plus) - { - var matchers = new List - { - // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D, - null, null, null, null, null, 0x4C, 0x8D, null, - null, null, null, null, 0x4D, 0x29, 0xC1, - }, - end: 0 - ), - "Denuvo v1.0 (x64)"), + // TODO: Re-enable all Entry Point checks after implementing + // if (pex.ContainsSection(".arch") || pex.ContainsSection(".srdata") || !string.IsNullOrWhiteSpace(MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, timingMatchers, includeDebug))) + // { + // if (pex.OH_Magic == OptionalHeaderType.PE32Plus) + // { + // var matchers = new List + // { + // // Mad Max, Metal Gear Solid: TPP, Rise of the Tomb Raider + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x4C, 0x8D, + // null, null, null, null, null, 0x4C, 0x8D, null, + // null, null, null, null, 0x4D, 0x29, 0xC1, + // }, + // end: 0 + // ), + // "Denuvo v1.0 (x64)"), - // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9, - null, null, null, null, - }, - end: 0 - ), - "Denuvo v2.0a (x64)"), + // // Lords of the Fallen, Batman: AK, Just Cause 3, Sherlock Holmes: TdD, Tales of Berseria etc + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x48, 0x8D, 0x0D, null, null, null, null, 0xE9, + // null, null, null, null, + // }, + // end: 0 + // ), + // "Denuvo v2.0a (x64)"), - // Yesterday Origins - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x48, 0x89, null, null, null, null, null, 0x48, - 0x89, null, null, null, null, null, 0x4C, 0x89, - null, null, null, null, null, 0x4C, 0x89, null, - null, null, null, null, 0x48, 0x83, 0xFA, 0x01, - }, - end: 0 - ), - "Denuvo v2.0b (x64)"), + // // Yesterday Origins + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x48, 0x89, null, null, null, null, null, 0x48, + // 0x89, null, null, null, null, null, 0x4C, 0x89, + // null, null, null, null, null, 0x4C, 0x89, null, + // null, null, null, null, 0x48, 0x83, 0xFA, 0x01, + // }, + // end: 0 + // ), + // "Denuvo v2.0b (x64)"), - // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free) - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - null, null, null, null, null, null, null, null, - 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3, - }, - end: 0 - ), - "Denuvo v3.0a (x64)"), + // // Sniper Ghost Warrior 3 (beta), Dead Rising 4 (SteamStub-free) + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // null, null, null, null, null, null, null, null, + // 0x4C, 0x89, 0x1C, 0x24, 0x49, 0x89, 0xE3, + // }, + // end: 0 + // ), + // "Denuvo v3.0a (x64)"), - // Train Sim World CSX Heavy Haul - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x4D, 0x8D, null, null, null, null, null, null, - null, null, null, 0x48, 0x89, null, null, null, - null, null, 0x48, 0x8D, null, null, 0x48, 0x89, - null, 0x48, 0x89, null, 0x48, 0x89, - }, - end: 0 - ), - "Denuvo v3.0b (x64)"), - }; + // // Train Sim World CSX Heavy Haul + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x4D, 0x8D, null, null, null, null, null, null, + // null, null, null, 0x48, 0x89, null, null, null, + // null, null, 0x48, 0x8D, null, null, 0x48, 0x89, + // null, 0x48, 0x89, null, 0x48, 0x89, + // }, + // end: 0 + // ), + // "Denuvo v3.0b (x64)"), + // }; - string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; + // string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); + // if (!string.IsNullOrWhiteSpace(match)) + // return match; - return "Denuvo (Unknown x64 Version)"; + // return "Denuvo (Unknown x64 Version)"; - //// Check if steam_api64.dll present - //if (PE.isLibraryPresent("steam_api64.dll")) - //{ - // // Override additional info - // sOptions = "x64 -> Steam"; - // bDetected = 1; - //} - //// Check if uplay_r1_loader64.dll present - //if (PE.isLibraryPresent("uplay_r1_loader64.dll")) - //{ - // // Override additional info - // sOptions = "x64 -> uPlay"; - // bDetected = 1; - //} - //// Check if uplay_r2_loader64.dll present - //if (PE.isLibraryPresent("uplay_r2_loader64.dll")) - //{ - // // Override additional info - // sOptions = "x64 -> uPlay"; - // bDetected = 1; - //} - //// Check if Core/Activation64.dll present - //if (PE.isLibraryPresent("Core/Activation64.dll")) - //{ - // // Override additional info - // sOptions = "x64 -> Origin"; - // bDetected = 1; - //} - } - else - { - var matchers = new List - { - // Pro Evolution Soccer 2017, Champions of Anteria - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x55, 0x89, 0xE5, 0x8D, null, null, null, null, - null, null, 0xE8, null, null, null, null, 0xE8, - null, null, null, null, 0xE8, null, null, null, - null, 0xE8, null, null, null, null, - }, - end: 0 - ), - "Denuvo v1.0 (x86)"), + // //// Check if steam_api64.dll present + // //if (PE.isLibraryPresent("steam_api64.dll")) + // //{ + // // // Override additional info + // // sOptions = "x64 -> Steam"; + // // bDetected = 1; + // //} + // //// Check if uplay_r1_loader64.dll present + // //if (PE.isLibraryPresent("uplay_r1_loader64.dll")) + // //{ + // // // Override additional info + // // sOptions = "x64 -> uPlay"; + // // bDetected = 1; + // //} + // //// Check if uplay_r2_loader64.dll present + // //if (PE.isLibraryPresent("uplay_r2_loader64.dll")) + // //{ + // // // Override additional info + // // sOptions = "x64 -> uPlay"; + // // bDetected = 1; + // //} + // //// Check if Core/Activation64.dll present + // //if (PE.isLibraryPresent("Core/Activation64.dll")) + // //{ + // // // Override additional info + // // sOptions = "x64 -> Origin"; + // // bDetected = 1; + // //} + // } + // else + // { + // var matchers = new List + // { + // // Pro Evolution Soccer 2017, Champions of Anteria + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x55, 0x89, 0xE5, 0x8D, null, null, null, null, + // null, null, 0xE8, null, null, null, null, 0xE8, + // null, null, null, null, 0xE8, null, null, null, + // null, 0xE8, null, null, null, null, + // }, + // end: 0 + // ), + // "Denuvo v1.0 (x86)"), - // Romance of 13 Kingdoms, 2Dark - new ContentMatchSet( - new ContentMatch( - new byte?[] - { - 0x8D, null, null, null, null, null, null, 0x89, - 0x7C, 0x24, 0x04, 0x89, 0xE7, - }, - end: 0 - ), - "Denuvo v2.0 (x86)"), - }; + // // Romance of 13 Kingdoms, 2Dark + // new ContentMatchSet( + // new ContentMatch( + // new byte?[] + // { + // 0x8D, null, null, null, null, null, null, 0x89, + // 0x7C, 0x24, 0x04, 0x89, 0xE7, + // }, + // end: 0 + // ), + // "Denuvo v2.0 (x86)"), + // }; - string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; + // string match = MatchUtil.GetFirstMatch(file, pex.EntryPointRaw, matchers, includeDebug); + // if (!string.IsNullOrWhiteSpace(match)) + // return match; - //// Check if steam_api64.dll present - //if (PE.isLibraryPresent("steam_api.dll")) - //{ - // // Override additional info - // sOptions = "x86 -> Steam"; - // bDetected = 1; - //} - //// Check if uplay_r1_loader.dll present - //if (PE.isLibraryPresent("uplay_r1_loader.dll")) - //{ - // // Override additional info - // sOptions = "x86 -> uPlay"; - // bDetected = 1; - //} - //// Check if Core/Activation.dll present - //if (PE.isLibraryPresent("Core/Activation.dll")) - //{ - // // Override additional info - // sOptions = "x86 -> Origin"; - // bDetected = 1; - //} - } - } + // //// Check if steam_api64.dll present + // //if (PE.isLibraryPresent("steam_api.dll")) + // //{ + // // // Override additional info + // // sOptions = "x86 -> Steam"; + // // bDetected = 1; + // //} + // //// Check if uplay_r1_loader.dll present + // //if (PE.isLibraryPresent("uplay_r1_loader.dll")) + // //{ + // // // Override additional info + // // sOptions = "x86 -> uPlay"; + // // bDetected = 1; + // //} + // //// Check if Core/Activation.dll present + // //if (PE.isLibraryPresent("Core/Activation.dll")) + // //{ + // // // Override additional info + // // sOptions = "x86 -> Origin"; + // // bDetected = 1; + // //} + // } + // } return null; } diff --git a/BurnOutSharp/ProtectionType/DiscGuard.cs b/BurnOutSharp/ProtectionType/DiscGuard.cs index 01ef346e..f1b41ae0 100644 --- a/BurnOutSharp/ProtectionType/DiscGuard.cs +++ b/BurnOutSharp/ProtectionType/DiscGuard.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Linq; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -41,21 +42,28 @@ namespace BurnOutSharp.ProtectionType // Found in "IOSLinksys.dll" (Redump entries 31914, 46743, 46961, 79284, and 79374). string name = pex.FileDescription; if (name?.StartsWith("IOSLinkNT", StringComparison.OrdinalIgnoreCase) == true) - return $"DiscGuard"; + return "DiscGuard"; // Found in "T29.dll" (Redump entry 31914). name = pex.ProductName; if (name?.StartsWith("DiscGuard (tm)", StringComparison.OrdinalIgnoreCase) == true) - return $"DiscGuard"; + return "DiscGuard"; // Found in "IOSLinksys.dll" (Redump entries 31914, 46743, 46961, 79284, and 79374). name = pex.ProductName; if (name?.StartsWith("TTR Technologies Ltd. DiscGuard (tm)", StringComparison.OrdinalIgnoreCase) == true) - return $"DiscGuard"; + return "DiscGuard"; + + // Found in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374). + var resources = pex.FindStringTableByEntry("DiscGuard") + .Concat(pex.FindStringTableByEntry("The file Dg.vbn was not found.")) + .Concat(pex.FindStringTableByEntry("The file IosLink.VxD was not found.")) + .Concat(pex.FindStringTableByEntry("The file IosLink.sys was not found.")); + if (resources.Any()) + return "DiscGuard"; // Get the .vbn section, if it exists - var DiscGuardSection = pex.ReadRawSection(".vbn"); - if (DiscGuardSection != null) + if (pex.ContainsSection(".vbn")) { var matchers = new List { @@ -106,31 +114,7 @@ namespace BurnOutSharp.ProtectionType }, "DiscGuard"), }; - string match = MatchUtil.GetFirstMatch(file, DiscGuardSection, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } - - // Get the .rsrc section, if it exists - var rsrcSection = pex.ReadRawSection(".rsrc"); - if (rsrcSection != null) - { - var matchers = new List - { - // Found in "Alternate.exe" (Redump entry 31914) and "Alt.exe" (Redump entries 46743, 46961, 79284, and 79374). - // T.h.e. .f.i.l.e. .I.o.s.L.i.n.k...V.x.D. .w.a.s. .n.o.t. .f.o.u.n.d. - new ContentMatchSet(new byte?[] - { - 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x69, 0x00, - 0x6C, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6F, 0x00, 0x73, 0x00, - 0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6B, 0x00, 0x2E, 0x00, 0x56, 0x00, - 0x78, 0x00, 0x44, 0x00, 0x20, 0x00, 0x77, 0x00, 0x61, 0x00, 0x73, 0x00, - 0x20, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, - 0x6F, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x64, 0x00 - }, "DiscGuard"), - }; - - string match = MatchUtil.GetFirstMatch(file, rsrcSection, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".vbn"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/EasyAntiCheat.cs b/BurnOutSharp/ProtectionType/EasyAntiCheat.cs index 390089ef..9a942e6e 100644 --- a/BurnOutSharp/ProtectionType/EasyAntiCheat.cs +++ b/BurnOutSharp/ProtectionType/EasyAntiCheat.cs @@ -1,8 +1,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/ElectronicArts.cs b/BurnOutSharp/ProtectionType/ElectronicArts.cs index d7a75c77..a24a4a46 100644 --- a/BurnOutSharp/ProtectionType/ElectronicArts.cs +++ b/BurnOutSharp/ProtectionType/ElectronicArts.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Linq; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -29,12 +30,14 @@ namespace BurnOutSharp.ProtectionType if (name?.Equals("CDCode", StringComparison.Ordinal) == true) return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}"; - var resource = pex.FindResource(dataContains: "A\0b\0o\0u\0t\0 \0C\0D\0K\0e\0y"); - if (resource != null) + if (pex.FindDialogByTitle("About CDKey").Any()) return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}"; + else if (pex.FindGenericResource("About CDKey").Any()) + return $"EA CdKey Registration Module {Utilities.GetInternalVersion(pex)}"; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -46,13 +49,13 @@ namespace BurnOutSharp.ProtectionType }, Utilities.GetInternalVersion, "EA CdKey Registration Module"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -65,13 +68,13 @@ namespace BurnOutSharp.ProtectionType }, "EA DRM Protection"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -84,7 +87,7 @@ namespace BurnOutSharp.ProtectionType }, "EA DRM Protection"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/GFWL.cs b/BurnOutSharp/ProtectionType/GFWL.cs index 8487f3be..5068633d 100644 --- a/BurnOutSharp/ProtectionType/GFWL.cs +++ b/BurnOutSharp/ProtectionType/GFWL.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -25,7 +25,7 @@ namespace BurnOutSharp.ProtectionType return $"Games for Windows LIVE {Utilities.GetInternalVersion(pex)}"; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -33,7 +33,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x78, 0x6C, 0x69, 0x76, 0x65, 0x2E, 0x64, 0x6C, 0x6C }, "Games for Windows LIVE"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/HexaLock.cs b/BurnOutSharp/ProtectionType/HexaLock.cs index 8313d324..73ac9bd8 100644 --- a/BurnOutSharp/ProtectionType/HexaLock.cs +++ b/BurnOutSharp/ProtectionType/HexaLock.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -57,8 +57,8 @@ namespace BurnOutSharp.ProtectionType return null; } - /// - public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) + /// + public ConcurrentQueue CheckDirectoryPath(string path, IEnumerable files) { var matchers = new List { diff --git a/BurnOutSharp/ProtectionType/ImpulseReactor.cs b/BurnOutSharp/ProtectionType/ImpulseReactor.cs index 3857a103..b66fbabe 100644 --- a/BurnOutSharp/ProtectionType/ImpulseReactor.cs +++ b/BurnOutSharp/ProtectionType/ImpulseReactor.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -27,12 +27,12 @@ namespace BurnOutSharp.ProtectionType if (name?.Contains("ImpulseReactor Dynamic Link Library") == true) return $"Impulse Reactor Core Module {Utilities.GetInternalVersion(pex)}"; - name = pex.OriginalFileName; + name = pex.OriginalFilename; if (name?.Contains("ReactorActivate.exe") == true) return $"Stardock Product Activation {Utilities.GetInternalVersion(pex)}"; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { // CVPInitializeClient byte?[] check = new byte?[] @@ -41,7 +41,7 @@ namespace BurnOutSharp.ProtectionType 0x61, 0x6C, 0x69, 0x7A, 0x65, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74 }; - bool containsCheck = pex.ResourceDataSectionRaw.FirstPosition(check, out int position); + bool containsCheck = pex.GetFirstSectionData(".rdata").FirstPosition(check, out int position); // TODO: Find what resource this is in // A + (char)0x00 + T + (char)0x00 + T + (char)0x00 + L + (char)0x00 + I + (char)0x00 + S + (char)0x00 + T + (char)0x00 + (char)0x00 + (char)0x00 + E + (char)0x00 + L + (char)0x00 + E + (char)0x00 + M + (char)0x00 + E + (char)0x00 + N + (char)0x00 + T + (char)0x00 + (char)0x00 + (char)0x00 + N + (char)0x00 + O + (char)0x00 + T + (char)0x00 + A + (char)0x00 + T + (char)0x00 + I + (char)0x00 + O + (char)0x00 + N + (char)0x00 @@ -54,7 +54,7 @@ namespace BurnOutSharp.ProtectionType 0x4E, 0x00, 0x4F, 0x00, 0x54, 0x00, 0x41, 0x00, 0x54, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x4E }; - bool containsCheck2 = pex.ResourceDataSectionRaw.FirstPosition(check2, out int position2); + bool containsCheck2 = pex.GetFirstSectionData(".rdata").FirstPosition(check2, out int position2); if (containsCheck && containsCheck2) return $"Impulse Reactor Core Module {Utilities.GetInternalVersion(pex)}" + (includeDebug ? $" (Index {position}, {position2})" : string.Empty); diff --git a/BurnOutSharp/ProtectionType/Intenium.cs b/BurnOutSharp/ProtectionType/Intenium.cs index 18cc00dd..6072b6d1 100644 --- a/BurnOutSharp/ProtectionType/Intenium.cs +++ b/BurnOutSharp/ProtectionType/Intenium.cs @@ -1,5 +1,6 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Linq; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -29,8 +30,8 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - var fileNameResource = pex.FindResource(dataContains: $"NO NESTED PRMS SUPPORTED"); - if (fileNameResource != null) + var fileNameResource = pex.FindGenericResource("NO NESTED PRMS SUPPORTED"); + if (fileNameResource.Any()) return "INTENIUM Trial & Buy Protection"; return null; diff --git a/BurnOutSharp/ProtectionType/JoWood.cs b/BurnOutSharp/ProtectionType/JoWood.cs index f975eb03..fe343024 100644 --- a/BurnOutSharp/ProtectionType/JoWood.cs +++ b/BurnOutSharp/ProtectionType/JoWood.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -25,8 +25,7 @@ namespace BurnOutSharp.ProtectionType if (extSection) { // Get the .dcrtext section, if it exists - var dcrtextSectionRaw = pex.ReadRawSection(".dcrtext"); - if (dcrtextSectionRaw != null) + if (pex.ContainsSection(".dcrtext")) { var matchers = new List { @@ -40,7 +39,7 @@ namespace BurnOutSharp.ProtectionType }, GetVersion, "JoWood X-Prot"), }; - string match = MatchUtil.GetFirstMatch(file, dcrtextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".dcrtext"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/LabelGate.cs b/BurnOutSharp/ProtectionType/LabelGate.cs index d5d94824..f38d6367 100644 --- a/BurnOutSharp/ProtectionType/LabelGate.cs +++ b/BurnOutSharp/ProtectionType/LabelGate.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -18,6 +18,7 @@ namespace BurnOutSharp.ProtectionType /// public class LabelGate : IPathCheck, IPortableExecutableCheck { + /// public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible @@ -34,8 +35,9 @@ namespace BurnOutSharp.ProtectionType if (name?.StartsWith("MQSTART", StringComparison.OrdinalIgnoreCase) == true) return $"LabelGate CD2 Media Player"; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -44,7 +46,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x4C, 0x47, 0x43, 0x44, 0x32, 0x5F, 0x4C, 0x41, 0x55, 0x4E, 0x43, 0x48 }, "LabelGate CD2"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/LaserLok.cs b/BurnOutSharp/ProtectionType/LaserLok.cs index 0907c3f9..ddffc049 100644 --- a/BurnOutSharp/ProtectionType/LaserLok.cs +++ b/BurnOutSharp/ProtectionType/LaserLok.cs @@ -3,10 +3,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -64,15 +64,15 @@ namespace BurnOutSharp.ProtectionType 0x6C, 0x61, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x73, 0x2E, 0x50, 0x45 }; - int endDosStub = pex.DOSStubHeader.NewExeHeaderAddr; - bool containsCheck = pex.DOSStubHeader.ExecutableData.FirstPosition(check, out int position); + int endDosStub = (int)pex.Stub_NewExeHeaderAddr; + bool containsCheck = pex.StubExecutableData.FirstPosition(check, out int position); // If the .text section doesn't exist, then the second check can't be found bool containsCheck2 = false; int position2 = -1; // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { // GetModuleHandleA + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + GetProcAddress + (char)0x00 + (char)0x00 + (char)0x00 + (char)0x00 + LoadLibraryA + (char)0x00 + (char)0x00 + KERNEL32.dll + (char)0x00 + ëy + (char)0x01 + SNIF/MPVI byte?[] check2 = new byte?[] @@ -87,15 +87,15 @@ namespace BurnOutSharp.ProtectionType 0x45, 0x4C, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0xEB, 0x79, 0x01, null, null, null, null, }; - containsCheck2 = pex.TextSectionRaw.FirstPosition(check2, out position2); + containsCheck2 = pex.GetFirstSectionData(".text").FirstPosition(check2, out position2); } if (containsCheck && containsCheck2) - return $"LaserLok {GetVersion(pex.TextSectionRaw, position2)} {GetBuild(pex.TextSectionRaw, true)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position}, {position2})" : string.Empty); + return $"LaserLok {GetVersion(pex.GetFirstSectionData(".text"), position2)} {GetBuild(pex.GetFirstSectionData(".text"), true)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position}, {position2})" : string.Empty); else if (containsCheck && !containsCheck2) - return $"LaserLok Marathon {GetBuild(pex.TextSectionRaw, false)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position})" : string.Empty); + return $"LaserLok Marathon {GetBuild(pex.GetFirstSectionData(".text"), false)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position})" : string.Empty); else if (!containsCheck && containsCheck2) - return $"LaserLok {GetVersion(pex.TextSectionRaw, --position2)} {GetBuild(pex.TextSectionRaw, false)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position2})" : string.Empty); + return $"LaserLok {GetVersion(pex.GetFirstSectionData(".text"), --position2)} {GetBuild(pex.GetFirstSectionData(".text"), false)} [Check disc for physical ring]" + (includeDebug ? $" (Index {position2})" : string.Empty); return null; } diff --git a/BurnOutSharp/ProtectionType/Macrovision.CDilla.cs b/BurnOutSharp/ProtectionType/Macrovision.CDilla.cs index d5478b91..f434dd9e 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.CDilla.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.CDilla.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; -using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -38,9 +34,8 @@ namespace BurnOutSharp.ProtectionType /// public string CDillaCheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; // TODO: Implement NE checks for "CDILLA05", "CDILLA10", "CDILLA16", and "CDILLA40". @@ -73,8 +68,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -86,7 +82,7 @@ namespace BurnOutSharp.ProtectionType 0x5C, 0x52, 0x54, 0x53 }, "C-Dilla License Management System"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/Macrovision.CactusDataShield.cs b/BurnOutSharp/ProtectionType/Macrovision.CactusDataShield.cs index af76cb3d..0d96045d 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.CactusDataShield.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.CactusDataShield.cs @@ -2,10 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/Macrovision.FLEXnet.cs b/BurnOutSharp/ProtectionType/Macrovision.FLEXnet.cs index 879507f5..1a811800 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.FLEXnet.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.FLEXnet.cs @@ -1,11 +1,5 @@ using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; -using BurnOutSharp.Matching; -using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/Macrovision.SafeCast.cs b/BurnOutSharp/ProtectionType/Macrovision.SafeCast.cs index 6a17bf0c..b295ba2e 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.SafeCast.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.SafeCast.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; -using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -37,9 +33,8 @@ namespace BurnOutSharp.ProtectionType /// public string SafeCastCheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; // TODO: Implement the following NE checks: @@ -59,8 +54,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -73,7 +69,7 @@ namespace BurnOutSharp.ProtectionType 0x74 }, "SafeCast"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/Macrovision.SafeDisc.cs b/BurnOutSharp/ProtectionType/Macrovision.SafeDisc.cs index 4c9d0ad4..97e572aa 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.SafeDisc.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.SafeDisc.cs @@ -2,10 +2,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/Macrovision.cs b/BurnOutSharp/ProtectionType/Macrovision.cs index 5c3cd6c1..5d01f0f1 100644 --- a/BurnOutSharp/ProtectionType/Macrovision.cs +++ b/BurnOutSharp/ProtectionType/Macrovision.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.IO; -using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.NE; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; -using static System.Net.WebRequestMethods; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -20,9 +16,8 @@ namespace BurnOutSharp.ProtectionType /// public string CheckNewExecutable(string file, NewExecutable nex, bool includeDebug) { - // Get the DOS stub from the executable, if possible - var stub = nex?.DOSStubHeader; - if (stub == null) + // Check we have a valid executable + if (nex == null) return null; List resultsList = new List(); @@ -195,7 +190,7 @@ namespace BurnOutSharp.ProtectionType return $"SafeDisc SRV Tool APP {GetSafeDiscDiagExecutableVersion(pex)}"; // This subtract is needed because BoG_ starts before the section - var sectionRaw = pex.ReadRawSection(sectionName, first: true, offset: -64); + var sectionRaw = pex.GetFirstSectionDataWithOffset(sectionName, offset: -64); if (sectionRaw != null) { // TODO: Add more checks to help differentiate between SafeDisc and SafeCast. diff --git a/BurnOutSharp/ProtectionType/MediaCloQ.cs b/BurnOutSharp/ProtectionType/MediaCloQ.cs index e7f0a9b2..09a572b9 100644 --- a/BurnOutSharp/ProtectionType/MediaCloQ.cs +++ b/BurnOutSharp/ProtectionType/MediaCloQ.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/MediaMaxCD3.cs b/BurnOutSharp/ProtectionType/MediaMaxCD3.cs index 339194fb..1d956fe7 100644 --- a/BurnOutSharp/ProtectionType/MediaMaxCD3.cs +++ b/BurnOutSharp/ProtectionType/MediaMaxCD3.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Linq; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -32,12 +33,17 @@ namespace BurnOutSharp.ProtectionType if (name?.StartsWith("LicGen Module", StringComparison.OrdinalIgnoreCase) == true) return $"MediaMax CD-3"; - var resource = pex.FindResource(dataContains: "Cd3Ctl"); - if (resource != null) + var cd3CtrlResources = pex.FindGenericResource("Cd3Ctl"); + if (cd3CtrlResources.Any()) + return $"MediaMax CD-3"; + + var limitedProductionResources = pex.FindDialogBoxByItemTitle("This limited production advanced CD is not playable on your computer. It is solely intended for playback on standard CD players."); + if (limitedProductionResources.Any()) return $"MediaMax CD-3"; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -49,13 +55,13 @@ namespace BurnOutSharp.ProtectionType }, "MediaMax CD-3"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -67,7 +73,7 @@ namespace BurnOutSharp.ProtectionType }, "MediaMax CD-3"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/OnlineRegistration.cs b/BurnOutSharp/ProtectionType/OnlineRegistration.cs index c314cd8e..ca1c7ffb 100644 --- a/BurnOutSharp/ProtectionType/OnlineRegistration.cs +++ b/BurnOutSharp/ProtectionType/OnlineRegistration.cs @@ -1,7 +1,7 @@ using System; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/OpenMG.cs b/BurnOutSharp/ProtectionType/OpenMG.cs index ac2d78a9..76cbed2a 100644 --- a/BurnOutSharp/ProtectionType/OpenMG.cs +++ b/BurnOutSharp/ProtectionType/OpenMG.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -16,6 +16,7 @@ namespace BurnOutSharp.ProtectionType /// public class OpenMG : IPathCheck, IPortableExecutableCheck { + /// public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible diff --git a/BurnOutSharp/ProtectionType/Origin.cs b/BurnOutSharp/ProtectionType/Origin.cs index 75e57461..9d76dd5b 100644 --- a/BurnOutSharp/ProtectionType/Origin.cs +++ b/BurnOutSharp/ProtectionType/Origin.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/PlayJ.cs b/BurnOutSharp/ProtectionType/PlayJ.cs index 53f8b26c..29bd3f7f 100644 --- a/BurnOutSharp/ProtectionType/PlayJ.cs +++ b/BurnOutSharp/ProtectionType/PlayJ.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -29,6 +29,7 @@ namespace BurnOutSharp.ProtectionType /// public class PlayJ : IPathCheck, IPortableExecutableCheck { + /// public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible @@ -38,15 +39,17 @@ namespace BurnOutSharp.ProtectionType // Found in "PlayJ.exe" (https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe) and "CACTUSPJ.exe" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])). string name = pex.FileDescription; - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("PlayJ Music Player", StringComparison.OrdinalIgnoreCase)) + if (name?.StartsWith("PlayJ Music Player", StringComparison.OrdinalIgnoreCase) == true) return $"PlayJ Music Player"; + // Found in "PJSTREAM.DLL" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])). name = pex.FileDescription; - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("EVAUX32 Module", StringComparison.OrdinalIgnoreCase)) + if (name.StartsWith("EVAUX32 Module", StringComparison.OrdinalIgnoreCase) == true) return $"PlayJ Music Player Component"; + // Found in "PlayJ.exe" (https://web.archive.org/web/20010417025347/http://dlp.playj.com:80/playj/PlayJIns266.exe) and "CACTUSPJ.exe" ("Volumia!" by Puur (Barcode 7 43218 63282 2) (Discogs Release Code [r795427])). name = pex.ProductName; - if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("PlayJ", StringComparison.OrdinalIgnoreCase)) + if (name?.StartsWith("PlayJ", StringComparison.OrdinalIgnoreCase) == true) return $"PlayJ"; return null; diff --git a/BurnOutSharp/ProtectionType/ProtectDisc.cs b/BurnOutSharp/ProtectionType/ProtectDisc.cs index 7bf41da1..8d5d61ed 100644 --- a/BurnOutSharp/ProtectionType/ProtectDisc.cs +++ b/BurnOutSharp/ProtectionType/ProtectDisc.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Text; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -18,12 +19,11 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the 4th section, if it exists (example names: ACE4) (Found in Redump entry 94793) - var fourthSection = sections.Length < 4 ? null : sections[3]; - if (fourthSection != null) + // Get the 4th and 5th sections, if they exist (example names: ACE4/ACE5) (Found in Redump entries 94792, 94793) + for (int i = 3; i < sections.Length; i++) { - var fourthSectionData = pex.ReadRawSection(fourthSection.NameString, first: true); - if (fourthSectionData != null) + var nthSectionData = pex.GetSectionData(i); + if (nthSectionData != null) { var matchers = new List { @@ -31,33 +31,15 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDISC"), }; - string match = MatchUtil.GetFirstMatch(file, fourthSectionData, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, nthSectionData, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } } - // Get the 5th section, if it exists (example names: ACE5) (Found in Redump entry 94792) - var fifthSection = sections.Length < 5 ? null : sections[4]; - if (fifthSection != null) - { - var fifthSectionData = pex.ReadRawSection(fifthSection.NameString, first: true); - if (fifthSectionData != null) - { - var matchers = new List - { - // ACE-PCD - new ContentMatchSet(new byte?[] { 0x41, 0x43, 0x45, 0x2D, 0x50, 0x43, 0x44 }, GetVersion6till8, "ProtectDISC"), - }; - - string match = MatchUtil.GetFirstMatch(file, fifthSectionData, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } - } - - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -65,7 +47,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x44, 0x43, 0x50, 0x2D, 0x42, 0x4F, 0x56, 0x00, 0x00 }, GetVersion3till6, "VOB ProtectCD/DVD"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } @@ -74,7 +56,7 @@ namespace BurnOutSharp.ProtectionType var secondToLastSection = sections.Length > 1 ? sections[sections.Length - 2] : null; if (secondToLastSection != null) { - var secondToLastSectionData = pex.ReadRawSection(secondToLastSection.NameString, first: true); + var secondToLastSectionData = pex.GetSectionData(sections.Length - 2); if (secondToLastSectionData != null) { var matchers = new List @@ -96,11 +78,13 @@ namespace BurnOutSharp.ProtectionType } } + // TODO: Be better about finding the last section // Get the last section (example names: ACE5, akxpxgcv, and piofinqb) var lastSection = sections.LastOrDefault(); if (lastSection != null) { - var lastSectionData = pex.ReadRawSection(lastSection.NameString, first: true); + string lastSectionName = Encoding.UTF8.GetString(lastSection.Name).TrimEnd('\0'); + var lastSectionData = pex.GetFirstSectionData(lastSectionName); if (lastSectionData != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/RainbowSentinel.cs b/BurnOutSharp/ProtectionType/RainbowSentinel.cs index c46f385a..0adb6558 100644 --- a/BurnOutSharp/ProtectionType/RainbowSentinel.cs +++ b/BurnOutSharp/ProtectionType/RainbowSentinel.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -30,8 +30,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -45,13 +46,13 @@ namespace BurnOutSharp.ProtectionType }, "Rainbow Sentinel SuperPro"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -74,7 +75,7 @@ namespace BurnOutSharp.ProtectionType }, "Rainbow Sentinel SuperPro"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/SVKP.cs b/BurnOutSharp/ProtectionType/SVKP.cs index add8f89e..ef6670dc 100644 --- a/BurnOutSharp/ProtectionType/SVKP.cs +++ b/BurnOutSharp/ProtectionType/SVKP.cs @@ -1,5 +1,5 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; +using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -13,12 +13,13 @@ namespace BurnOutSharp.ProtectionType /// public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { - // Get the image file header from the executable, if possible - if (pex?.ImageFileHeader == null) + // Get the sections from the executable, if possible + var sections = pex?.SectionTable; + if (sections == null) return null; - + // 0x504B5653 is "SVKP" - if (pex.ImageFileHeader.PointerToSymbolTable == 0x504B5653) + if (pex.PointerToSymbolTable == 0x504B5653) return "SVKP (Slovak Protector)"; return null; diff --git a/BurnOutSharp/ProtectionType/SecuROM.cs b/BurnOutSharp/ProtectionType/SecuROM.cs index b1c7f99c..4c1479c1 100644 --- a/BurnOutSharp/ProtectionType/SecuROM.cs +++ b/BurnOutSharp/ProtectionType/SecuROM.cs @@ -2,10 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -44,7 +44,7 @@ namespace BurnOutSharp.ProtectionType return $"SecuROM SLL Protected (for SecuROM v8.x)"; // Search after the last section - if (pex.OverlayRaw != null) + if (pex.Overlay != null) { var matchers = new List { @@ -52,7 +52,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x41, 0x64, 0x64, 0x44, 0x03, 0x00, 0x00, 0x00 }, GetV4Version, "SecuROM"), }; - string match = MatchUtil.GetFirstMatch(file, pex.OverlayRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.Overlay, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } @@ -61,10 +61,10 @@ namespace BurnOutSharp.ProtectionType for (int i = 4; i < sections.Length; i++) { var nthSection = sections[i]; - string nthSectionName = nthSection.NameString; + string nthSectionName = Encoding.UTF8.GetString(nthSection.Name).TrimEnd('\0'); if (nthSection != null && nthSectionName != ".idata" && nthSectionName != ".rsrc") { - var nthSectionData = pex.ReadRawSection(nthSectionName, first: true); + var nthSectionData = pex.GetFirstSectionData(nthSectionName); if (nthSectionData != null) { var matchers = new List @@ -81,7 +81,7 @@ namespace BurnOutSharp.ProtectionType } // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -112,7 +112,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x53, 0x65, 0x63, 0x75, 0x45, 0x78, 0x70 }, "WHITELABEL"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) { if (match.StartsWith("WHITELABEL")) @@ -240,7 +240,7 @@ namespace BurnOutSharp.ProtectionType private static string GetV7Version(PortableExecutable pex) { int index = 172; // 64 bytes for DOS stub, 236 bytes in total - byte[] bytes = new ReadOnlySpan(pex.DOSStubHeader.ExecutableData, index, 4).ToArray(); + byte[] bytes = new ReadOnlySpan(pex.StubExecutableData, index, 4).ToArray(); //SecuROM 7 new and 8 if (bytes[3] == 0x5C) // if (bytes[0] == 0xED && bytes[3] == 0x5C { @@ -252,15 +252,16 @@ namespace BurnOutSharp.ProtectionType else { index = 58; // 64 bytes for DOS stub, 122 bytes in total - bytes = new ReadOnlySpan(pex.DOSStubHeader.ExecutableData, index, 2).ToArray(); + bytes = new ReadOnlySpan(pex.StubExecutableData, index, 2).ToArray(); return $"7.{bytes[0] ^ 0x10:00}.{bytes[1] ^ 0x10:0000}"; //return "7.01-7.10" } } private static string GetV8WhiteLabelVersion(PortableExecutable pex) { - // If we don't have a data section, we default to generic - if (pex.DataSectionRaw == null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) return "8"; // Search .data for the version indicator @@ -274,13 +275,13 @@ namespace BurnOutSharp.ProtectionType 0x82, 0xD8, 0x0C, 0xAC }); - (bool success, int position) = matcher.Match(pex.DataSectionRaw); + (bool success, int position) = matcher.Match(dataSectionRaw); // If we can't find the string, we default to generic if (!success) return "8"; - byte[] bytes = new ReadOnlySpan(pex.DataSectionRaw, position + 0xAC, 3).ToArray(); + byte[] bytes = new ReadOnlySpan(dataSectionRaw, position + 0xAC, 3).ToArray(); return $"{bytes[0] ^ 0xCA}.{bytes[1] ^ 0x39:00}.{bytes[2] ^ 0x51:0000}"; } } diff --git a/BurnOutSharp/ProtectionType/SmartE.cs b/BurnOutSharp/ProtectionType/SmartE.cs index be068f3a..4ac8b02a 100644 --- a/BurnOutSharp/ProtectionType/SmartE.cs +++ b/BurnOutSharp/ProtectionType/SmartE.cs @@ -1,10 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.ExecutableType.Microsoft.PE.Headers; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -18,26 +17,25 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .edata section, if it exists - string match = GetMatchForSection(file, pex.ExportDataSectionRaw, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; + // Get the last section + var lastSetionData = pex.GetSectionData(sections.Length); + if (lastSetionData != null) + { + var matchers = new List + { + // BITARTS + new ContentMatchSet( + new ContentMatch( + new byte?[] { 0x42, 0x49, 0x54, 0x41, 0x52, 0x54, 0x53 }, + start: 18319, + end: 18320), + "SmartE"), + }; - // Get the .idata section, if it exists - match = GetMatchForSection(file, pex.ImportDataSectionRaw, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - - // Get the .rdata section, if it exists - match = GetMatchForSection(file, pex.ResourceDataSectionRaw, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - - // Get the .tls section, if it exists - var tlsSectionRaw = pex.ReadRawSection(".tls", first: false); - match = GetMatchForSection(file, tlsSectionRaw, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; + string match = MatchUtil.GetFirstMatch(file, lastSetionData, matchers, includeDebug); + if (!string.IsNullOrWhiteSpace(match)) + return match; + } return null; } @@ -68,43 +66,5 @@ namespace BurnOutSharp.ProtectionType return MatchUtil.GetFirstMatch(path, matchers, any: true); } - - /// - /// Check a section for the SmartE string(s) - /// - private string GetMatchForSection(SectionHeader section, string file, byte[] sectionContent, bool includeDebug) - { - if (section == null) - return null; - - int sectionAddr = (int)section.PointerToRawData; - int sectionEnd = sectionAddr + (int)section.VirtualSize; - var matchers = new List - { - // BITARTS - new ContentMatchSet( - new ContentMatch(new byte?[] { 0x42, 0x49, 0x54, 0x41, 0x52, 0x54, 0x53 }, start: sectionAddr, end: sectionEnd), - "SmartE"), - }; - - return MatchUtil.GetFirstMatch(file, sectionContent, matchers, includeDebug); - } - - /// - /// Check a section for the SmartE string(s) - /// - private string GetMatchForSection(string file, byte[] sectionContent, bool includeDebug) - { - if (sectionContent == null) - return null; - - var matchers = new List - { - // BITARTS - new ContentMatchSet(new byte?[] { 0x42, 0x49, 0x54, 0x41, 0x52, 0x54, 0x53 }, "SmartE"), - }; - - return MatchUtil.GetFirstMatch(file, sectionContent, matchers, includeDebug); - } } } diff --git a/BurnOutSharp/ProtectionType/SolidShield.cs b/BurnOutSharp/ProtectionType/SolidShield.cs index f381f658..a3dfcbae 100644 --- a/BurnOutSharp/ProtectionType/SolidShield.cs +++ b/BurnOutSharp/ProtectionType/SolidShield.cs @@ -3,10 +3,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -53,8 +53,7 @@ namespace BurnOutSharp.ProtectionType return $"SolidShield {GetInternalVersion(pex)}"; // Get the .init section, if it exists - var initSectionRaw = pex.ReadRawSection(".init", first: true); - if (initSectionRaw != null) + if (pex.ContainsSection(".init")) { var matchers = new List { @@ -68,21 +67,21 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x64, 0x76, 0x6D, 0x2E, 0x64, 0x6C, 0x6C }, "SolidShield EXE Wrapper v1"), }; - string match = MatchUtil.GetFirstMatch(file, initSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".init"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } // Get the wrapper resource, if it exists - var resource = pex.FindResource(dataContains: "B\0I\0N\0" + (char)0x07 + "\0I\0D\0R\0_\0S\0G\0T\0"); - if (resource != null) + var wrapperResources = pex.FindResourceByNamedType("BIN, IDR_SGT"); + if (wrapperResources.Any()) return "SolidShield EXE Wrapper v1"; // Search the last two available sections - var sectionNames = pex.GetSectionNames(); + var sectionNames = pex.SectionNames; for (int i = (sectionNames.Length >= 2 ? sectionNames.Length - 2 : 0); i < sectionNames.Length; i++) { - var nthSectionRaw = pex.ReadRawSection(sectionNames[i], first: false); + var nthSectionRaw = pex.GetLastSectionData(sectionNames[i]); if (nthSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/StarForce.cs b/BurnOutSharp/ProtectionType/StarForce.cs index fde08f76..8b9ab205 100644 --- a/BurnOutSharp/ProtectionType/StarForce.cs +++ b/BurnOutSharp/ProtectionType/StarForce.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; -using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -36,34 +35,6 @@ namespace BurnOutSharp.ProtectionType // TODO: Check to see if there are any missing checks // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/StarForce.2.sg - // TODO: Find this inside of the .rsrc section using the executable header - // Get the .rsrc section, if it exists - var rsrcSection = pex.GetLastSection(".rsrc", exact: true); - if (rsrcSection != null) - { - var rsrcSectionData = pex.ReadRawSection(".rsrc", first: true); - if (rsrcSectionData != null) - { - var matchers = new List - { - // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + e + (char)0x00 + d + (char)0x00 + + (char)0x00 + M + (char)0x00 + o + (char)0x00 + d + (char)0x00 + u + (char)0x00 + l + (char)0x00 + e + (char)0x00 - new ContentMatchSet( - new byte?[] - { - 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x74, 0x00, - 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x64, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, - 0x64, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x65, 0x00 - }, - "StarForce 5 [Protected Module]"), - }; - - string match = MatchUtil.GetFirstMatch(file, rsrcSectionData, matchers, includeDebug); - if (!string.IsNullOrWhiteSpace(match)) - return match; - } - } - // Get the .brick section, if it exists bool brickSection = pex.ContainsSection(".brick", exact: true); if (brickSection) @@ -106,43 +77,5 @@ namespace BurnOutSharp.ProtectionType // return MatchUtil.GetFirstMatch(path, matchers, any: true); return null; } - - // This section contains extraneous checks in the .rsrc section that have not been confirmed - // new ContentMatchSet(new List - // { - // // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + T + (char)0x00 + e + (char)0x00 + c + (char)0x00 + h + (char)0x00 + n + (char)0x00 + o + (char)0x00 + l + (char)0x00 + o + (char)0x00 + g + (char)0x00 + y + (char)0x00 - // new ContentMatch(new byte?[] - // { - // 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00, - // 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, - // 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00, - // 0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00, - // 0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, - // 0x79, 0x00 - // }, start: sectionAddr, end: sectionEnd), - - // // // PSA_GetDiscLabel - // // new ContentMatch(new byte?[] - // // { - // // 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44, - // // 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C - // // }, start: sectionAddr, end: sectionEnd), - - // // (c) Protection Technology - // // new ContentMatch(new byte?[] - // // { - // // 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74, - // // 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54, - // // 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, - // // 0x79 - // // }, start: sectionAddr, end: sectionEnd), - - // // TradeName - // new ContentMatch(new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 }, start: sectionAddr, end: sectionEnd), - // }, GetVersion, "StarForce"), - // public static string GetVersion(string file, byte[] fileContent, List positions) - // { - // return $"{Utilities.GetInternalVersion(fileContent)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})"; - // } } } diff --git a/BurnOutSharp/ProtectionType/StarForceRSRC.cs b/BurnOutSharp/ProtectionType/StarForceRSRC.cs new file mode 100644 index 00000000..9a456f14 --- /dev/null +++ b/BurnOutSharp/ProtectionType/StarForceRSRC.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Linq; +using BurnOutSharp.Interfaces; +using BurnOutSharp.Matching; +using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; + +namespace BurnOutSharp.ProtectionType +{ + public class StarForceRSRC : IPortableExecutableCheck + { + /// + public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) + { + // Get the sections from the executable, if possible + var sections = pex?.SectionTable; + if (sections == null) + return null; + + // Get the .rsrc section, if it exists + var rsrcSection = pex.GetLastSection(".rsrc", exact: true); + if (rsrcSection != null) + { + var rsrcSectionData = pex.GetLastSectionData(".rsrc"); + if (rsrcSectionData != null) + { + var matchers = new List + { + // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + e + (char)0x00 + d + (char)0x00 + + (char)0x00 + M + (char)0x00 + o + (char)0x00 + d + (char)0x00 + u + (char)0x00 + l + (char)0x00 + e + (char)0x00 + new ContentMatchSet( + new byte?[] + { + 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x74, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x64, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, + 0x64, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x65, 0x00 + }, + "StarForce 5 [**Protected Module**] (Unconfirmed - Please report to us on Github)"), + + new ContentMatchSet(new List + { + // P + (char)0x00 + r + (char)0x00 + o + (char)0x00 + t + (char)0x00 + e + (char)0x00 + c + (char)0x00 + t + (char)0x00 + i + (char)0x00 + o + (char)0x00 + n + (char)0x00 + + (char)0x00 + T + (char)0x00 + e + (char)0x00 + c + (char)0x00 + h + (char)0x00 + n + (char)0x00 + o + (char)0x00 + l + (char)0x00 + o + (char)0x00 + g + (char)0x00 + y + (char)0x00 + new ContentMatch(new byte?[] + { + 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x74, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, + 0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x54, 0x00, + 0x65, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6E, 0x00, + 0x6F, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x67, 0x00, + 0x79, 0x00 + }), + + // // PSA_GetDiscLabel + new ContentMatch(new byte?[] + { + 0x50, 0x53, 0x41, 0x5F, 0x47, 0x65, 0x74, 0x44, + 0x69, 0x73, 0x63, 0x4C, 0x61, 0x62, 0x65, 0x6C + }), + + // (c) Protection Technology + new ContentMatch(new byte?[] + { + 0x28, 0x63, 0x29, 0x20, 0x50, 0x72, 0x6F, 0x74, + 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, + 0x79 + }), + + // TradeName + new ContentMatch(new byte?[] { 0x54, 0x72, 0x61, 0x64, 0x65, 0x4E, 0x61, 0x6D, 0x65 }), + }, GetVersion, "StarForce [**Large Combined Check**] (Unconfirmed - Please report to us on Github)"), + }; + + string match = string.Join(", ", MatchUtil.GetAllMatches(file, rsrcSectionData, matchers, includeDebug)); + if (!string.IsNullOrWhiteSpace(match)) + return match; + } + } + + return null; + } + + public static string GetVersion(string file, byte[] fileContent, List positions) + { + return $"{Utilities.GetInternalVersion(file)} ({fileContent.Skip(positions[1] + 22).TakeWhile(c => c != 0x00)})"; + } + } +} diff --git a/BurnOutSharp/ProtectionType/Steam.cs b/BurnOutSharp/ProtectionType/Steam.cs index 39661f09..2944c65b 100644 --- a/BurnOutSharp/ProtectionType/Steam.cs +++ b/BurnOutSharp/ProtectionType/Steam.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/Sysiphus.cs b/BurnOutSharp/ProtectionType/Sysiphus.cs index 77bb2771..383f62c6 100644 --- a/BurnOutSharp/ProtectionType/Sysiphus.cs +++ b/BurnOutSharp/ProtectionType/Sysiphus.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -17,8 +17,9 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -30,7 +31,7 @@ namespace BurnOutSharp.ProtectionType }, GetVersion, "Sysiphus"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/Tages.cs b/BurnOutSharp/ProtectionType/Tages.cs index 8fee4282..8081db1f 100644 --- a/BurnOutSharp/ProtectionType/Tages.cs +++ b/BurnOutSharp/ProtectionType/Tages.cs @@ -2,10 +2,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; using BurnOutSharp.Tools; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -44,8 +44,9 @@ namespace BurnOutSharp.ProtectionType // TODO: Add entry point check // https://github.com/horsicq/Detect-It-Easy/blob/master/db/PE/Tages.2.sg - // Get the .data section, if it exists - if (pex.DataSectionRaw != null) + // Get the .data/DATA section, if it exists + var dataSectionRaw = pex.GetFirstSectionData(".data") ?? pex.GetFirstSectionData("DATA"); + if (dataSectionRaw != null) { var matchers = new List { @@ -53,7 +54,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0xE8, 0x75, 0x00, 0x00, 0x00, 0xE8, null, null, 0xFF, 0xFF, 0x68 }, GetVersion, "TAGES"), }; - string match = MatchUtil.GetFirstMatch(file, pex.DataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, dataSectionRaw, matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/Themida.cs b/BurnOutSharp/ProtectionType/Themida.cs index cf37aba2..d4846607 100644 --- a/BurnOutSharp/ProtectionType/Themida.cs +++ b/BurnOutSharp/ProtectionType/Themida.cs @@ -1,7 +1,7 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Collections.Generic; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; -using System.Collections.Generic; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -35,8 +35,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the "Arcsoft " section, if it exists - var initSectionRaw = pex.ReadRawSection("Arcsoft ", first: true); - if (initSectionRaw != null) + if (pex.ContainsSection("Arcsoft ")) { var matchers = new List { @@ -46,7 +45,7 @@ namespace BurnOutSharp.ProtectionType new ContentMatchSet(new byte?[] { 0x54, 0x68, 0x65, 0x6D, 0x69, 0x64, 0x61 }, "Themida"), }; - string match = MatchUtil.GetFirstMatch(file, initSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData("Arcsoft "), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/ThreePLock.cs b/BurnOutSharp/ProtectionType/ThreePLock.cs index a85188a9..95e06e57 100644 --- a/BurnOutSharp/ProtectionType/ThreePLock.cs +++ b/BurnOutSharp/ProtectionType/ThreePLock.cs @@ -1,5 +1,5 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; -using BurnOutSharp.Interfaces; +using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/ThreeTwoOneStudios.cs b/BurnOutSharp/ProtectionType/ThreeTwoOneStudios.cs index a0936541..27880e8c 100644 --- a/BurnOutSharp/ProtectionType/ThreeTwoOneStudios.cs +++ b/BurnOutSharp/ProtectionType/ThreeTwoOneStudios.cs @@ -1,5 +1,6 @@ -using BurnOutSharp.ExecutableType.Microsoft.PE; +using System.Linq; using BurnOutSharp.Interfaces; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -13,8 +14,10 @@ namespace BurnOutSharp.ProtectionType if (sections == null) return null; - var resource = pex.FindResource(dataContains: "3\02\01\0S\0t\0u\0d\0i\0o\0s\0 \0A\0c\0t\0i\0v\0a\0t\0i\0o\0n\0"); - if (resource != null) + // Check the dialog box resources + if (pex.FindDialogByTitle("321Studios Activation").Any()) + return $"321Studios Online Activation"; + else if (pex.FindDialogByTitle("321Studios Phone Activation").Any()) return $"321Studios Online Activation"; return null; diff --git a/BurnOutSharp/ProtectionType/Uplay.cs b/BurnOutSharp/ProtectionType/Uplay.cs index 59ac08a2..14d0dc73 100644 --- a/BurnOutSharp/ProtectionType/Uplay.cs +++ b/BurnOutSharp/ProtectionType/Uplay.cs @@ -1,8 +1,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { diff --git a/BurnOutSharp/ProtectionType/WMDS.cs b/BurnOutSharp/ProtectionType/WMDS.cs index a2a61b5c..483e147d 100644 --- a/BurnOutSharp/ProtectionType/WMDS.cs +++ b/BurnOutSharp/ProtectionType/WMDS.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -15,6 +15,7 @@ namespace BurnOutSharp.ProtectionType /// public class WMDS : IPathCheck, IPortableExecutableCheck { + /// public string CheckPortableExecutable(string file, PortableExecutable pex, bool includeDebug) { // Get the sections from the executable, if possible @@ -28,7 +29,7 @@ namespace BurnOutSharp.ProtectionType return $"Windows Media Data Session DRM"; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -47,7 +48,7 @@ namespace BurnOutSharp.ProtectionType }, "Windows Media Data Session DRM"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/WTMCDProtect.cs b/BurnOutSharp/ProtectionType/WTMCDProtect.cs index 10463e88..4150b1d8 100644 --- a/BurnOutSharp/ProtectionType/WTMCDProtect.cs +++ b/BurnOutSharp/ProtectionType/WTMCDProtect.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -25,8 +25,8 @@ namespace BurnOutSharp.ProtectionType if (!string.IsNullOrEmpty(name) && name.Contains("WTM Copy Protection Viewer")) return "WTM Protection Viewer"; - // Get the CODE section, if it exists - var codeSectionRaw = pex.ReadRawSection("CODE", first: true); + // Get the code/CODE section, if it exists + var codeSectionRaw = pex.GetFirstSectionData("code") ?? pex.GetFirstSectionData("CODE"); if (codeSectionRaw != null) { var matchers = new List @@ -45,7 +45,7 @@ namespace BurnOutSharp.ProtectionType } // Get the .text section, if it exists - if (pex.TextSectionRaw != null) + if (pex.ContainsSection(".text")) { var matchers = new List { @@ -68,7 +68,7 @@ namespace BurnOutSharp.ProtectionType }, "WTM Protection Viewer"), }; - string match = MatchUtil.GetFirstMatch(file, pex.TextSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".text"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/ProtectionType/XCP.cs b/BurnOutSharp/ProtectionType/XCP.cs index 8f3366cb..862e2d3a 100644 --- a/BurnOutSharp/ProtectionType/XCP.cs +++ b/BurnOutSharp/ProtectionType/XCP.cs @@ -3,10 +3,10 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using BurnOutSharp.ExecutableType.Microsoft.PE; using BurnOutSharp.FileType; using BurnOutSharp.Interfaces; using BurnOutSharp.Matching; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.ProtectionType { @@ -22,7 +22,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the .rdata section, if it exists - if (pex.ResourceDataSectionRaw != null) + if (pex.ContainsSection(".rdata")) { var matchers = new List { @@ -47,7 +47,7 @@ namespace BurnOutSharp.ProtectionType }, "XCP"), }; - string match = MatchUtil.GetFirstMatch(file, pex.ResourceDataSectionRaw, matchers, includeDebug); + string match = MatchUtil.GetFirstMatch(file, pex.GetFirstSectionData(".rdata"), matchers, includeDebug); if (!string.IsNullOrWhiteSpace(match)) return match; } diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs index 7cc9af88..2ffa4e2e 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using BurnOutSharp.FileType; using BurnOutSharp.Tools; @@ -48,6 +49,9 @@ namespace BurnOutSharp ScanPackers = scanPackers; IncludeDebug = includeDebug; this.fileProgress = fileProgress; + + // Register the codepages + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); } #region Scanning diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs index 8e44ad69..90ef4d2d 100644 --- a/BurnOutSharp/Tools/Utilities.cs +++ b/BurnOutSharp/Tools/Utilities.cs @@ -5,7 +5,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Security.Cryptography; -using BurnOutSharp.ExecutableType.Microsoft.PE; +using BurnOutSharp.Wrappers; namespace BurnOutSharp.Tools { @@ -179,19 +179,6 @@ namespace BurnOutSharp.Tools #region Processed Executable Information - /// - /// Get the internal version as reported by the resources - /// - /// Byte array representing the file contents - /// Version string, null on error - public static string GetInternalVersion(byte[] fileContent) - { - if (fileContent == null || !fileContent.Any()) - return null; - - return GetInternalVersion(new PortableExecutable(fileContent, 0)); - } - /// /// Get the internal version as reported by the resources /// @@ -201,13 +188,13 @@ namespace BurnOutSharp.Tools { string version = pex.FileVersion; if (!string.IsNullOrWhiteSpace(version)) - return version; + return version.Replace(", ", "."); version = pex.ProductVersion; if (!string.IsNullOrWhiteSpace(version)) - return version; + return version.Replace(", ", "."); - version = pex.ManifestVersion; + version = pex.AssemblyVersion; if (!string.IsNullOrWhiteSpace(version)) return version; @@ -306,7 +293,7 @@ namespace BurnOutSharp.Tools /// Byte array representing the file contents /// Last matched positions in the contents /// Version string, null on error - public static string GetInternalVersion(string file, byte[] fileContent, List positions) => GetInternalVersion(fileContent); + public static string GetInternalVersion(string file, byte[] fileContent, List positions) => GetInternalVersion(file); /// /// Wrapper for GetInternalVersion for use in path matching