From d9fa5110e02b59332311c74c2c2dfb681a8769d1 Mon Sep 17 00:00:00 2001 From: Solomon Rutzky Date: Tue, 8 Sep 2020 02:24:21 -0400 Subject: [PATCH] Fix "Base of Data" in Optional Header Based on the definition of the "BaseOfData" field as found in the official documentation ( https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-standard-fields-image-only ), and confirmed via a PE32+ SQL Server DLL (sqlaccess): 1. Updated the "Meaning" to include: 1. the value that this particular value is relative to (i.e. "ImageBase"). 2. the fact that this value is _not_ present in PE32Plus (only regular 'ol PE32): 1. Placed this info at the beginning (i.e. far left) of the "Meaning" to increase visibility and reduce the chances of it not being seen (since it might be unexpected to simply not exist for certain images). 2. Intentionally stated both that it's not present in PE32Plus, _and_ only present in PE32, to be as clear as possible as to why the offset is 0 for PE32Plus. 2. Updated the "Offset" to be conditional, based on whether or not image is PE32Plus (same condition used for "Size" and "Value"). It now shows 0 for PE32Plus as this field does not exist under this condition. Showing a 0 offset is preferable to removing this field / entry entirely as that might lead to confusion for those who would have no idea why this field / entry was missing. 3. Updated the "Value" to be a literal 0 (ulong; was reading next UInt64 from the header). 4. Updated the "Size" to be 0 if image is PE32Plus (was 8 bytes). Also: 5. Simplified multiple occurrences of `header.Magic == PEMagic.PE32Plus` test with a new variable: `isPE32Plus`. --- ILSpy/Metadata/OptionalHeaderTreeNode.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ILSpy/Metadata/OptionalHeaderTreeNode.cs b/ILSpy/Metadata/OptionalHeaderTreeNode.cs index 6aad4c1c1..a5895bd87 100644 --- a/ILSpy/Metadata/OptionalHeaderTreeNode.cs +++ b/ILSpy/Metadata/OptionalHeaderTreeNode.cs @@ -60,6 +60,7 @@ namespace ICSharpCode.ILSpy.Metadata var headers = module.Reader.PEHeaders; var reader = module.Reader.GetEntireImage().GetReader(headers.PEHeaderStartOffset, 128); var header = headers.PEHeader; + var isPE32Plus = (header.Magic == PEMagic.PE32Plus); var entries = new List(); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, "Magic", header.Magic.ToString())); @@ -70,8 +71,8 @@ namespace ICSharpCode.ILSpy.Metadata entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "Uninitialized Data Size", "Size of the uninitialized data section, or the sum of all uninitialized data sections if there are multiple uninitialized data sections.")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "Entry Point RVA", "RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA in a section marked execute / read for EXEs or 0 for DLLs")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "Base Of Code", "RVA of the code section.")); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Base Of Data", "RVA of the data section.")); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Image Base", "Shall be a multiple of 0x10000.")); + entries.Add(new Entry(isPE32Plus ? 0 : headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? 0UL : reader.ReadUInt32(), isPE32Plus ? 0 : 4, "Base Of Data", "PE32 only (not present in PE32Plus): RVA of the data section, relative to the Image Base.")); + entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, "Image Base", "Shall be a multiple of 0x10000.")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "Section Alignment", "Shall be greater than File Alignment.")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "File Alignment", "")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, "Major OS Version", "")); @@ -86,10 +87,10 @@ namespace ICSharpCode.ILSpy.Metadata entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "File Checksum", "")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, "Subsystem", header.Subsystem.ToString())); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, "DLL Characteristics", header.DllCharacteristics.ToString())); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Stack Reserve Size", "")); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Stack Commit Size", "")); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Heap Reserve Size", "")); - entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Heap Commit Size", "")); + entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, "Stack Reserve Size", "")); + entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, "Stack Commit Size", "")); + entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, "Heap Reserve Size", "")); + entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, "Heap Commit Size", "")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt32(), 4, "Loader Flags", "")); entries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, "Number of Data Directories", ""));