Trait PE

Source
pub trait PE: Buffer + Sized {
Show 71 methods // Required methods fn get_type(&self) -> PEType; fn is_allocated(&self) -> bool; // Provided methods fn get_cstring_size( &self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<usize, Error> { ... } fn get_widestring_size( &self, offset: usize, max_size: Option<usize>, ) -> Result<usize, Error> { ... } fn get_cstring( &self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<&[CChar], Error> { ... } fn get_mut_cstring( &mut self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<&mut [CChar], Error> { ... } fn get_widestring( &self, offset: usize, max_size: Option<usize>, ) -> Result<&[WChar], Error> { ... } fn get_mut_widestring( &mut self, offset: usize, max_size: Option<usize>, ) -> Result<&mut [WChar], Error> { ... } fn translate(&self, addr: PETranslation) -> Result<usize, Error> { ... } fn get_dos_header(&self) -> Result<&ImageDOSHeader, Error> { ... } fn get_mut_dos_header(&mut self) -> Result<&mut ImageDOSHeader, Error> { ... } fn get_valid_dos_header(&self) -> Result<&ImageDOSHeader, Error> { ... } fn get_valid_mut_dos_header(&mut self) -> Result<&mut ImageDOSHeader, Error> { ... } fn e_lfanew(&self) -> Result<Offset, Error> { ... } fn get_dos_stub(&self) -> Result<&[u8], Error> { ... } fn get_nt_headers_32(&self) -> Result<&ImageNTHeaders32, Error> { ... } fn get_mut_nt_headers_32(&mut self) -> Result<&mut ImageNTHeaders32, Error> { ... } fn get_valid_nt_headers_32(&self) -> Result<&ImageNTHeaders32, Error> { ... } fn get_valid_mut_nt_headers_32( &mut self, ) -> Result<&mut ImageNTHeaders32, Error> { ... } fn get_nt_headers_64(&self) -> Result<&ImageNTHeaders64, Error> { ... } fn get_mut_nt_headers_64(&mut self) -> Result<&mut ImageNTHeaders64, Error> { ... } fn get_valid_nt_headers_64(&self) -> Result<&ImageNTHeaders64, Error> { ... } fn get_valid_mut_nt_headers_64( &mut self, ) -> Result<&mut ImageNTHeaders64, Error> { ... } fn get_nt_magic(&self) -> Result<u16, Error> { ... } fn get_arch(&self) -> Result<Arch, Error> { ... } fn get_valid_nt_headers(&self) -> Result<NTHeaders<'_>, Error> { ... } fn get_valid_mut_nt_headers(&mut self) -> Result<NTHeadersMut<'_>, Error> { ... } fn validate_checksum(&self) -> Result<bool, Error> { ... } fn calculate_checksum(&self) -> Result<u32, Error> { ... } fn get_entrypoint(&self) -> Result<RVA, Error> { ... } fn get_image_base(&self) -> Result<u64, Error> { ... } fn get_data_directory_offset(&self) -> Result<Offset, Error> { ... } fn get_data_directory_size(&self) -> Result<usize, Error> { ... } fn get_data_directory_table(&self) -> Result<&[ImageDataDirectory], Error> { ... } fn get_mut_data_directory_table( &mut self, ) -> Result<&mut [ImageDataDirectory], Error> { ... } fn get_data_directory( &self, dir: ImageDirectoryEntry, ) -> Result<&ImageDataDirectory, Error> { ... } fn get_mut_data_directory( &mut self, dir: ImageDirectoryEntry, ) -> Result<&mut ImageDataDirectory, Error> { ... } fn has_data_directory(&self, dir: ImageDirectoryEntry) -> bool { ... } fn cast_directory<T: Castable>( &self, dir: ImageDirectoryEntry, ) -> Result<&T, Error> { ... } fn cast_directory_mut<T: Castable>( &mut self, dir: ImageDirectoryEntry, ) -> Result<&mut T, Error> { ... } fn get_section_table_offset(&self) -> Result<Offset, Error> { ... } fn get_section_table(&self) -> Result<&[ImageSectionHeader], Error> { ... } fn get_mut_section_table( &mut self, ) -> Result<&mut [ImageSectionHeader], Error> { ... } fn get_section_by_offset( &self, offset: Offset, ) -> Result<&ImageSectionHeader, Error> { ... } fn get_mut_section_by_offset( &mut self, offset: Offset, ) -> Result<&mut ImageSectionHeader, Error> { ... } fn get_section_by_rva(&self, rva: RVA) -> Result<&ImageSectionHeader, Error> { ... } fn get_mut_section_by_rva( &mut self, rva: RVA, ) -> Result<&mut ImageSectionHeader, Error> { ... } fn get_section_by_name<S: AsRef<str>>( &self, name: S, ) -> Result<&ImageSectionHeader, Error> { ... } fn get_mut_section_by_name( &mut self, name: String, ) -> Result<&mut ImageSectionHeader, Error> { ... } fn add_section( &mut self, section: &ImageSectionHeader, ) -> Result<&mut ImageSectionHeader, Error> { ... } fn append_section( &mut self, section: &ImageSectionHeader, ) -> Result<&mut ImageSectionHeader, Error> { ... } fn validate_offset(&self, offset: Offset) -> bool { ... } fn validate_rva(&self, rva: RVA) -> bool { ... } fn validate_va(&self, va: VA) -> bool { ... } fn is_aligned_to_file(&self, offset: Offset) -> bool { ... } fn is_aligned_to_section(&self, rva: RVA) -> bool { ... } fn align_to_file(&self, offset: Offset) -> Result<Offset, Error> { ... } fn align_to_section(&self, rva: RVA) -> Result<RVA, Error> { ... } fn offset_to_rva(&self, offset: Offset) -> Result<RVA, Error> { ... } fn offset_to_va(&self, offset: Offset) -> Result<VA, Error> { ... } fn rva_to_offset(&self, rva: RVA) -> Result<Offset, Error> { ... } fn rva_to_va(&self, rva: RVA) -> Result<VA, Error> { ... } fn va_to_rva(&self, va: VA) -> Result<RVA, Error> { ... } fn va_to_offset(&self, va: VA) -> Result<Offset, Error> { ... } fn get_resource_address(&self, offset: ResourceOffset) -> Result<RVA, Error> { ... } fn calculate_header_size(&self) -> Result<usize, Error> { ... } fn calculate_disk_size(&self) -> Result<usize, Error> { ... } fn calculate_memory_size(&self) -> Result<usize, Error> { ... } fn calculate_imphash(&self) -> Result<Vec<u8>, Error> { ... } fn recreate_image(&self, pe_type: PEType) -> Result<Vec<u8>, Error> { ... } fn fix_image_size(&mut self) -> Result<(), Error> { ... }
}
Expand description

Represents a type which handles PE data.

Required Methods§

Source

fn get_type(&self) -> PEType

Return the type of PE this object represents.

Source

fn is_allocated(&self) -> bool

Only for Windows. Return if the PE has been allocated by VirtualAlloc.

Provided Methods§

Source

fn get_cstring_size( &self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<usize, Error>

Get the size of a zero-terminated C-string in the data.

Source

fn get_widestring_size( &self, offset: usize, max_size: Option<usize>, ) -> Result<usize, Error>

Gets the size of a zero-terminated UTF16 string in the data.

Source

fn get_cstring( &self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<&[CChar], Error>

Get a zero-terminated C-string from the data. The thunk option is there to handle imports by name, whose null terminated value size is dependent on how long the string is (i.e., if it’s an odd length, an extra zero is appended).

§Example
use exe::{PE, VecPE};
use exe::types::{Offset, CCharString};

let pefile = VecPE::from_disk_file("test/dll.dll").unwrap();
let dll_name = pefile.get_cstring(Offset(0x328).into(), false, None).unwrap();

assert_eq!(dll_name.as_str().unwrap(), "dll.dll");
Source

fn get_mut_cstring( &mut self, offset: usize, thunk: bool, max_size: Option<usize>, ) -> Result<&mut [CChar], Error>

Get a mutable zero-terminated C-string from the data.

Source

fn get_widestring( &self, offset: usize, max_size: Option<usize>, ) -> Result<&[WChar], Error>

Get a zero-terminated UTF16 string from the data.

Source

fn get_mut_widestring( &mut self, offset: usize, max_size: Option<usize>, ) -> Result<&mut [WChar], Error>

Get a mutable zero-terminated UTF16 string from the data.

Source

fn translate(&self, addr: PETranslation) -> Result<usize, Error>

Translate an address into an offset usable by the Buffer trait based on the PE object’s type (i.e., the result of PE::get_type).

This differs from rva_to_offset because it does not directly rely on the section table. Rather, if the image is a memory image, it treats RVAs as buffer offsets, because that’s what they are in memory. Otherwise, it converts the RVA into an offset via the section table. The reverse goes for if the PE image is a disk image and an Offset is provided.

Typically, if you’re going to directly access data with the Buffer, you’ll want to call this function instead of calling rva_to_offset and similar functions because this function should guarantee the buffer offset is correct.

§Example
use exe::{PE, VecPE};
use exe::types::Offset;

let pefile = VecPE::from_memory_file("test/compiled_dumped.bin").unwrap();
let offset = Offset(0x400);

assert_eq!(pefile.translate(offset.into()).unwrap(), 0x1000);
Source

fn get_dos_header(&self) -> Result<&ImageDOSHeader, Error>

Get the DOS header without verifying its contents.

Source

fn get_mut_dos_header(&mut self) -> Result<&mut ImageDOSHeader, Error>

Get a mutable DOS header without verifying its contents.

Source

fn get_valid_dos_header(&self) -> Result<&ImageDOSHeader, Error>

Get the DOS header and verify it’s a valid DOS header.

Source

fn get_valid_mut_dos_header(&mut self) -> Result<&mut ImageDOSHeader, Error>

Get a mutable DOS header and verify it’s a valid DOS header.

Source

fn e_lfanew(&self) -> Result<Offset, Error>

Get the offset to the PE headers.

Source

fn get_dos_stub(&self) -> Result<&[u8], Error>

Get the executable DOS stub in the data.

This collects a u8 slice from the end of the DOS header to e_lfanew. If e_lfanew overlaps the DOS header, an empty slice is returned.

Source

fn get_nt_headers_32(&self) -> Result<&ImageNTHeaders32, Error>

Get 32-bit NT headers without verifying its contents.

Source

fn get_mut_nt_headers_32(&mut self) -> Result<&mut ImageNTHeaders32, Error>

Get mutable 32-bit NT headers without verifying its contents.

Source

fn get_valid_nt_headers_32(&self) -> Result<&ImageNTHeaders32, Error>

Get 32-bit NT headers and verify that they’re 32-bit NT headers.

Source

fn get_valid_mut_nt_headers_32( &mut self, ) -> Result<&mut ImageNTHeaders32, Error>

Get mutable 32-bit NT headers and verify that they’re 32-bit NT headers.

Source

fn get_nt_headers_64(&self) -> Result<&ImageNTHeaders64, Error>

Get 64-bit NT headers without verifying its contents.

Source

fn get_mut_nt_headers_64(&mut self) -> Result<&mut ImageNTHeaders64, Error>

Get mutable 64-bit NT headers without verifying its contents.

Source

fn get_valid_nt_headers_64(&self) -> Result<&ImageNTHeaders64, Error>

Get 64-bit NT headers and verify that they’re 64-bit NT headers.

Source

fn get_valid_mut_nt_headers_64( &mut self, ) -> Result<&mut ImageNTHeaders64, Error>

Get mutable 64-bit NT headers and verify that they’re 64-bit NT headers.

Source

fn get_nt_magic(&self) -> Result<u16, Error>

Get the NT signature from the optional header of the NT headers.

Source

fn get_arch(&self) -> Result<Arch, Error>

Get the architecture of this PE file.

Source

fn get_valid_nt_headers(&self) -> Result<NTHeaders<'_>, Error>

Get the NT headers of this PE file, inferring from the content of the file which architecture it is and validating the headers.

§Example
use exe::{PE, VecPE};
use exe::headers::HDR64_MAGIC;
use exe::types::NTHeaders;

let image = VecPE::from_disk_file("test/normal64.exe").unwrap();
let headers = image.get_valid_nt_headers().unwrap();

let magic = match headers {
   NTHeaders::NTHeaders32(hdr32) => hdr32.optional_header.magic,
   NTHeaders::NTHeaders64(hdr64) => hdr64.optional_header.magic,
};

assert_eq!(magic, HDR64_MAGIC);
Source

fn get_valid_mut_nt_headers(&mut self) -> Result<NTHeadersMut<'_>, Error>

Get mutable NT headers of this PE file, inferring from the content of the file which architecture it is and validating the headers.

Source

fn validate_checksum(&self) -> Result<bool, Error>

Validate the checksum in the image with the calculated checksum.

Source

fn calculate_checksum(&self) -> Result<u32, Error>

Calculate the checksum of the PE image.

Source

fn get_entrypoint(&self) -> Result<RVA, Error>

Get the entrypoint of this PE file.

Source

fn get_image_base(&self) -> Result<u64, Error>

Get the image base of this PE file.

On Windows, if the buffer has been allocated with VirtualAlloc (like a VallocBuffer), return that base address instead. Otherwise, return ImageBase from the NT headers.

Source

fn get_data_directory_offset(&self) -> Result<Offset, Error>

Get the offset to the data directory within the PE file.

Source

fn get_data_directory_size(&self) -> Result<usize, Error>

Get the size of the data directory. Rounds down number_of_rva_and_sizes to 16, which is what the Windows loader does.

Source

fn get_data_directory_table(&self) -> Result<&[ImageDataDirectory], Error>

Get the data directory table.

Normally one would expect this to be a part of ImageOptionalHeader, but ImageOptionalHeader::number_of_rva_and_sizes controls the size of the array. Therefore, we can’t stick it in the optional header, because that would produce a variable-sized structure, which Rust doesn’t support.

Source

fn get_mut_data_directory_table( &mut self, ) -> Result<&mut [ImageDataDirectory], Error>

Get a mutable data directory table.

Source

fn get_data_directory( &self, dir: ImageDirectoryEntry, ) -> Result<&ImageDataDirectory, Error>

Get the data directory reference represented by the ImageDirectoryEntry enum. Returns Error::BadDirectory if the given directory is inaccessible due to the directory size.

Source

fn get_mut_data_directory( &mut self, dir: ImageDirectoryEntry, ) -> Result<&mut ImageDataDirectory, Error>

Get the mutable data directory reference represented by the ImageDirectoryEntry enum.

Source

fn has_data_directory(&self, dir: ImageDirectoryEntry) -> bool

Check whether or not this PE file has a given data directory.

A PE file “has” a data directory if the following conditions are met:

  • the directory is present in the data directory array
  • the RVA is nonzero
  • the RVA is valid
Source

fn cast_directory<T: Castable>( &self, dir: ImageDirectoryEntry, ) -> Result<&T, Error>

Parse an object at the given data directory identified by ImageDirectoryEntry.

Source

fn cast_directory_mut<T: Castable>( &mut self, dir: ImageDirectoryEntry, ) -> Result<&mut T, Error>

Parse a mutable object at the given data directory identified by ImageDirectoryEntry.

Source

fn get_section_table_offset(&self) -> Result<Offset, Error>

Get the offset to the section table within the PE file.

Source

fn get_section_table(&self) -> Result<&[ImageSectionHeader], Error>

Get the section table of the PE file.

Source

fn get_mut_section_table(&mut self) -> Result<&mut [ImageSectionHeader], Error>

Get a mutable section table from the PE file.

Source

fn get_section_by_offset( &self, offset: Offset, ) -> Result<&ImageSectionHeader, Error>

Get a reference to a section in the PE file by a given offset. Yields a Error::SectionNotFound error if the offset wasn’t found to be in a section.

Source

fn get_mut_section_by_offset( &mut self, offset: Offset, ) -> Result<&mut ImageSectionHeader, Error>

Get a mutable reference to a section in the PE file by a given offset. Yields a Error::SectionNotFound error if the offset wasn’t found to be in a section.

Source

fn get_section_by_rva(&self, rva: RVA) -> Result<&ImageSectionHeader, Error>

Get a reference to a section in the PE file by a given RVA. Yields a Error::SectionNotFound error if the RVA wasn’t found to be in a section.

Source

fn get_mut_section_by_rva( &mut self, rva: RVA, ) -> Result<&mut ImageSectionHeader, Error>

Get a mutable reference to a section in the PE file by a given RVA. Yields a Error::SectionNotFound error if the RVA wasn’t found to be in a section.

Source

fn get_section_by_name<S: AsRef<str>>( &self, name: S, ) -> Result<&ImageSectionHeader, Error>

Get a reference to a section in the PE file by its name. Yields a Error::SectionNotFound error if the name wasn’t found in the section table.

Source

fn get_mut_section_by_name( &mut self, name: String, ) -> Result<&mut ImageSectionHeader, Error>

Get a mutable reference to a section in the PE file by its name. Yields a Error::SectionNotFound error if the name wasn’t found in the section table.

Source

fn add_section( &mut self, section: &ImageSectionHeader, ) -> Result<&mut ImageSectionHeader, Error>

Add a given section header to the section table. Returns a mutable reference to the section header as it exists in the section table.

Source

fn append_section( &mut self, section: &ImageSectionHeader, ) -> Result<&mut ImageSectionHeader, Error>

Append a given section header to the end of the PE sections. This function differs from add_section by setting the new section’s pointer_to_raw_data and virtual_address to the end of the previous section’s boundaries.

Returns a mutable reference to the new section as it exists in the section table.

Source

fn validate_offset(&self, offset: Offset) -> bool

Verify that the given offset is a valid offset.

An offset is validated if it is less than the length of the buffer.

Source

fn validate_rva(&self, rva: RVA) -> bool

Verify that the given RVA is a valid RVA.

An RVA is validated if it is less than the size of the image.

Source

fn validate_va(&self, va: VA) -> bool

Verify that the given VA is a valid VA for this image.

A VA is validated if it lands between the image base and the end of the image, determined by its size. In other words: image_base <= VA < (image_base+image_size)

Source

fn is_aligned_to_file(&self, offset: Offset) -> bool

Check if a given Offset is aligned to the file_alignment attribute of the optional header.

Source

fn is_aligned_to_section(&self, rva: RVA) -> bool

Check if a given RVA is aligned to the section_alignment attribute of the optional header.

Source

fn align_to_file(&self, offset: Offset) -> Result<Offset, Error>

Aligns a given Offset to the file_alignment attribute of the optional header.

Source

fn align_to_section(&self, rva: RVA) -> Result<RVA, Error>

Aligns a given RVA to the section_alignment attribute of the optional header.

Source

fn offset_to_rva(&self, offset: Offset) -> Result<RVA, Error>

Convert an offset to an RVA address. Produces Error::InvalidRVA if the produced RVA is invalid or if the section it was transposed from no longer contains it.

Source

fn offset_to_va(&self, offset: Offset) -> Result<VA, Error>

Convert an offset to a VA address.

Source

fn rva_to_offset(&self, rva: RVA) -> Result<Offset, Error>

Convert an RVA to an offset address. Produces a Error::InvalidOffset error if the produced offset is invalid or if the section it was transposed from no longer contains it.

Source

fn rva_to_va(&self, rva: RVA) -> Result<VA, Error>

Convert an RVA to a VA address. Produces a Error::InvalidVA error if the produced VA is invalid.

Source

fn va_to_rva(&self, va: VA) -> Result<RVA, Error>

Convert a VA to an RVA. Produces a Error::InvalidRVA error if the produced RVA is invalid.

Source

fn va_to_offset(&self, va: VA) -> Result<Offset, Error>

Converts a VA to an offset.

Source

fn get_resource_address(&self, offset: ResourceOffset) -> Result<RVA, Error>

Get an RVA object relative to the resource directory.

This is useful for gathering addresses when parsing the resource directory. Returns Error::OutOfBounds if the offset doesn’t fit in the resource directory.

Source

fn calculate_header_size(&self) -> Result<usize, Error>

Calculates the size of the image headers.

Source

fn calculate_disk_size(&self) -> Result<usize, Error>

Calculate the size of the image as it appears on disk. Note that if there is appended data at the end of the file, it will not be factored in.

Source

fn calculate_memory_size(&self) -> Result<usize, Error>

Calculate the size of the image as it appears in memory.

Source

fn calculate_imphash(&self) -> Result<Vec<u8>, Error>

Calculate the imphash of the PE file.

Source

fn recreate_image(&self, pe_type: PEType) -> Result<Vec<u8>, Error>

Creates a new vector representing either what the image looks like on disk (i.e., a PEType::Disk image) or what the image looks like in memory (i.e., a PEType::Memory image).

Note that for Memory images, it does not use caluclate_memory_size. It rather relies on the size_of_image field, as that’s what the loader does.

Source

fn fix_image_size(&mut self) -> Result<(), Error>

Recalculate the PE’s memory size with calculate_memory_size and set this value as the header’s size_of_image value.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§