diff --git a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs index 8b048258..82bbcbc1 100644 --- a/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs +++ b/BurnOutSharp/ExecutableType/Microsoft/PortableExecutable.cs @@ -176,6 +176,34 @@ namespace BurnOutSharp.ExecutableType.Microsoft return sectionNames.Any(n => n.Trim('\0').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 /// @@ -230,13 +258,27 @@ namespace BurnOutSharp.ExecutableType.Microsoft return SectionTable.Select(s => Encoding.ASCII.GetString(s.Name)).ToArray(); } + /// + /// Print all sections, including their start and end addresses + /// + public void PrintAllSections() + { + foreach (var section in SectionTable) + { + string sectionName = Encoding.ASCII.GetString(section.Name).Trim('\0'); + int sectionAddr = (int)section.PointerToRawData; + int sectionEnd = sectionAddr + (int)section.VirtualSize; + Console.WriteLine($"{sectionName}: {sectionAddr} -> {sectionEnd}"); + } + } + /// /// Get the raw bytes from a section, if possible /// - public byte[] ReadRawSection(Stream stream, string sectionName, bool first = true, int offset = 0) + public byte[] ReadRawSection(Stream stream, string sectionName, bool force = false, bool first = true, int offset = 0) { - // Special cases for non-offset data - if (offset == 0) + // Special cases for non-forced, non-offset data + if (!force && offset == 0) { switch (sectionName) { @@ -274,10 +316,10 @@ namespace BurnOutSharp.ExecutableType.Microsoft /// /// Get the raw bytes from a section, if possible /// - public byte[] ReadRawSection(byte[] content, string sectionName, bool first = true, int offset = 0) + public byte[] ReadRawSection(byte[] content, string sectionName, bool force = false, bool first = true, int offset = 0) { - // Special cases for non-offset data - if (offset == 0) + // Special cases for non-forced, non-offset data + if (!force && offset == 0) { switch (sectionName) { @@ -304,34 +346,6 @@ namespace BurnOutSharp.ExecutableType.Microsoft return content.ReadBytes(ref startingIndex, readLength); } - /// - /// 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; - } - #endregion public static PortableExecutable Deserialize(Stream stream) @@ -396,19 +410,19 @@ namespace BurnOutSharp.ExecutableType.Microsoft #region Freeform Sections // Data Section - pex.DataSectionRaw = pex.ReadRawSection(stream, ".data", false) ?? pex.ReadRawSection(stream, "DATA", false); + pex.DataSectionRaw = pex.ReadRawSection(stream, ".data", force: true, first: false) ?? pex.ReadRawSection(stream, "DATA", force: true, first: false); // Export Table - pex.ExportDataSectionRaw = pex.ReadRawSection(stream, ".edata", false); + pex.ExportDataSectionRaw = pex.ReadRawSection(stream, ".edata", force: true, first: false); // Import Table - pex.ImportDataSectionRaw = pex.ReadRawSection(stream, ".idata", false); + pex.ImportDataSectionRaw = pex.ReadRawSection(stream, ".idata", force: true, first: false); // Resource Data Section - pex.ResourceDataSectionRaw = pex.ReadRawSection(stream, ".rdata", false); + pex.ResourceDataSectionRaw = pex.ReadRawSection(stream, ".rdata", force: true, first: false); // Text Section - pex.TextSectionRaw = pex.ReadRawSection(stream, ".text", false); + pex.TextSectionRaw = pex.ReadRawSection(stream, ".text", force: true, first: false); #endregion } @@ -484,19 +498,19 @@ namespace BurnOutSharp.ExecutableType.Microsoft #region Freeform Sections // Data Section - pex.DataSectionRaw = pex.ReadRawSection(content, ".data", false) ?? pex.ReadRawSection(content, "DATA", false); + pex.DataSectionRaw = pex.ReadRawSection(content, ".data", force: true, first: false) ?? pex.ReadRawSection(content, "DATA", force: true, first: false); // Export Table - pex.ExportDataSectionRaw = pex.ReadRawSection(content, ".edata", false); + pex.ExportDataSectionRaw = pex.ReadRawSection(content, ".edata", force: true, first: false); // Import Table - pex.ImportDataSectionRaw = pex.ReadRawSection(content, ".idata", false); + pex.ImportDataSectionRaw = pex.ReadRawSection(content, ".idata", force: true, first: false); // Resource Data Section - pex.ResourceDataSectionRaw = pex.ReadRawSection(content, ".rdata", false); + pex.ResourceDataSectionRaw = pex.ReadRawSection(content, ".rdata", force: true, first: false); // Text Section - pex.TextSectionRaw = pex.ReadRawSection(content, ".text", false); + pex.TextSectionRaw = pex.ReadRawSection(content, ".text", force: true, first: false); #endregion } diff --git a/BurnOutSharp/ProtectionType/ActiveMARK.cs b/BurnOutSharp/ProtectionType/ActiveMARK.cs index 0718a39c..c0987aac 100644 --- a/BurnOutSharp/ProtectionType/ActiveMARK.cs +++ b/BurnOutSharp/ProtectionType/ActiveMARK.cs @@ -16,7 +16,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the last .bss section, if it exists - var bssSectionRaw = pex.ReadRawSection(fileContent, ".bss", true); + var bssSectionRaw = pex.ReadRawSection(fileContent, ".bss", first: false); if (bssSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/CDDVDCops.cs b/BurnOutSharp/ProtectionType/CDDVDCops.cs index 767a2c55..7bf85b40 100644 --- a/BurnOutSharp/ProtectionType/CDDVDCops.cs +++ b/BurnOutSharp/ProtectionType/CDDVDCops.cs @@ -18,7 +18,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the .grand section, if it exists - var grandSectionRaw = pex.ReadRawSection(fileContent, ".grand", true); + var grandSectionRaw = pex.ReadRawSection(fileContent, ".grand", first: true); if (grandSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/SolidShield.cs b/BurnOutSharp/ProtectionType/SolidShield.cs index ff4702be..6310ac2e 100644 --- a/BurnOutSharp/ProtectionType/SolidShield.cs +++ b/BurnOutSharp/ProtectionType/SolidShield.cs @@ -48,7 +48,7 @@ namespace BurnOutSharp.ProtectionType return $"SolidShield Activation Manager Module {GetFileVersion(pex)}"; // Get the .init section, if it exists - var initSectionRaw = pex.ReadRawSection(fileContent, ".init", true); + var initSectionRaw = pex.ReadRawSection(fileContent, ".init", first: true); if (initSectionRaw != null) { var matchers = new List diff --git a/BurnOutSharp/ProtectionType/WTMCDProtect.cs b/BurnOutSharp/ProtectionType/WTMCDProtect.cs index a2d43f01..3383fb5f 100644 --- a/BurnOutSharp/ProtectionType/WTMCDProtect.cs +++ b/BurnOutSharp/ProtectionType/WTMCDProtect.cs @@ -16,7 +16,7 @@ namespace BurnOutSharp.ProtectionType return null; // Get the CODE section, if it exists - var codeSectionRaw = pex.ReadRawSection(fileContent, "CODE", true); + var codeSectionRaw = pex.ReadRawSection(fileContent, "CODE", first: true); if (codeSectionRaw != null) { var matchers = new List