diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs
new file mode 100644
index 00000000..fea04df5
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/PE/Entries/BaseRelocationBlock.cs
@@ -0,0 +1,48 @@
+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/PortableExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs
index 8db4d59a..55acc224 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/PE/PortableExecutable.cs
@@ -89,6 +89,12 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
///
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.
@@ -110,7 +116,7 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
// 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 [Mostly taken care of, last protection needs research]
+ // - .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)
//
@@ -120,7 +126,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
// 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
@@ -131,15 +141,11 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
// - .ldr 1 protection 3PLock
// - .ldt 1 protection 3PLock
// - .nicode 1 protection Armadillo
- // - .NOS0 1 protection UPX (NOS Variant) [Used as endpoint]
- // - .NOS1 1 protection UPX (NOS Variant) [Used as endpoint]
// - .pec1 1 protection PE Compact
// - .securom 1 protection SecuROM
// - .sforce 1 protection StarForce
// - stxt371 1 protection SafeDisc
// - stxt774 1 protection SafeDisc
- // - .UPX0 1 protection UPX [Used as endpoint]
- // - .UPX1 1 protection UPX [Used as endpoint]
// - .vob.pcd 1 protection VOB ProtectCD
// - _winzip_ 1 protection WinZip SFX
// - XPROT 1 protection JoWood
@@ -266,6 +272,14 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
// 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)
@@ -362,7 +376,15 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
// if (table != null && table.VirtualSize > 0)
// {
// int tableAddress = (int)table.PointerToRawData;
- // this.ImportTable = ImportDataSection.Deserialize(content, tableAddress, this.OptionalHeader.Magic == OptionalHeaderType.PE32Plus, hintCount: 0);
+ // 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
@@ -420,13 +442,13 @@ namespace BurnOutSharp.ExecutableType.Microsoft.PE
if (sectionNames == null)
return false;
- // If we're checking exactly, return only exact matches (with nulls trimmed)
+ // If we're checking exactly, return only exact matches
if (exact)
- return sectionNames.Any(n => n.Trim('\0').Equals(sectionName));
+ return sectionNames.Any(n => n.Equals(sectionName));
// Otherwise, check if section name starts with the value
else
- return sectionNames.Any(n => n.Trim('\0').StartsWith(sectionName));
+ return sectionNames.Any(n => n.StartsWith(sectionName));
}
///
diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs
index 92e105c7..f63bef74 100644
--- a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs
+++ b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/DebugSection.cs
@@ -1,5 +1,4 @@
using System.IO;
-using BurnOutSharp.ExecutableType.Microsoft.PE.Headers;
using BurnOutSharp.ExecutableType.Microsoft.PE.Tables;
namespace BurnOutSharp.ExecutableType.Microsoft.PE.Sections
diff --git a/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs
new file mode 100644
index 00000000..bd7e82b6
--- /dev/null
+++ b/BurnOutSharp/ExecutableType/Microsoft/PE/Sections/RelocationSection.cs
@@ -0,0 +1,51 @@
+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