From 1d6fa06e9702a34b3e4e97c740100588bd4afdae Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 11 Sep 2025 12:24:56 -0400 Subject: [PATCH] Placeholder for section table trailer data --- .../Deserializers/PortableExecutable.cs | 5 -- .../Wrappers/PortableExecutable.cs | 49 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/SabreTools.Serialization/Deserializers/PortableExecutable.cs b/SabreTools.Serialization/Deserializers/PortableExecutable.cs index eeeb981a..817285dd 100644 --- a/SabreTools.Serialization/Deserializers/PortableExecutable.cs +++ b/SabreTools.Serialization/Deserializers/PortableExecutable.cs @@ -103,11 +103,6 @@ namespace SabreTools.Serialization.Deserializers pex.SectionTable[i] = ParseSectionHeader(data); } - // TODO: Figure out a way to determine the end of the data here - // to find hidden things between the end of the section table and - // the beginning of the next data block. Some packers and protections - // can hide things here, e.g. ActiveMark - #endregion #region COFF Symbol Table and COFF String Table diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs index 06dc0bf9..32ba1918 100644 --- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs +++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs @@ -390,6 +390,45 @@ namespace SabreTools.Serialization.Wrappers /// public Models.PortableExecutable.SectionHeader[]? SectionTable => Model.SectionTable; + /// + /// Data after the section table, if it exists + /// + public byte[] SectionTrailerData + { + get + { + lock (_sectionTrailerDataLock) + { + // If we already have cached data, just use that immediately + if (_sectionTrailerData != null) + return _sectionTrailerData; + + if (Stub?.Header?.NewExeHeaderAddr == null) + { + _sectionTrailerData = []; + return _sectionTrailerData; + } + if (COFFFileHeader == null) + { + _sectionTrailerData = []; + return _sectionTrailerData; + } + + // Get the offset from the end of the section table + long endOfSectionTable = Stub.Header.NewExeHeaderAddr + + 24 // Signature size + COFF file header size + + COFFFileHeader.SizeOfOptionalHeader + + (COFFFileHeader.NumberOfSections * 40); // Size of a section header + + // TODO: Figure out how to determine the end of the extra data + _sectionTrailerData = []; + + // Cache and return the stub executable data, even if null + return _sectionTrailerData; + } + } + } + /// public Models.MSDOS.Executable? Stub => Model.Stub; @@ -745,6 +784,16 @@ namespace SabreTools.Serialization.Wrappers /// private readonly object _sectionStringDataLock = new(); + /// + /// Data after the section table, if it exists + /// + private byte[]? _sectionTrailerData = null; + + /// + /// Lock object for + /// + private readonly object _sectionTrailerDataLock = new(); + /// /// Stub executable data, if it exists ///