Skip to content

Commit 3901ecf

Browse files
committed
Improve support for directories. Add auto discovery from section content
1 parent d54f1be commit 3901ecf

27 files changed

+249
-165
lines changed

src/LibObjectFile.Tests/PE/PEReaderTests.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,26 +118,25 @@ public void TestCreatePE()
118118
exitProcessFunction
119119
};
120120

121-
var importDirectory = new PEImportDirectory();
122-
importDirectory.Entries.Add(new PEImportDirectoryEntry(kernelName, peImportAddressTable, peImportLookupTable));
121+
var importDirectory = new PEImportDirectory()
122+
{
123+
Entries =
124+
{
125+
new PEImportDirectoryEntry(kernelName, peImportAddressTable, peImportLookupTable)
126+
}
127+
};
123128

124129
// Layout of the data section
125130
dataSection.Content.Add(iatDirectory);
126131
dataSection.Content.Add(peImportLookupTable);
127132
dataSection.Content.Add(importDirectory);
128133
dataSection.Content.Add(streamData);
129134

130-
// ***************************************************************************
131-
// Directories
132-
// ***************************************************************************
133-
pe.Directories[PEDataDirectoryKind.Import] = importDirectory;
134-
pe.Directories[PEDataDirectoryKind.ImportAddressTable] = iatDirectory;
135-
136135
// ***************************************************************************
137136
// Optional Header
138137
// ***************************************************************************
139-
pe.OptionalHeader.AddressOfEntryPoint = 0x1000;
140-
pe.OptionalHeader.BaseOfCode = 0x1000;
138+
pe.OptionalHeader.AddressOfEntryPoint = new(streamCode, 0);
139+
pe.OptionalHeader.BaseOfCode = codeSection;
141140

142141
// ***************************************************************************
143142
// Write the PE to a file
@@ -232,6 +231,7 @@ public static IEnumerable<object[]> GetWindowsExeAndDlls()
232231
}
233232

234233
[TestMethod]
234+
[Ignore("PEFile does not support PE files that are folding the PE header into the DosHeader")]
235235
public async Task TestTinyExe97Bytes()
236236
{
237237
// http://www.phreedom.org/research/tinype/

src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsole2Win64.exe.verified.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ Optional Header
3838
SizeOfCode = 0x1A00
3939
SizeOfInitializedData = 0x2A00
4040
SizeOfUninitializedData = 0x0
41-
AddressOfEntryPoint = 0x15E0
42-
BaseOfCode = 0x1000
43-
BaseOfData = 0x0
41+
AddressOfEntryPoint = RVA = 0x15E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x19E9 }, Offset = 0x5E0
42+
BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x19E9, Position = 0x400, Size = 0x1A00, Content[1] }
43+
BaseOfData = 0x0x0
4444
ImageBase = 0x140000000
4545
SectionAlignment = 0x1000
4646
FileAlignment = 0x200

src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeConsoleWin64.exe.verified.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ Optional Header
3838
SizeOfCode = 0x1200
3939
SizeOfInitializedData = 0x2200
4040
SizeOfUninitializedData = 0x0
41-
AddressOfEntryPoint = 0x14E0
42-
BaseOfCode = 0x1000
43-
BaseOfData = 0x0
41+
AddressOfEntryPoint = RVA = 0x14E0, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x10C9 }, Offset = 0x4E0
42+
BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x10C9, Position = 0x400, Size = 0x1200, Content[1] }
43+
BaseOfData = 0x0x0
4444
ImageBase = 0x140000000
4545
SectionAlignment = 0x1000
4646
FileAlignment = 0x200

src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=NativeLibraryWin64.dll.verified.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ Optional Header
3838
SizeOfCode = 0x1000
3939
SizeOfInitializedData = 0x1C00
4040
SizeOfUninitializedData = 0x0
41-
AddressOfEntryPoint = 0x1370
42-
BaseOfCode = 0x1000
43-
BaseOfData = 0x0
41+
AddressOfEntryPoint = RVA = 0x1370, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0xF18 }, Offset = 0x370
42+
BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0xF18, Position = 0x400, Size = 0x1000, Content[1] }
43+
BaseOfData = 0x0x0
4444
ImageBase = 0x180000000
4545
SectionAlignment = 0x1000
4646
FileAlignment = 0x200

src/LibObjectFile.Tests/Verified/PEReaderTests.TestPrinter_name=RawNativeConsoleWin64.exe.verified.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ Optional Header
3838
SizeOfCode = 0x200
3939
SizeOfInitializedData = 0x400
4040
SizeOfUninitializedData = 0x0
41-
AddressOfEntryPoint = 0x1000
42-
BaseOfCode = 0x1000
43-
BaseOfData = 0x0
41+
AddressOfEntryPoint = RVA = 0x1000, PEStreamSectionData { RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x10 }, Offset = 0x0
42+
BaseOfCode = PESection { .text RVA = 0x1000, VirtualSize = 0x10, Position = 0x400, Size = 0x200, Content[1] }
43+
BaseOfData = 0x0x0
4444
ImageBase = 0x140000000
4545
SectionAlignment = 0x1000
4646
FileAlignment = 0x200

src/LibObjectFile/Diagnostics/DiagnosticId.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ public enum DiagnosticId
133133
PE_ERR_SectionAlignmentLessThanFileAlignment = 3015,
134134
PE_ERR_InvalidPEHeaderPosition = 3016,
135135
PE_ERR_InvalidNumberOfDataDirectories = 3017,
136-
136+
PE_ERR_InvalidBaseOfCode = 3018,
137+
PE_ERR_InvalidAddressOfEntryPoint = 3019,
138+
PE_ERR_DirectoryWithSameKindAlreadyAdded = 3020,
139+
137140
// PE Exception directory
138141
PE_ERR_InvalidExceptionDirectory_Entries = 3100,
139142
PE_ERR_InvalidExceptionDirectory_Entry = 3101,

src/LibObjectFile/PE/DataDirectory/PEBaseRelocationBlock.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public ulong ReadAddress(PEFile file, PEBaseRelocation relocation)
7272

7373
var vaOfReloc = SectionLink.RVA() + relocation.OffsetInBlock;
7474

75-
if (!file.TryFindContainerByRVA(vaOfReloc, out var container))
75+
if (!file.TryFindByRVA(vaOfReloc, out var container))
7676
{
7777
throw new InvalidOperationException($"Unable to find the section data containing the virtual address {vaOfReloc}");
7878
}
@@ -118,7 +118,7 @@ public override unsafe void Read(PEImageReader reader)
118118
return;
119119
}
120120

121-
if (!reader.File.TryFindSection(block.PageRVA, out var section))
121+
if (!reader.File.TryFindSectionByRVA(block.PageRVA, out var section))
122122
{
123123
reader.Diagnostics.Error(DiagnosticId.PE_ERR_BaseRelocationDirectoryInvalidVirtualAddress, $"Unable to find the section containing the virtual address {block.PageRVA} at position {position}");
124124
return;

src/LibObjectFile/PE/DataDirectory/PEBoundImportDirectory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ internal override void Bind(PEImageReader reader)
113113
{
114114
// The RVO is actually an RVA until we bind it here
115115
var va = (RVA)(uint)entry.ModuleName.RVO;
116-
if (!peFile.TryFindContainerByRVA(va, out var container))
116+
if (!peFile.TryFindByRVA(va, out var container))
117117
{
118118
diagnostics.Error(DiagnosticId.PE_ERR_BoundImportDirectoryInvalidModuleName, $"Unable to find the section data for ModuleName {va}");
119119
return;
@@ -134,7 +134,7 @@ internal override void Bind(PEImageReader reader)
134134
{
135135
// The RVO is actually an RVA until we bind it here
136136
va = (RVA)(uint)forwarderRef.ModuleName.RVO;
137-
if (!peFile.TryFindContainerByRVA(va, out container))
137+
if (!peFile.TryFindByRVA(va, out container))
138138
{
139139
diagnostics.Error(DiagnosticId.PE_ERR_BoundImportDirectoryInvalidForwarderRefModuleName, $"Unable to find the section data for ForwarderRef ModuleName {va}");
140140
return;

src/LibObjectFile/PE/DataDirectory/PECompositeSectionData.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Diagnostics.CodeAnalysis;
99
using System.Linq;
1010
using LibObjectFile.Collections;
11+
using LibObjectFile.Diagnostics;
1112
using LibObjectFile.Utils;
1213
using static System.Runtime.InteropServices.JavaScript.JSType;
1314

@@ -32,6 +33,30 @@ protected PECompositeSectionData()
3233
/// </summary>
3334
public ObjectList<PESectionData> Content { get; }
3435

36+
internal void UpdateDirectories(PEFile peFile, DiagnosticBag diagnostics)
37+
{
38+
if (this is PEDataDirectory directory)
39+
{
40+
var existingDirectory = peFile.Directories[directory.Kind];
41+
if (existingDirectory is not null)
42+
{
43+
diagnostics.Error(DiagnosticId.PE_ERR_DirectoryWithSameKindAlreadyAdded, $"A directory with the kind {directory.Kind} was already found {existingDirectory} while trying to add new directory {directory}");
44+
}
45+
else
46+
{
47+
peFile.Directories[directory.Kind] = directory;
48+
}
49+
}
50+
51+
foreach (var data in Content)
52+
{
53+
if (data is PECompositeSectionData compositeSectionData)
54+
{
55+
compositeSectionData.UpdateDirectories(peFile, diagnostics);
56+
}
57+
}
58+
}
59+
3560
protected sealed override void UpdateLayoutCore(PELayoutContext context)
3661
{
3762
var va = RVA;

src/LibObjectFile/PE/DataDirectory/PEDebugDirectory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public override unsafe void Read(PEImageReader reader)
5656

5757
if (rawEntry.AddressOfRawData != 0)
5858
{
59-
if (!reader.File.TryFindSection(rawEntry.AddressOfRawData, out var section))
59+
if (!reader.File.TryFindSectionByRVA(rawEntry.AddressOfRawData, out var section))
6060
{
6161
reader.Diagnostics.Error(DiagnosticId.PE_ERR_DebugDirectorySectionNotFound, $"Unable to find the section for the debug directory entry at {rawEntry.AddressOfRawData}");
6262
continue;

0 commit comments

Comments
 (0)