Skip to content

Commit a8831a1

Browse files
committed
Add better support for resource directory
1 parent 0f147b4 commit a8831a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+937
-651
lines changed

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -605,11 +605,20 @@ Sections
605605
[04] .rsrc PESection Position = 0x00003E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
606606

607607
[00] PEResourceDirectory Position = 0x00003E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
608-
> PEResourceDirectoryEntry { Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
609-
> PEResourceDirectoryEntry { Id = 0x18 (RT_MANIFEST), Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
610-
> PEResourceDirectoryEntry { Id = 0x1, Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
611-
> PEResourceDataEntry { Id = 0x409 (en-US), Data = Stream (381 bytes) }
612-
[00] PEStreamSectionData Position = 0x00003FD8, Size = 0x00000008, RVA = 0x000071D8, VirtualSize = 0x00000008
608+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
609+
[0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x7018, VirtualSize = 0x18, Position = 0x3E18, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
610+
[00] PEResourceDirectoryEntry Position = 0x00003E18, Size = 0x00000018, RVA = 0x00007018, VirtualSize = 0x00000018
611+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
612+
[0] Id = 0x1, Entry = PEResourceDirectoryEntry { RVA = 0x7030, VirtualSize = 0x18, Position = 0x3E30, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
613+
614+
[01] PEResourceDirectoryEntry Position = 0x00003E30, Size = 0x00000018, RVA = 0x00007030, VirtualSize = 0x00000018
615+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
616+
[0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x7048, VirtualSize = 0x10, Position = 0x3E48, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x3E60, Size = 0x17D } }
617+
618+
[02] PEResourceDataEntry Position = 0x00003E48, Size = 0x00000010, RVA = 0x00007048, VirtualSize = 0x00000010
619+
> CodePage = null, Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x3E60, Size = 0x17D }
620+
621+
[03] PEResourceData Position = 0x00003E60, Size = 0x0000017D, RVA = 0x00007060, VirtualSize = 0x0000017D
613622

614623

615624
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -512,11 +512,20 @@ Sections
512512
[04] .rsrc PESection Position = 0x00002E00, Size = 0x00000200, RVA = 0x00007000, VirtualSize = 0x000001E0, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
513513

514514
[00] PEResourceDirectory Position = 0x00002E00, Size = 0x000001E0, RVA = 0x00007000, VirtualSize = 0x000001E0
515-
> PEResourceDirectoryEntry { Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
516-
> PEResourceDirectoryEntry { Id = 0x18 (RT_MANIFEST), Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
517-
> PEResourceDirectoryEntry { Id = 0x1, Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
518-
> PEResourceDataEntry { Id = 0x409 (en-US), Data = Stream (381 bytes) }
519-
[00] PEStreamSectionData Position = 0x00002FD8, Size = 0x00000008, RVA = 0x000071D8, VirtualSize = 0x00000008
515+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
516+
[0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x7018, VirtualSize = 0x18, Position = 0x2E18, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
517+
[00] PEResourceDirectoryEntry Position = 0x00002E18, Size = 0x00000018, RVA = 0x00007018, VirtualSize = 0x00000018
518+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
519+
[0] Id = 0x1, Entry = PEResourceDirectoryEntry { RVA = 0x7030, VirtualSize = 0x18, Position = 0x2E30, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
520+
521+
[01] PEResourceDirectoryEntry Position = 0x00002E30, Size = 0x00000018, RVA = 0x00007030, VirtualSize = 0x00000018
522+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
523+
[0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x7048, VirtualSize = 0x10, Position = 0x2E48, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x2E60, Size = 0x17D } }
524+
525+
[02] PEResourceDataEntry Position = 0x00002E48, Size = 0x00000010, RVA = 0x00007048, VirtualSize = 0x00000010
526+
> CodePage = null, Data = PEResourceData { RVA = 0x7060, VirtualSize = 0x17D, Position = 0x2E60, Size = 0x17D }
527+
528+
[03] PEResourceData Position = 0x00002E60, Size = 0x0000017D, RVA = 0x00007060, VirtualSize = 0x0000017D
520529

521530

522531
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,22 @@ Sections
436436
[04] .rsrc PESection Position = 0x00002600, Size = 0x00000200, RVA = 0x00005000, VirtualSize = 0x000000F8, Characteristics = 0x40000040 (ContainsInitializedData, MemRead)
437437

438438
[00] PEResourceDirectory Position = 0x00002600, Size = 0x000000F8, RVA = 0x00005000, VirtualSize = 0x000000F8
439-
> PEResourceDirectoryEntry { Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
440-
> PEResourceDirectoryEntry { Id = 0x18 (RT_MANIFEST), Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
441-
> PEResourceDirectoryEntry { Id = 0x2, Entries[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0}
442-
> PEResourceDataEntry { Id = 0x409 (en-US), Data = Stream (145 bytes) }
443-
[00] PEStreamSectionData Position = 0x000026EC, Size = 0x0000000C, RVA = 0x000050EC, VirtualSize = 0x0000000C
439+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
440+
[0] Id = 0x18, Entry = PEResourceDirectoryEntry { RVA = 0x5018, VirtualSize = 0x18, Position = 0x2618, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
441+
[00] PEResourceDirectoryEntry Position = 0x00002618, Size = 0x00000018, RVA = 0x00005018, VirtualSize = 0x00000018
442+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
443+
[0] Id = 0x2, Entry = PEResourceDirectoryEntry { RVA = 0x5030, VirtualSize = 0x18, Position = 0x2630, Size = 0x18, ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, MajorVersion = 0, MinorVersion = 0 }
444+
445+
[01] PEResourceDirectoryEntry Position = 0x00002630, Size = 0x00000018, RVA = 0x00005030, VirtualSize = 0x00000018
446+
> ByNames[0], ByIds[1] , TimeDateStamp = 01/01/1970 00:00:00, Version = 0.0
447+
[0] Id = 0x409, Entry = PEResourceDataEntry { RVA = 0x5048, VirtualSize = 0x10, Position = 0x2648, Size = 0x10, CodePage = , Data = PEResourceData { RVA = 0x5060, VirtualSize = 0x91, Position = 0x2660, Size = 0x91 } }
448+
449+
[02] PEResourceDataEntry Position = 0x00002648, Size = 0x00000010, RVA = 0x00005048, VirtualSize = 0x00000010
450+
> CodePage = null, Data = PEResourceData { RVA = 0x5060, VirtualSize = 0x91, Position = 0x2660, Size = 0x91 }
451+
452+
[03] PEResourceData Position = 0x00002660, Size = 0x00000091, RVA = 0x00005060, VirtualSize = 0x00000091
453+
454+
[04] PEStreamSectionData Position = 0x000026F4, Size = 0x00000004, RVA = 0x000050F4, VirtualSize = 0x00000004
444455

445456

446457
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

src/LibObjectFile/ObjectFileElement.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

src/LibObjectFile/ObjectFileReaderWriter.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

@@ -18,6 +18,7 @@ namespace LibObjectFile;
1818
public abstract class ObjectFileReaderWriter : VisitorContextBase
1919
{
2020
private Stream _stream;
21+
private readonly byte[] _zeroBuffer = new byte[1024];
2122

2223
internal ObjectFileReaderWriter(ObjectFileElement file, Stream stream) : this(file, stream, new DiagnosticBag())
2324
{
@@ -192,6 +193,20 @@ public void Write(byte[] buffer, int offset, int count)
192193
Stream.Write(buffer, offset, count);
193194
}
194195

196+
/// <summary>
197+
/// Writes count bytes with zero.
198+
/// </summary>
199+
/// <param name="count">The number of bytes to write with zero.</param>
200+
public void WriteZero(int count)
201+
{
202+
while (count > 0)
203+
{
204+
var size = Math.Min(count, _zeroBuffer.Length);
205+
Stream.Write(_zeroBuffer, 0, size);
206+
count -= size;
207+
}
208+
}
209+
195210
/// <summary>
196211
/// Writes to the <see cref="Stream"/> and current position from the specified buffer.
197212
/// </summary>

src/LibObjectFile/PE/DataDirectory/PEArchitectureDirectory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

@@ -18,7 +18,7 @@ public PEArchitectureDirectory() : base(PEDataDirectoryKind.Architecture)
1818
{
1919
}
2020

21-
protected override uint ComputeHeaderSize(PEVisitorContext context)
21+
protected override uint ComputeHeaderSize(PELayoutContext context)
2222
{
2323
return 0;
2424
}

src/LibObjectFile/PE/DataDirectory/PEBaseRelocationDirectory.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public PEBaseRelocationDirectory() : base(PEDataDirectoryKind.BaseRelocation)
1919

2020
public List<PEBaseRelocationBlock> Blocks { get; } = new();
2121

22-
protected override unsafe uint ComputeHeaderSize(PEVisitorContext context)
22+
protected override unsafe uint ComputeHeaderSize(PELayoutContext context)
2323
{
2424
var size = 0U;
2525
foreach (var block in Blocks)
@@ -44,8 +44,6 @@ public override unsafe void Read(PEImageReader reader)
4444
return;
4545
}
4646

47-
var allSectionData = reader.File.GetAllSectionData();
48-
4947
int blockIndex = 0;
5048
while (buffer.Length > 0)
5149
{
@@ -59,7 +57,6 @@ public override unsafe void Read(PEImageReader reader)
5957
}
6058

6159
var sizeOfRelocations = (int)location.SizeOfBlock - sizeof(ImageBaseRelocation);
62-
6360

6461
// Create a block
6562
var block = new PEBaseRelocationBlock(new PESectionLink(section, (uint)(location.PageRVA - section.RVA)))
@@ -89,7 +86,12 @@ internal override void Bind(PEImageReader reader)
8986

9087
public override void Write(PEImageWriter writer)
9188
{
92-
throw new NotImplementedException();
89+
ImageBaseRelocation rawBlock = default;
90+
foreach (var block in Blocks)
91+
{
92+
rawBlock.PageRVA = block.SectionLink.RVA();
93+
rawBlock.SizeOfBlock = block.CalculateSizeOf();
94+
}
9395
}
9496

9597
protected override bool PrintMembers(StringBuilder builder)

src/LibObjectFile/PE/DataDirectory/PEBoundImportDirectory.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

@@ -30,9 +30,10 @@ public PEBoundImportDirectory() : base(PEDataDirectoryKind.BoundImport)
3030
public List<PEBoundImportDirectoryEntry> Entries { get; }
3131

3232
/// <inheritdoc/>
33-
protected override uint ComputeHeaderSize(PEVisitorContext context)
33+
protected override unsafe uint ComputeHeaderSize(PELayoutContext context)
3434
{
35-
var size = 0u;
35+
// Last raw entry is zero
36+
var size = (uint)sizeof(RawPEBoundImportDirectory);
3637
var entries = CollectionsMarshal.AsSpan(Entries);
3738
foreach (var entry in entries)
3839
{
@@ -156,6 +157,23 @@ internal override void Bind(PEImageReader reader)
156157
/// <inheritdoc/>
157158
public override void Write(PEImageWriter writer)
158159
{
159-
throw new NotImplementedException();
160+
RawPEBoundImportDirectory rawEntry = default;
161+
RawPEBoundImportForwarderRef rawForwarderRef = default;
162+
foreach (var entry in Entries)
163+
{
164+
rawEntry.OffsetModuleName = (ushort)entry.ModuleName.RVO;
165+
rawEntry.NumberOfModuleForwarderRefs = (ushort)entry.ForwarderRefs.Count;
166+
writer.Write(rawEntry);
167+
168+
foreach (var forwarderRef in entry.ForwarderRefs)
169+
{
170+
rawForwarderRef.OffsetModuleName = (ushort)forwarderRef.ModuleName.RVO;
171+
writer.Write(rawForwarderRef);
172+
}
173+
}
174+
175+
// Last entry is null
176+
rawEntry = default;
177+
writer.Write(rawEntry);
160178
}
161179
}

src/LibObjectFile/PE/DataDirectory/PEBoundImportDirectoryEntry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

src/LibObjectFile/PE/DataDirectory/PEClrMetadata.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Alexandre Mutel. All rights reserved.
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
22
// This file is licensed under the BSD-Clause 2 license.
33
// See the license.txt file in the project root for more information.
44

@@ -12,7 +12,7 @@ public PEClrMetadata() : base(PEDataDirectoryKind.ClrMetadata)
1212
{
1313
}
1414

15-
protected override uint ComputeHeaderSize(PEVisitorContext context)
15+
protected override uint ComputeHeaderSize(PELayoutContext context)
1616
{
1717
return 0;
1818
}

0 commit comments

Comments
 (0)