Skip to content

Commit

Permalink
Add API doc to PE relocation
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Oct 2, 2024
1 parent 4896f9a commit 4847d50
Showing 1 changed file with 24 additions and 10 deletions.
34 changes: 24 additions & 10 deletions src/LibObjectFile/PE/PEFile.Relocate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@

namespace LibObjectFile.PE;

/// <summary>
/// A Portable Executable file that can be read, modified and written.
/// </summary>
partial class PEFile
{
/// <summary>
/// Relocates the PE file to a new image base.
/// </summary>
/// <param name="newImageBase">The new image base.</param>
public void Relocate(ulong newImageBase)
{
var diagnostics = new DiagnosticBag();
Expand All @@ -22,6 +23,11 @@ public void Relocate(ulong newImageBase)
}
}

/// <summary>
/// Relocates the PE file to a new image base.
/// </summary>
/// <param name="newImageBase">The new image base.</param>
/// <param name="diagnostics">The diagnostic bag to collect errors and warnings.</param>
public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
if (IsPE32 && newImageBase > uint.MaxValue)
Expand All @@ -36,7 +42,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
// Nothing to do
return;
}

// If we don't have a base relocation directory, we can just update the ImageBase
var baseRelocationDirectory = Directories.BaseRelocation;
if (baseRelocationDirectory is null)
Expand All @@ -59,12 +65,13 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
var section = baseRelocationBlock.PageLink.Container;
if (section is null)
{
diagnostics.Error(DiagnosticId.PE_ERR_VerifyContextInvalidObject, $"The {nameof(PEBaseRelocationBlock.PageLink)} in the base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)} is null and missing a link to an actual section");
diagnostics.Error(DiagnosticId.PE_ERR_VerifyContextInvalidObject,
$"The {nameof(PEBaseRelocationBlock.PageLink)} in the base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)} is null and missing a link to an actual section");
return;
}

var pageBaseRva = baseRelocationBlock.PageLink.RVA();

var relocations = CollectionsMarshal.AsSpan(baseRelocationBlock.Relocations);
try
{
Expand All @@ -77,11 +84,13 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
if (sectionData is null)
{
diagnostics.Error(DiagnosticId.PE_ERR_BaseRelocationInvalid, $"Unable to find the section data for the rva {rva} in the base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}");
diagnostics.Error(DiagnosticId.PE_ERR_BaseRelocationInvalid,
$"Unable to find the section data for the rva {rva} in the base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}");
return;
}

diagnostics.Warning(DiagnosticId.PE_WRN_BaseRelocationInVirtualMemory, $"Invalid RVA {rva} found in virtual memory from base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}");
diagnostics.Warning(DiagnosticId.PE_WRN_BaseRelocationInVirtualMemory,
$"Invalid RVA {rva} found in virtual memory from base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}");
continue;
}

Expand All @@ -102,6 +111,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
goto WarningOutOfBound;
}

break;
case PEBaseRelocationType.Low:
if (sectionData.CanReadWriteAt(offsetInSectionData, sizeof(ushort)))
Expand All @@ -112,6 +122,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
goto WarningOutOfBound;
}

break;
case PEBaseRelocationType.HighLow:
if (sectionData.CanReadWriteAt(offsetInSectionData, sizeof(uint)))
Expand All @@ -122,6 +133,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
goto WarningOutOfBound;
}

break;
case PEBaseRelocationType.HighAdj:

Expand All @@ -142,6 +154,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
goto WarningOutOfBound;
}

break;
case PEBaseRelocationType.Dir64:
if (sectionData.CanReadWriteAt(offsetInSectionData, sizeof(ulong)))
Expand All @@ -152,6 +165,7 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)
{
goto WarningOutOfBound;
}

break;
default:
diagnostics.Error(DiagnosticId.PE_ERR_BaseRelocationInvalid, $"Unsupported relocation type {relocation.Type} #{j} in {nameof(PEBaseRelocationBlock)} {baseRelocationBlock}.");
Expand All @@ -160,7 +174,8 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)

continue;
WarningOutOfBound:
diagnostics.Warning(DiagnosticId.PE_WRN_BaseRelocationInVirtualMemory, $"Cannot process base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}. The linked address is out of bound.");
diagnostics.Warning(DiagnosticId.PE_WRN_BaseRelocationInVirtualMemory,
$"Cannot process base relocation block {baseRelocationBlock} at index #{i} in the {nameof(PEBaseRelocationDirectory)}. The linked address is out of bound.");
continue;

}
Expand All @@ -174,5 +189,4 @@ public void Relocate(ulong newImageBase, DiagnosticBag diagnostics)

OptionalHeader.ImageBase = newImageBase;
}

}

0 comments on commit 4847d50

Please sign in to comment.