pub struct PeHeaders {
pub dos: DosHeader,
pub coff: CoffHeader,
pub optional: OptionalHeader64,
}Expand description
Complete PE headers structure
Fields§
§dos: DosHeader§coff: CoffHeader§optional: OptionalHeader64Implementations§
Source§impl PeHeaders
impl PeHeaders
Sourcepub unsafe fn parse(image_base: *const u8, image_size: usize) -> PeResult<Self>
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
Sourcepub fn relocation_delta(&self, actual_load_address: u64) -> i64
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!
Sourcepub unsafe fn reconstruct_original_image_base(
&self,
image_base: *const u8,
image_size: usize,
actual_load_address: u64,
) -> PeResult<(u64, u32, u32)>
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:
- Check for compile-time hint (LINKER_IMAGE_BASE constant)
- Parse section table to know valid RVA ranges
- Collect DIR64 relocations from memory
- 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
- 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
Sourcepub unsafe fn unrelocate_image(
&self,
image_data: &mut [u8],
actual_load_address: u64,
) -> PeResult<i64>
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:
- Reconstruct original ImageBase (validated)
- Calculate relocation delta
- Reverse all DIR64 relocations (using embedded metadata if available)
- Patch ImageBase field in header
Returns the delta used for unrelocating (for logging)
§Safety
Caller must ensure image_data is valid relocated PE image
Sourcepub unsafe fn rva_to_file_layout(&self, rva_image: &[u8]) -> PeResult<Vec<u8>>
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