Skip to content

Commit 7d36386

Browse files
authored
Fix corrupted debug header directory entry when writing multiple such entries. (#869)
Basically the first two entries are written correctly, and any after that which has data will have the RVA correct, but the virtual address field will be wrong. Depending on the consumer this can work (if they use RVA) or fail (if they use virtual address) as they would read garbage data. Currently this mostly affects embedded protable PDBs since in that case we write 4 headers: CodeView, PdbChecksum, EmbeddedPdb and Deterministic (in this order), so the embedded PDB data is effectively wrong. Also adds a test which validates that both the RVA and virtual address point to the same thing.
1 parent 6f94613 commit 7d36386

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

Mono.Cecil.PE/ImageWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ void BuildTextMap ()
719719
entry.Directory = directory;
720720

721721
data_len += entry.Data.Length;
722-
data_address += data_len;
722+
data_address += entry.Data.Length;
723723
}
724724

725725
debug_dir_len = directories_len + data_len;

Test/Mono.Cecil.Tests/PortablePdbTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ public void ReadEmbeddedPortablePdbChecksum ()
911911
Assert.AreEqual ("SHA256", algorithmName);
912912
GetCodeViewPdbId (module, out byte [] pdbId);
913913

914-
GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
914+
GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb);
915915
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId);
916916

917917
CollectionAssert.AreEqual (expectedChecksum, checksum);
@@ -1005,7 +1005,7 @@ public void WriteEmbeddedPortablePdbChecksum ()
10051005
Assert.AreEqual ("SHA256", algorithmName);
10061006
GetCodeViewPdbId (module, out byte [] pdbId);
10071007

1008-
GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
1008+
GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb);
10091009
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId);
10101010

10111011
CollectionAssert.AreEqual (expectedChecksum, checksum);
@@ -1026,7 +1026,7 @@ public void DoubleWriteEmbeddedPortablePdbChecksum ()
10261026
byte [] pdbIdOne;
10271027
using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) {
10281028
var debugHeader = module.GetDebugHeader ();
1029-
GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
1029+
GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb);
10301030
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out pdbIdOne);
10311031
}
10321032

@@ -1037,18 +1037,20 @@ public void DoubleWriteEmbeddedPortablePdbChecksum ()
10371037
byte [] pdbIdTwo;
10381038
using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) {
10391039
var debugHeader = module.GetDebugHeader ();
1040-
GetEmbeddedPdb (debugHeader, out byte [] embeddedPdb);
1040+
GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb);
10411041
CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out pdbIdTwo);
10421042
}
10431043

10441044
CollectionAssert.AreEqual (pdbIdOne, pdbIdTwo);
10451045
}
10461046

1047-
private void GetEmbeddedPdb (ImageDebugHeader debugHeader, out byte [] embeddedPdb)
1047+
private void GetEmbeddedPdb (Image image, ImageDebugHeader debugHeader, out byte [] embeddedPdb)
10481048
{
10491049
var entry = Mixin.GetEmbeddedPortablePdbEntry (debugHeader);
10501050
Assert.IsNotNull (entry);
10511051

1052+
Assert.AreEqual (entry.Directory.PointerToRawData, image.ResolveVirtualAddress ((uint)entry.Directory.AddressOfRawData));
1053+
10521054
var compressed_stream = new MemoryStream (entry.Data);
10531055
var reader = new BinaryStreamReader (compressed_stream);
10541056
Assert.AreEqual (0x4244504D, reader.ReadInt32 ());

0 commit comments

Comments
 (0)