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