morpheus_persistent::pe::header

Struct PeHeaders

Source
pub struct PeHeaders {
    pub dos: DosHeader,
    pub coff: CoffHeader,
    pub optional: OptionalHeader64,
}
Expand description

Complete PE headers structure

Fields§

§dos: DosHeader§coff: CoffHeader§optional: OptionalHeader64

Implementations§

Source§

impl PeHeaders

Source

pub unsafe fn parse(image_base: *const u8, image_size: usize) -> PeResult<Self>

Parse all PE headers from image in memory

§Safety

Caller must ensure image_base points to valid PE file of given size

Source

pub fn arch(&self) -> PeResult<PeArch>

Get the architecture of this PE file

Source

pub fn relocation_delta(&self, actual_load_address: u64) -> i64

Calculate relocation delta between loaded address and ImageBase WARNING: ImageBase in memory is PATCHED by UEFI loader - this will always return 0!

Source

pub unsafe fn reconstruct_original_image_base( &self, image_base: *const u8, image_size: usize, actual_load_address: u64, ) -> PeResult<(u64, u32, u32)>

Reconstruct original ImageBase using proper validation

Strategy:

  1. Check for compile-time hint (LINKER_IMAGE_BASE constant)
  2. Parse section table to know valid RVA ranges
  3. Collect DIR64 relocations from memory
  4. For each candidate ImageBase:
    • Calculate what the ORIGINAL pointer values would have been
    • Check if those original values = candidate + valid_section_RVA
    • Original value MUST point within a valid section’s RVA range
  5. Return candidate with highest validation rate

This fixes the circular logic bug by validating against section boundaries, not against our own derived values!

Returns: (original_image_base, validated_relocs, total_relocs)

§Safety

Caller must ensure image_base points to valid relocated PE image

Source

pub unsafe fn unrelocate_image( &self, image_data: &mut [u8], actual_load_address: u64, ) -> PeResult<i64>

Create bootable PE image from relocated memory image

This is the main function for extracting the running bootloader and making it bootable again.

Steps:

  1. Reconstruct original ImageBase (validated)
  2. Calculate relocation delta
  3. Reverse all DIR64 relocations (using embedded metadata if available)
  4. Patch ImageBase field in header

Returns the delta used for unrelocating (for logging)

§Safety

Caller must ensure image_data is valid relocated PE image

Source

pub unsafe fn rva_to_file_layout(&self, rva_image: &[u8]) -> PeResult<Vec<u8>>

Convert memory-layout (RVA-based) PE image to file-layout (PointerToRawData-based)

UEFI loads PE files into memory with sections at their VirtualAddress (RVA) offsets. But PE files on disk have sections at PointerToRawData (file) offsets. This function converts from memory layout back to file layout.

§Safety

Caller must ensure rva_image is valid PE image in memory layout

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.