diff options
| author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 | 
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 | 
| commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
| tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/object/src/read/pe | |
| parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
| download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip  | |
Deleted vendor folder
Diffstat (limited to 'vendor/object/src/read/pe')
| -rw-r--r-- | vendor/object/src/read/pe/data_directory.rs | 213 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/export.rs | 333 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/file.rs | 1050 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/import.rs | 337 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/mod.rs | 68 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/relocation.rs | 92 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/resource.rs | 209 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/rich.rs | 91 | ||||
| -rw-r--r-- | vendor/object/src/read/pe/section.rs | 440 | 
9 files changed, 0 insertions, 2833 deletions
diff --git a/vendor/object/src/read/pe/data_directory.rs b/vendor/object/src/read/pe/data_directory.rs deleted file mode 100644 index a17179f..0000000 --- a/vendor/object/src/read/pe/data_directory.rs +++ /dev/null @@ -1,213 +0,0 @@ -use core::slice; - -use crate::read::{Error, ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE}; - -use super::{ -    DelayLoadImportTable, ExportTable, ImportTable, RelocationBlockIterator, ResourceDirectory, -    SectionTable, -}; - -/// The table of data directories in a PE file. -/// -/// Returned by [`ImageNtHeaders::parse`](super::ImageNtHeaders::parse). -#[derive(Debug, Clone, Copy)] -pub struct DataDirectories<'data> { -    entries: &'data [pe::ImageDataDirectory], -} - -impl<'data> DataDirectories<'data> { -    /// Parse the data directory table. -    /// -    /// `data` must be the remaining optional data following the -    /// [optional header](pe::ImageOptionalHeader64).  `number` must be from the -    /// [`number_of_rva_and_sizes`](pe::ImageOptionalHeader64::number_of_rva_and_sizes) -    /// field of the optional header. -    pub fn parse(data: &'data [u8], number: u32) -> Result<Self> { -        let entries = data -            .read_slice_at(0, number as usize) -            .read_error("Invalid PE number of RVA and sizes")?; -        Ok(DataDirectories { entries }) -    } - -    /// The number of data directories. -    #[allow(clippy::len_without_is_empty)] -    pub fn len(&self) -> usize { -        self.entries.len() -    } - -    /// Iterator over the data directories. -    pub fn iter(&self) -> slice::Iter<'data, pe::ImageDataDirectory> { -        self.entries.iter() -    } - -    /// Iterator which gives the directories as well as their index (one of the IMAGE_DIRECTORY_ENTRY_* constants). -    pub fn enumerate(&self) -> core::iter::Enumerate<slice::Iter<'data, pe::ImageDataDirectory>> { -        self.entries.iter().enumerate() -    } - -    /// Returns the data directory at the given index. -    /// -    /// Index should be one of the `IMAGE_DIRECTORY_ENTRY_*` constants. -    /// -    /// Returns `None` if the index is larger than the table size, -    /// or if the entry at the index has a zero virtual address. -    pub fn get(&self, index: usize) -> Option<&'data pe::ImageDataDirectory> { -        self.entries -            .get(index) -            .filter(|d| d.virtual_address.get(LE) != 0) -    } - -    /// Returns the unparsed export directory. -    /// -    /// `data` must be the entire file data. -    pub fn export_directory<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<&'data pe::ImageExportDirectory>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let export_data = data_dir.data(data, sections)?; -        ExportTable::parse_directory(export_data).map(Some) -    } - -    /// Returns the partially parsed export directory. -    /// -    /// `data` must be the entire file data. -    pub fn export_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ExportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_EXPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let export_va = data_dir.virtual_address.get(LE); -        let export_data = data_dir.data(data, sections)?; -        ExportTable::parse(export_data, export_va).map(Some) -    } - -    /// Returns the partially parsed import directory. -    /// -    /// `data` must be the entire file data. -    pub fn import_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ImportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_IMPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let import_va = data_dir.virtual_address.get(LE); -        let (section_data, section_va) = sections -            .pe_data_containing(data, import_va) -            .read_error("Invalid import data dir virtual address")?; -        Ok(Some(ImportTable::new(section_data, section_va, import_va))) -    } - -    /// Returns the partially parsed delay-load import directory. -    /// -    /// `data` must be the entire file data. -    pub fn delay_load_import_table<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<DelayLoadImportTable<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let import_va = data_dir.virtual_address.get(LE); -        let (section_data, section_va) = sections -            .pe_data_containing(data, import_va) -            .read_error("Invalid import data dir virtual address")?; -        Ok(Some(DelayLoadImportTable::new( -            section_data, -            section_va, -            import_va, -        ))) -    } - -    /// Returns the blocks in the base relocation directory. -    /// -    /// `data` must be the entire file data. -    pub fn relocation_blocks<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<RelocationBlockIterator<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_BASERELOC) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let reloc_data = data_dir.data(data, sections)?; -        Ok(Some(RelocationBlockIterator::new(reloc_data))) -    } - -    /// Returns the resource directory. -    /// -    /// `data` must be the entire file data. -    pub fn resource_directory<R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<Option<ResourceDirectory<'data>>> { -        let data_dir = match self.get(pe::IMAGE_DIRECTORY_ENTRY_RESOURCE) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let rsrc_data = data_dir.data(data, sections)?; -        Ok(Some(ResourceDirectory::new(rsrc_data))) -    } -} - -impl pe::ImageDataDirectory { -    /// Return the virtual address range of this directory entry. -    pub fn address_range(&self) -> (u32, u32) { -        (self.virtual_address.get(LE), self.size.get(LE)) -    } - -    /// Return the file offset and size of this directory entry. -    /// -    /// This function has some limitations: -    /// - It requires that the data is contained in a single section. -    /// - It uses the size field of the directory entry, which is -    /// not desirable for all data directories. -    /// - It uses the `virtual_address` of the directory entry as an address, -    /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`. -    pub fn file_range(&self, sections: &SectionTable<'_>) -> Result<(u32, u32)> { -        let (offset, section_size) = sections -            .pe_file_range_at(self.virtual_address.get(LE)) -            .read_error("Invalid data dir virtual address")?; -        let size = self.size.get(LE); -        if size > section_size { -            return Err(Error("Invalid data dir size")); -        } -        Ok((offset, size)) -    } - -    /// Get the data referenced by this directory entry. -    /// -    /// This function has some limitations: -    /// - It requires that the data is contained in a single section. -    /// - It uses the size field of the directory entry, which is -    /// not desirable for all data directories. -    /// - It uses the `virtual_address` of the directory entry as an address, -    /// which is not valid for `IMAGE_DIRECTORY_ENTRY_SECURITY`. -    pub fn data<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        sections: &SectionTable<'data>, -    ) -> Result<&'data [u8]> { -        sections -            .pe_data_at(data, self.virtual_address.get(LE)) -            .read_error("Invalid data dir virtual address")? -            .get(..self.size.get(LE) as usize) -            .read_error("Invalid data dir size") -    } -} diff --git a/vendor/object/src/read/pe/export.rs b/vendor/object/src/read/pe/export.rs deleted file mode 100644 index 1aba844..0000000 --- a/vendor/object/src/read/pe/export.rs +++ /dev/null @@ -1,333 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; - -use crate::read::{ByteString, Bytes, Error, ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE, U16Bytes, U32Bytes}; - -/// Where an export is pointing to. -#[derive(Clone, Copy)] -pub enum ExportTarget<'data> { -    /// The address of the export, relative to the image base. -    Address(u32), -    /// Forwarded to an export ordinal in another DLL. -    /// -    /// This gives the name of the DLL, and the ordinal. -    ForwardByOrdinal(&'data [u8], u32), -    /// Forwarded to an export name in another DLL. -    /// -    /// This gives the name of the DLL, and the export name. -    ForwardByName(&'data [u8], &'data [u8]), -} - -impl<'data> ExportTarget<'data> { -    /// Returns true if the target is an address. -    pub fn is_address(&self) -> bool { -        match self { -            ExportTarget::Address(_) => true, -            _ => false, -        } -    } - -    /// Returns true if the export is forwarded to another DLL. -    pub fn is_forward(&self) -> bool { -        !self.is_address() -    } -} - -/// An export from a PE file. -/// -/// There are multiple kinds of PE exports (with or without a name, and local or forwarded). -#[derive(Clone, Copy)] -pub struct Export<'data> { -    /// The ordinal of the export. -    /// -    /// These are sequential, starting at a base specified in the DLL. -    pub ordinal: u32, -    /// The name of the export, if known. -    pub name: Option<&'data [u8]>, -    /// The target of this export. -    pub target: ExportTarget<'data>, -} - -impl<'a> Debug for Export<'a> { -    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { -        f.debug_struct("Export") -            .field("ordinal", &self.ordinal) -            .field("name", &self.name.map(ByteString)) -            .field("target", &self.target) -            .finish() -    } -} - -impl<'a> Debug for ExportTarget<'a> { -    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> { -        match self { -            ExportTarget::Address(address) => write!(f, "Address({:#x})", address), -            ExportTarget::ForwardByOrdinal(library, ordinal) => write!( -                f, -                "ForwardByOrdinal({:?}.#{})", -                ByteString(library), -                ordinal -            ), -            ExportTarget::ForwardByName(library, name) => write!( -                f, -                "ForwardByName({:?}.{:?})", -                ByteString(library), -                ByteString(name) -            ), -        } -    } -} - -/// A partially parsed PE export table. -/// -/// Returned by [`DataDirectories::export_table`](super::DataDirectories::export_table). -#[derive(Debug, Clone)] -pub struct ExportTable<'data> { -    data: Bytes<'data>, -    virtual_address: u32, -    directory: &'data pe::ImageExportDirectory, -    addresses: &'data [U32Bytes<LE>], -    names: &'data [U32Bytes<LE>], -    name_ordinals: &'data [U16Bytes<LE>], -} - -impl<'data> ExportTable<'data> { -    /// Parse the export table given its section data and address. -    pub fn parse(data: &'data [u8], virtual_address: u32) -> Result<Self> { -        let directory = Self::parse_directory(data)?; -        let data = Bytes(data); - -        let mut addresses = &[][..]; -        let address_of_functions = directory.address_of_functions.get(LE); -        if address_of_functions != 0 { -            addresses = data -                .read_slice_at::<U32Bytes<_>>( -                    address_of_functions.wrapping_sub(virtual_address) as usize, -                    directory.number_of_functions.get(LE) as usize, -                ) -                .read_error("Invalid PE export address table")?; -        } - -        let mut names = &[][..]; -        let mut name_ordinals = &[][..]; -        let address_of_names = directory.address_of_names.get(LE); -        let address_of_name_ordinals = directory.address_of_name_ordinals.get(LE); -        if address_of_names != 0 { -            if address_of_name_ordinals == 0 { -                return Err(Error("Missing PE export ordinal table")); -            } - -            let number = directory.number_of_names.get(LE) as usize; -            names = data -                .read_slice_at::<U32Bytes<_>>( -                    address_of_names.wrapping_sub(virtual_address) as usize, -                    number, -                ) -                .read_error("Invalid PE export name pointer table")?; -            name_ordinals = data -                .read_slice_at::<U16Bytes<_>>( -                    address_of_name_ordinals.wrapping_sub(virtual_address) as usize, -                    number, -                ) -                .read_error("Invalid PE export ordinal table")?; -        } - -        Ok(ExportTable { -            data, -            virtual_address, -            directory, -            addresses, -            names, -            name_ordinals, -        }) -    } - -    /// Parse the export directory given its section data. -    pub fn parse_directory(data: &'data [u8]) -> Result<&'data pe::ImageExportDirectory> { -        data.read_at::<pe::ImageExportDirectory>(0) -            .read_error("Invalid PE export dir size") -    } - -    /// Returns the header of the export table. -    pub fn directory(&self) -> &'data pe::ImageExportDirectory { -        self.directory -    } - -    /// Returns the base value of ordinals. -    /// -    /// Adding this to an address index will give an ordinal. -    pub fn ordinal_base(&self) -> u32 { -        self.directory.base.get(LE) -    } - -    /// Returns the unparsed address table. -    /// -    /// An address table entry may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    pub fn addresses(&self) -> &'data [U32Bytes<LE>] { -        self.addresses -    } - -    /// Returns the unparsed name pointer table. -    /// -    /// A name pointer table entry can be used with [`Self::name_from_pointer`]. -    pub fn name_pointers(&self) -> &'data [U32Bytes<LE>] { -        self.names -    } - -    /// Returns the unparsed ordinal table. -    /// -    /// An ordinal table entry is a 0-based index into the address table. -    /// See [`Self::address_by_index`] and [`Self::target_by_index`]. -    pub fn name_ordinals(&self) -> &'data [U16Bytes<LE>] { -        self.name_ordinals -    } - -    /// Returns an iterator for the entries in the name pointer table and ordinal table. -    /// -    /// A name pointer table entry can be used with [`Self::name_from_pointer`]. -    /// -    /// An ordinal table entry is a 0-based index into the address table. -    /// See [`Self::address_by_index`] and [`Self::target_by_index`]. -    pub fn name_iter(&self) -> impl Iterator<Item = (u32, u16)> + 'data { -        self.names -            .iter() -            .map(|x| x.get(LE)) -            .zip(self.name_ordinals.iter().map(|x| x.get(LE))) -    } - -    /// Returns the export address table entry at the given address index. -    /// -    /// This may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    /// -    /// `index` is a 0-based index into the export address table. -    pub fn address_by_index(&self, index: u32) -> Result<u32> { -        Ok(self -            .addresses -            .get(index as usize) -            .read_error("Invalid PE export address index")? -            .get(LE)) -    } - -    /// Returns the export address table entry at the given ordinal. -    /// -    /// This may be a local address, or the address of a forwarded export entry. -    /// See [`Self::is_forward`] and [`Self::target_from_address`]. -    pub fn address_by_ordinal(&self, ordinal: u32) -> Result<u32> { -        self.address_by_index(ordinal.wrapping_sub(self.ordinal_base())) -    } - -    /// Returns the target of the export at the given address index. -    /// -    /// `index` is a 0-based index into the export address table. -    pub fn target_by_index(&self, index: u32) -> Result<ExportTarget<'data>> { -        self.target_from_address(self.address_by_index(index)?) -    } - -    /// Returns the target of the export at the given ordinal. -    pub fn target_by_ordinal(&self, ordinal: u32) -> Result<ExportTarget<'data>> { -        self.target_from_address(self.address_by_ordinal(ordinal)?) -    } - -    /// Convert an export address table entry into a target. -    pub fn target_from_address(&self, address: u32) -> Result<ExportTarget<'data>> { -        Ok(if let Some(forward) = self.forward_string(address)? { -            let i = forward -                .iter() -                .position(|x| *x == b'.') -                .read_error("Missing PE forwarded export separator")?; -            let library = &forward[..i]; -            match &forward[i + 1..] { -                [b'#', digits @ ..] => { -                    let ordinal = -                        parse_ordinal(digits).read_error("Invalid PE forwarded export ordinal")?; -                    ExportTarget::ForwardByOrdinal(library, ordinal) -                } -                [] => { -                    return Err(Error("Missing PE forwarded export name")); -                } -                name => ExportTarget::ForwardByName(library, name), -            } -        } else { -            ExportTarget::Address(address) -        }) -    } - -    fn forward_offset(&self, address: u32) -> Option<usize> { -        let offset = address.wrapping_sub(self.virtual_address) as usize; -        if offset < self.data.len() { -            Some(offset) -        } else { -            None -        } -    } - -    /// Return true if the export address table entry is a forward. -    pub fn is_forward(&self, address: u32) -> bool { -        self.forward_offset(address).is_some() -    } - -    /// Return the forward string if the export address table entry is a forward. -    pub fn forward_string(&self, address: u32) -> Result<Option<&'data [u8]>> { -        if let Some(offset) = self.forward_offset(address) { -            self.data -                .read_string_at(offset) -                .read_error("Invalid PE forwarded export address") -                .map(Some) -        } else { -            Ok(None) -        } -    } - -    /// Convert an export name pointer table entry into a name. -    pub fn name_from_pointer(&self, name_pointer: u32) -> Result<&'data [u8]> { -        let offset = name_pointer.wrapping_sub(self.virtual_address); -        self.data -            .read_string_at(offset as usize) -            .read_error("Invalid PE export name pointer") -    } - -    /// Returns the parsed exports in this table. -    pub fn exports(&self) -> Result<Vec<Export<'data>>> { -        // First, let's list all exports. -        let mut exports = Vec::new(); -        let ordinal_base = self.ordinal_base(); -        for (i, address) in self.addresses.iter().enumerate() { -            // Convert from an array index to an ordinal. -            let ordinal = ordinal_base.wrapping_add(i as u32); -            let target = self.target_from_address(address.get(LE))?; -            exports.push(Export { -                ordinal, -                target, -                // Might be populated later. -                name: None, -            }); -        } - -        // Now, check whether some (or all) of them have an associated name. -        // `ordinal_index` is a 0-based index into `addresses`. -        for (name_pointer, ordinal_index) in self.name_iter() { -            let name = self.name_from_pointer(name_pointer)?; -            exports -                .get_mut(ordinal_index as usize) -                .read_error("Invalid PE export ordinal")? -                .name = Some(name); -        } - -        Ok(exports) -    } -} - -fn parse_ordinal(digits: &[u8]) -> Option<u32> { -    if digits.is_empty() { -        return None; -    } -    let mut result: u32 = 0; -    for &c in digits { -        let x = (c as char).to_digit(10)?; -        result = result.checked_mul(10)?.checked_add(x)?; -    } -    Some(result) -} diff --git a/vendor/object/src/read/pe/file.rs b/vendor/object/src/read/pe/file.rs deleted file mode 100644 index 5372bdd..0000000 --- a/vendor/object/src/read/pe/file.rs +++ /dev/null @@ -1,1050 +0,0 @@ -use alloc::vec::Vec; -use core::fmt::Debug; -use core::{mem, str}; - -use core::convert::TryInto; - -use crate::read::coff::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable}; -use crate::read::{ -    self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator, -    Object, ObjectComdat, ObjectKind, ReadError, ReadRef, Result, SectionIndex, SymbolIndex, -}; -use crate::{pe, ByteString, Bytes, CodeView, LittleEndian as LE, Pod, SubArchitecture, U32}; - -use super::{ -    DataDirectories, ExportTable, ImageThunkData, ImportTable, PeSection, PeSectionIterator, -    PeSegment, PeSegmentIterator, RichHeaderInfo, SectionTable, -}; - -/// A PE32 (32-bit) image file. -/// -/// This is a file that starts with [`pe::ImageNtHeaders32`], and corresponds -/// to [`crate::FileKind::Pe32`]. -pub type PeFile32<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders32, R>; -/// A PE32+ (64-bit) image file. -/// -/// This is a file that starts with [`pe::ImageNtHeaders64`], and corresponds -/// to [`crate::FileKind::Pe64`]. -pub type PeFile64<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders64, R>; - -/// A PE image file. -/// -/// Most functionality is provided by the [`Object`] trait implementation. -#[derive(Debug)] -pub struct PeFile<'data, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) dos_header: &'data pe::ImageDosHeader, -    pub(super) nt_headers: &'data Pe, -    pub(super) data_directories: DataDirectories<'data>, -    pub(super) common: CoffCommon<'data, R>, -    pub(super) data: R, -} - -impl<'data, Pe, R> PeFile<'data, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    /// Parse the raw PE file data. -    pub fn parse(data: R) -> Result<Self> { -        let dos_header = pe::ImageDosHeader::parse(data)?; -        let mut offset = dos_header.nt_headers_offset().into(); -        let (nt_headers, data_directories) = Pe::parse(data, &mut offset)?; -        let sections = nt_headers.sections(data, offset)?; -        let coff_symbols = nt_headers.symbols(data); -        let image_base = nt_headers.optional_header().image_base(); - -        Ok(PeFile { -            dos_header, -            nt_headers, -            data_directories, -            common: CoffCommon { -                sections, -                // The PE file format deprecates the COFF symbol table (https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image) -                // We do not want to prevent parsing the rest of the PE file for a corrupt COFF header, but rather return an empty symbol table -                symbols: coff_symbols.unwrap_or_default(), -                image_base, -            }, -            data, -        }) -    } - -    /// Returns this binary data. -    pub fn data(&self) -> R { -        self.data -    } - -    /// Return the DOS header of this file. -    pub fn dos_header(&self) -> &'data pe::ImageDosHeader { -        self.dos_header -    } - -    /// Return the NT Headers of this file. -    pub fn nt_headers(&self) -> &'data Pe { -        self.nt_headers -    } - -    /// Returns information about the rich header of this file (if any). -    pub fn rich_header_info(&self) -> Option<RichHeaderInfo<'_>> { -        RichHeaderInfo::parse(self.data, self.dos_header.nt_headers_offset().into()) -    } - -    /// Returns the section table of this binary. -    pub fn section_table(&self) -> SectionTable<'data> { -        self.common.sections -    } - -    /// Returns the data directories of this file. -    pub fn data_directories(&self) -> DataDirectories<'data> { -        self.data_directories -    } - -    /// Returns the data directory at the given index. -    pub fn data_directory(&self, id: usize) -> Option<&'data pe::ImageDataDirectory> { -        self.data_directories.get(id) -    } - -    /// Returns the export table of this file. -    /// -    /// The export table is located using the data directory. -    pub fn export_table(&self) -> Result<Option<ExportTable<'data>>> { -        self.data_directories -            .export_table(self.data, &self.common.sections) -    } - -    /// Returns the import table of this file. -    /// -    /// The import table is located using the data directory. -    pub fn import_table(&self) -> Result<Option<ImportTable<'data>>> { -        self.data_directories -            .import_table(self.data, &self.common.sections) -    } - -    pub(super) fn section_alignment(&self) -> u64 { -        u64::from(self.nt_headers.optional_header().section_alignment()) -    } -} - -impl<'data, Pe, R> read::private::Sealed for PeFile<'data, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> Object<'data, 'file> for PeFile<'data, Pe, R> -where -    'data: 'file, -    Pe: ImageNtHeaders, -    R: 'file + ReadRef<'data>, -{ -    type Segment = PeSegment<'data, 'file, Pe, R>; -    type SegmentIterator = PeSegmentIterator<'data, 'file, Pe, R>; -    type Section = PeSection<'data, 'file, Pe, R>; -    type SectionIterator = PeSectionIterator<'data, 'file, Pe, R>; -    type Comdat = PeComdat<'data, 'file, Pe, R>; -    type ComdatIterator = PeComdatIterator<'data, 'file, Pe, R>; -    type Symbol = CoffSymbol<'data, 'file, R>; -    type SymbolIterator = CoffSymbolIterator<'data, 'file, R>; -    type SymbolTable = CoffSymbolTable<'data, 'file, R>; -    type DynamicRelocationIterator = NoDynamicRelocationIterator; - -    fn architecture(&self) -> Architecture { -        match self.nt_headers.file_header().machine.get(LE) { -            pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm, -            pe::IMAGE_FILE_MACHINE_ARM64 | pe::IMAGE_FILE_MACHINE_ARM64EC => Architecture::Aarch64, -            pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386, -            pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64, -            _ => Architecture::Unknown, -        } -    } - -    fn sub_architecture(&self) -> Option<SubArchitecture> { -        match self.nt_headers.file_header().machine.get(LE) { -            pe::IMAGE_FILE_MACHINE_ARM64EC => Some(SubArchitecture::Arm64EC), -            _ => None, -        } -    } - -    #[inline] -    fn is_little_endian(&self) -> bool { -        // Only little endian is supported. -        true -    } - -    #[inline] -    fn is_64(&self) -> bool { -        self.nt_headers.is_type_64() -    } - -    fn kind(&self) -> ObjectKind { -        let characteristics = self.nt_headers.file_header().characteristics.get(LE); -        if characteristics & pe::IMAGE_FILE_DLL != 0 { -            ObjectKind::Dynamic -        } else if characteristics & pe::IMAGE_FILE_SYSTEM != 0 { -            ObjectKind::Unknown -        } else { -            ObjectKind::Executable -        } -    } - -    fn segments(&'file self) -> PeSegmentIterator<'data, 'file, Pe, R> { -        PeSegmentIterator { -            file: self, -            iter: self.common.sections.iter(), -        } -    } - -    fn section_by_name_bytes( -        &'file self, -        section_name: &[u8], -    ) -> Option<PeSection<'data, 'file, Pe, R>> { -        self.common -            .sections -            .section_by_name(self.common.symbols.strings(), section_name) -            .map(|(index, section)| PeSection { -                file: self, -                index: SectionIndex(index), -                section, -            }) -    } - -    fn section_by_index( -        &'file self, -        index: SectionIndex, -    ) -> Result<PeSection<'data, 'file, Pe, R>> { -        let section = self.common.sections.section(index.0)?; -        Ok(PeSection { -            file: self, -            index, -            section, -        }) -    } - -    fn sections(&'file self) -> PeSectionIterator<'data, 'file, Pe, R> { -        PeSectionIterator { -            file: self, -            iter: self.common.sections.iter().enumerate(), -        } -    } - -    fn comdats(&'file self) -> PeComdatIterator<'data, 'file, Pe, R> { -        PeComdatIterator { file: self } -    } - -    fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<CoffSymbol<'data, 'file, R>> { -        let symbol = self.common.symbols.symbol(index.0)?; -        Ok(CoffSymbol { -            file: &self.common, -            index, -            symbol, -        }) -    } - -    fn symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { -        CoffSymbolIterator { -            file: &self.common, -            index: 0, -        } -    } - -    fn symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> { -        Some(CoffSymbolTable { file: &self.common }) -    } - -    fn dynamic_symbols(&'file self) -> CoffSymbolIterator<'data, 'file, R> { -        CoffSymbolIterator { -            file: &self.common, -            // Hack: don't return any. -            index: self.common.symbols.len(), -        } -    } - -    fn dynamic_symbol_table(&'file self) -> Option<CoffSymbolTable<'data, 'file, R>> { -        None -    } - -    fn dynamic_relocations(&'file self) -> Option<NoDynamicRelocationIterator> { -        None -    } - -    fn imports(&self) -> Result<Vec<Import<'data>>> { -        let mut imports = Vec::new(); -        if let Some(import_table) = self.import_table()? { -            let mut import_descs = import_table.descriptors()?; -            while let Some(import_desc) = import_descs.next()? { -                let library = import_table.name(import_desc.name.get(LE))?; -                let mut first_thunk = import_desc.original_first_thunk.get(LE); -                if first_thunk == 0 { -                    first_thunk = import_desc.first_thunk.get(LE); -                } -                let mut thunks = import_table.thunks(first_thunk)?; -                while let Some(thunk) = thunks.next::<Pe>()? { -                    if !thunk.is_ordinal() { -                        let (_hint, name) = import_table.hint_name(thunk.address())?; -                        imports.push(Import { -                            library: ByteString(library), -                            name: ByteString(name), -                        }); -                    } -                } -            } -        } -        Ok(imports) -    } - -    fn exports(&self) -> Result<Vec<Export<'data>>> { -        let mut exports = Vec::new(); -        if let Some(export_table) = self.export_table()? { -            for (name_pointer, address_index) in export_table.name_iter() { -                let name = export_table.name_from_pointer(name_pointer)?; -                let address = export_table.address_by_index(address_index.into())?; -                if !export_table.is_forward(address) { -                    exports.push(Export { -                        name: ByteString(name), -                        address: self.common.image_base.wrapping_add(address.into()), -                    }) -                } -            } -        } -        Ok(exports) -    } - -    fn pdb_info(&self) -> Result<Option<CodeView<'_>>> { -        let data_dir = match self.data_directory(pe::IMAGE_DIRECTORY_ENTRY_DEBUG) { -            Some(data_dir) => data_dir, -            None => return Ok(None), -        }; -        let debug_data = data_dir.data(self.data, &self.common.sections).map(Bytes)?; -        let debug_data_size = data_dir.size.get(LE) as usize; - -        let count = debug_data_size / mem::size_of::<pe::ImageDebugDirectory>(); -        let rem = debug_data_size % mem::size_of::<pe::ImageDebugDirectory>(); -        if rem != 0 || count < 1 { -            return Err(Error("Invalid PE debug dir size")); -        } - -        let debug_dirs = debug_data -            .read_slice_at::<pe::ImageDebugDirectory>(0, count) -            .read_error("Invalid PE debug dir size")?; - -        for debug_dir in debug_dirs { -            if debug_dir.typ.get(LE) != pe::IMAGE_DEBUG_TYPE_CODEVIEW { -                continue; -            } - -            let info = self -                .data -                .read_slice_at::<u8>( -                    debug_dir.pointer_to_raw_data.get(LE) as u64, -                    debug_dir.size_of_data.get(LE) as usize, -                ) -                .read_error("Invalid CodeView Info address")?; - -            let mut info = Bytes(info); - -            let sig = info -                .read_bytes(4) -                .read_error("Invalid CodeView signature")?; -            if sig.0 != b"RSDS" { -                continue; -            } - -            let guid: [u8; 16] = info -                .read_bytes(16) -                .read_error("Invalid CodeView GUID")? -                .0 -                .try_into() -                .unwrap(); - -            let age = info.read::<U32<LE>>().read_error("Invalid CodeView Age")?; - -            let path = info -                .read_string() -                .read_error("Invalid CodeView file path")?; - -            return Ok(Some(CodeView { -                path: ByteString(path), -                guid, -                age: age.get(LE), -            })); -        } -        Ok(None) -    } - -    fn has_debug_symbols(&self) -> bool { -        self.section_by_name(".debug_info").is_some() -    } - -    fn relative_address_base(&self) -> u64 { -        self.common.image_base -    } - -    fn entry(&self) -> u64 { -        u64::from(self.nt_headers.optional_header().address_of_entry_point()) -            .wrapping_add(self.common.image_base) -    } - -    fn flags(&self) -> FileFlags { -        FileFlags::Coff { -            characteristics: self.nt_headers.file_header().characteristics.get(LE), -        } -    } -} - -/// An iterator for the COMDAT section groups in a [`PeFile32`]. -pub type PeComdatIterator32<'data, 'file, R = &'data [u8]> = -    PeComdatIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the COMDAT section groups in a [`PeFile64`]. -pub type PeComdatIterator64<'data, 'file, R = &'data [u8]> = -    PeComdatIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the COMDAT section groups in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdatIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> Iterator for PeComdatIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeComdat<'data, 'file, Pe, R>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -/// A COMDAT section group in a [`PeFile32`]. -pub type PeComdat32<'data, 'file, R = &'data [u8]> = -    PeComdat<'data, 'file, pe::ImageNtHeaders32, R>; -/// A COMDAT section group in a [`PeFile64`]. -pub type PeComdat64<'data, 'file, R = &'data [u8]> = -    PeComdat<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A COMDAT section group in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdat<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeComdat<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectComdat<'data> for PeComdat<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type SectionIterator = PeComdatSectionIterator<'data, 'file, Pe, R>; - -    #[inline] -    fn kind(&self) -> ComdatKind { -        unreachable!(); -    } - -    #[inline] -    fn symbol(&self) -> SymbolIndex { -        unreachable!(); -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        unreachable!(); -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        unreachable!(); -    } - -    #[inline] -    fn sections(&self) -> Self::SectionIterator { -        unreachable!(); -    } -} - -/// An iterator for the sections in a COMDAT section group in a [`PeFile32`]. -pub type PeComdatSectionIterator32<'data, 'file, R = &'data [u8]> = -    PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the sections in a COMDAT section group in a [`PeFile64`]. -pub type PeComdatSectionIterator64<'data, 'file, R = &'data [u8]> = -    PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the sections in a COMDAT section group in a [`PeFile`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeComdatSectionIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[allow(unused)] -    file: &'file PeFile<'data, Pe, R>, -} - -impl<'data, 'file, Pe, R> Iterator for PeComdatSectionIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = SectionIndex; - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -} - -impl pe::ImageDosHeader { -    /// Read the DOS header. -    /// -    /// Also checks that the `e_magic` field in the header is valid. -    pub fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> { -        // DOS header comes first. -        let dos_header = data -            .read_at::<pe::ImageDosHeader>(0) -            .read_error("Invalid DOS header size or alignment")?; -        if dos_header.e_magic.get(LE) != pe::IMAGE_DOS_SIGNATURE { -            return Err(Error("Invalid DOS magic")); -        } -        Ok(dos_header) -    } - -    /// Return the file offset of the nt_headers. -    #[inline] -    pub fn nt_headers_offset(&self) -> u32 { -        self.e_lfanew.get(LE) -    } -} - -/// Find the optional header and read its `magic` field. -/// -/// It can be useful to know this magic value before trying to -/// fully parse the NT headers. -pub fn optional_header_magic<'data, R: ReadRef<'data>>(data: R) -> Result<u16> { -    let dos_header = pe::ImageDosHeader::parse(data)?; -    // NT headers are at an offset specified in the DOS header. -    let offset = dos_header.nt_headers_offset().into(); -    // It doesn't matter which NT header type is used for the purpose -    // of reading the optional header magic. -    let nt_headers = data -        .read_at::<pe::ImageNtHeaders32>(offset) -        .read_error("Invalid NT headers offset, size, or alignment")?; -    if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE { -        return Err(Error("Invalid PE magic")); -    } -    Ok(nt_headers.optional_header().magic()) -} - -/// A trait for generic access to [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. -#[allow(missing_docs)] -pub trait ImageNtHeaders: Debug + Pod { -    type ImageOptionalHeader: ImageOptionalHeader; -    type ImageThunkData: ImageThunkData; - -    /// Return true if this type is a 64-bit header. -    /// -    /// This is a property of the type, not a value in the header data. -    fn is_type_64(&self) -> bool; - -    /// Return true if the magic field in the optional header is valid. -    fn is_valid_optional_magic(&self) -> bool; - -    /// Return the signature -    fn signature(&self) -> u32; - -    /// Return the file header. -    fn file_header(&self) -> &pe::ImageFileHeader; - -    /// Return the optional header. -    fn optional_header(&self) -> &Self::ImageOptionalHeader; - -    // Provided methods. - -    /// Read the NT headers, including the data directories. -    /// -    /// `data` must be for the entire file. -    /// -    /// `offset` must be headers offset, which can be obtained from [`pe::ImageDosHeader::nt_headers_offset`]. -    /// It is updated to point after the optional header, which is where the section headers are located. -    /// -    /// Also checks that the `signature` and `magic` fields in the headers are valid. -    fn parse<'data, R: ReadRef<'data>>( -        data: R, -        offset: &mut u64, -    ) -> read::Result<(&'data Self, DataDirectories<'data>)> { -        // Note that this does not include the data directories in the optional header. -        let nt_headers = data -            .read::<Self>(offset) -            .read_error("Invalid PE headers offset or size")?; -        if nt_headers.signature() != pe::IMAGE_NT_SIGNATURE { -            return Err(Error("Invalid PE magic")); -        } -        if !nt_headers.is_valid_optional_magic() { -            return Err(Error("Invalid PE optional header magic")); -        } - -        // Read the rest of the optional header, and then read the data directories from that. -        let optional_data_size = -            u64::from(nt_headers.file_header().size_of_optional_header.get(LE)) -                .checked_sub(mem::size_of::<Self::ImageOptionalHeader>() as u64) -                .read_error("PE optional header size is too small")?; -        let optional_data = data -            .read_bytes(offset, optional_data_size) -            .read_error("Invalid PE optional header size")?; -        let data_directories = DataDirectories::parse( -            optional_data, -            nt_headers.optional_header().number_of_rva_and_sizes(), -        )?; - -        Ok((nt_headers, data_directories)) -    } - -    /// Read the section table. -    /// -    /// `data` must be for the entire file. -    /// `offset` must be after the optional file header. -    #[inline] -    fn sections<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        offset: u64, -    ) -> read::Result<SectionTable<'data>> { -        SectionTable::parse(self.file_header(), data, offset) -    } - -    /// Read the COFF symbol table and string table. -    /// -    /// `data` must be the entire file data. -    #[inline] -    fn symbols<'data, R: ReadRef<'data>>(&self, data: R) -> read::Result<SymbolTable<'data, R>> { -        SymbolTable::parse(self.file_header(), data) -    } -} - -/// A trait for generic access to [`pe::ImageOptionalHeader32`] and [`pe::ImageOptionalHeader64`]. -#[allow(missing_docs)] -pub trait ImageOptionalHeader: Debug + Pod { -    // Standard fields. -    fn magic(&self) -> u16; -    fn major_linker_version(&self) -> u8; -    fn minor_linker_version(&self) -> u8; -    fn size_of_code(&self) -> u32; -    fn size_of_initialized_data(&self) -> u32; -    fn size_of_uninitialized_data(&self) -> u32; -    fn address_of_entry_point(&self) -> u32; -    fn base_of_code(&self) -> u32; -    fn base_of_data(&self) -> Option<u32>; - -    // NT additional fields. -    fn image_base(&self) -> u64; -    fn section_alignment(&self) -> u32; -    fn file_alignment(&self) -> u32; -    fn major_operating_system_version(&self) -> u16; -    fn minor_operating_system_version(&self) -> u16; -    fn major_image_version(&self) -> u16; -    fn minor_image_version(&self) -> u16; -    fn major_subsystem_version(&self) -> u16; -    fn minor_subsystem_version(&self) -> u16; -    fn win32_version_value(&self) -> u32; -    fn size_of_image(&self) -> u32; -    fn size_of_headers(&self) -> u32; -    fn check_sum(&self) -> u32; -    fn subsystem(&self) -> u16; -    fn dll_characteristics(&self) -> u16; -    fn size_of_stack_reserve(&self) -> u64; -    fn size_of_stack_commit(&self) -> u64; -    fn size_of_heap_reserve(&self) -> u64; -    fn size_of_heap_commit(&self) -> u64; -    fn loader_flags(&self) -> u32; -    fn number_of_rva_and_sizes(&self) -> u32; -} - -impl ImageNtHeaders for pe::ImageNtHeaders32 { -    type ImageOptionalHeader = pe::ImageOptionalHeader32; -    type ImageThunkData = pe::ImageThunkData32; - -    #[inline] -    fn is_type_64(&self) -> bool { -        false -    } - -    #[inline] -    fn is_valid_optional_magic(&self) -> bool { -        self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR32_MAGIC -    } - -    #[inline] -    fn signature(&self) -> u32 { -        self.signature.get(LE) -    } - -    #[inline] -    fn file_header(&self) -> &pe::ImageFileHeader { -        &self.file_header -    } - -    #[inline] -    fn optional_header(&self) -> &Self::ImageOptionalHeader { -        &self.optional_header -    } -} - -impl ImageOptionalHeader for pe::ImageOptionalHeader32 { -    #[inline] -    fn magic(&self) -> u16 { -        self.magic.get(LE) -    } - -    #[inline] -    fn major_linker_version(&self) -> u8 { -        self.major_linker_version -    } - -    #[inline] -    fn minor_linker_version(&self) -> u8 { -        self.minor_linker_version -    } - -    #[inline] -    fn size_of_code(&self) -> u32 { -        self.size_of_code.get(LE) -    } - -    #[inline] -    fn size_of_initialized_data(&self) -> u32 { -        self.size_of_initialized_data.get(LE) -    } - -    #[inline] -    fn size_of_uninitialized_data(&self) -> u32 { -        self.size_of_uninitialized_data.get(LE) -    } - -    #[inline] -    fn address_of_entry_point(&self) -> u32 { -        self.address_of_entry_point.get(LE) -    } - -    #[inline] -    fn base_of_code(&self) -> u32 { -        self.base_of_code.get(LE) -    } - -    #[inline] -    fn base_of_data(&self) -> Option<u32> { -        Some(self.base_of_data.get(LE)) -    } - -    #[inline] -    fn image_base(&self) -> u64 { -        self.image_base.get(LE).into() -    } - -    #[inline] -    fn section_alignment(&self) -> u32 { -        self.section_alignment.get(LE) -    } - -    #[inline] -    fn file_alignment(&self) -> u32 { -        self.file_alignment.get(LE) -    } - -    #[inline] -    fn major_operating_system_version(&self) -> u16 { -        self.major_operating_system_version.get(LE) -    } - -    #[inline] -    fn minor_operating_system_version(&self) -> u16 { -        self.minor_operating_system_version.get(LE) -    } - -    #[inline] -    fn major_image_version(&self) -> u16 { -        self.major_image_version.get(LE) -    } - -    #[inline] -    fn minor_image_version(&self) -> u16 { -        self.minor_image_version.get(LE) -    } - -    #[inline] -    fn major_subsystem_version(&self) -> u16 { -        self.major_subsystem_version.get(LE) -    } - -    #[inline] -    fn minor_subsystem_version(&self) -> u16 { -        self.minor_subsystem_version.get(LE) -    } - -    #[inline] -    fn win32_version_value(&self) -> u32 { -        self.win32_version_value.get(LE) -    } - -    #[inline] -    fn size_of_image(&self) -> u32 { -        self.size_of_image.get(LE) -    } - -    #[inline] -    fn size_of_headers(&self) -> u32 { -        self.size_of_headers.get(LE) -    } - -    #[inline] -    fn check_sum(&self) -> u32 { -        self.check_sum.get(LE) -    } - -    #[inline] -    fn subsystem(&self) -> u16 { -        self.subsystem.get(LE) -    } - -    #[inline] -    fn dll_characteristics(&self) -> u16 { -        self.dll_characteristics.get(LE) -    } - -    #[inline] -    fn size_of_stack_reserve(&self) -> u64 { -        self.size_of_stack_reserve.get(LE).into() -    } - -    #[inline] -    fn size_of_stack_commit(&self) -> u64 { -        self.size_of_stack_commit.get(LE).into() -    } - -    #[inline] -    fn size_of_heap_reserve(&self) -> u64 { -        self.size_of_heap_reserve.get(LE).into() -    } - -    #[inline] -    fn size_of_heap_commit(&self) -> u64 { -        self.size_of_heap_commit.get(LE).into() -    } - -    #[inline] -    fn loader_flags(&self) -> u32 { -        self.loader_flags.get(LE) -    } - -    #[inline] -    fn number_of_rva_and_sizes(&self) -> u32 { -        self.number_of_rva_and_sizes.get(LE) -    } -} - -impl ImageNtHeaders for pe::ImageNtHeaders64 { -    type ImageOptionalHeader = pe::ImageOptionalHeader64; -    type ImageThunkData = pe::ImageThunkData64; - -    #[inline] -    fn is_type_64(&self) -> bool { -        true -    } - -    #[inline] -    fn is_valid_optional_magic(&self) -> bool { -        self.optional_header.magic.get(LE) == pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC -    } - -    #[inline] -    fn signature(&self) -> u32 { -        self.signature.get(LE) -    } - -    #[inline] -    fn file_header(&self) -> &pe::ImageFileHeader { -        &self.file_header -    } - -    #[inline] -    fn optional_header(&self) -> &Self::ImageOptionalHeader { -        &self.optional_header -    } -} - -impl ImageOptionalHeader for pe::ImageOptionalHeader64 { -    #[inline] -    fn magic(&self) -> u16 { -        self.magic.get(LE) -    } - -    #[inline] -    fn major_linker_version(&self) -> u8 { -        self.major_linker_version -    } - -    #[inline] -    fn minor_linker_version(&self) -> u8 { -        self.minor_linker_version -    } - -    #[inline] -    fn size_of_code(&self) -> u32 { -        self.size_of_code.get(LE) -    } - -    #[inline] -    fn size_of_initialized_data(&self) -> u32 { -        self.size_of_initialized_data.get(LE) -    } - -    #[inline] -    fn size_of_uninitialized_data(&self) -> u32 { -        self.size_of_uninitialized_data.get(LE) -    } - -    #[inline] -    fn address_of_entry_point(&self) -> u32 { -        self.address_of_entry_point.get(LE) -    } - -    #[inline] -    fn base_of_code(&self) -> u32 { -        self.base_of_code.get(LE) -    } - -    #[inline] -    fn base_of_data(&self) -> Option<u32> { -        None -    } - -    #[inline] -    fn image_base(&self) -> u64 { -        self.image_base.get(LE) -    } - -    #[inline] -    fn section_alignment(&self) -> u32 { -        self.section_alignment.get(LE) -    } - -    #[inline] -    fn file_alignment(&self) -> u32 { -        self.file_alignment.get(LE) -    } - -    #[inline] -    fn major_operating_system_version(&self) -> u16 { -        self.major_operating_system_version.get(LE) -    } - -    #[inline] -    fn minor_operating_system_version(&self) -> u16 { -        self.minor_operating_system_version.get(LE) -    } - -    #[inline] -    fn major_image_version(&self) -> u16 { -        self.major_image_version.get(LE) -    } - -    #[inline] -    fn minor_image_version(&self) -> u16 { -        self.minor_image_version.get(LE) -    } - -    #[inline] -    fn major_subsystem_version(&self) -> u16 { -        self.major_subsystem_version.get(LE) -    } - -    #[inline] -    fn minor_subsystem_version(&self) -> u16 { -        self.minor_subsystem_version.get(LE) -    } - -    #[inline] -    fn win32_version_value(&self) -> u32 { -        self.win32_version_value.get(LE) -    } - -    #[inline] -    fn size_of_image(&self) -> u32 { -        self.size_of_image.get(LE) -    } - -    #[inline] -    fn size_of_headers(&self) -> u32 { -        self.size_of_headers.get(LE) -    } - -    #[inline] -    fn check_sum(&self) -> u32 { -        self.check_sum.get(LE) -    } - -    #[inline] -    fn subsystem(&self) -> u16 { -        self.subsystem.get(LE) -    } - -    #[inline] -    fn dll_characteristics(&self) -> u16 { -        self.dll_characteristics.get(LE) -    } - -    #[inline] -    fn size_of_stack_reserve(&self) -> u64 { -        self.size_of_stack_reserve.get(LE) -    } - -    #[inline] -    fn size_of_stack_commit(&self) -> u64 { -        self.size_of_stack_commit.get(LE) -    } - -    #[inline] -    fn size_of_heap_reserve(&self) -> u64 { -        self.size_of_heap_reserve.get(LE) -    } - -    #[inline] -    fn size_of_heap_commit(&self) -> u64 { -        self.size_of_heap_commit.get(LE) -    } - -    #[inline] -    fn loader_flags(&self) -> u32 { -        self.loader_flags.get(LE) -    } - -    #[inline] -    fn number_of_rva_and_sizes(&self) -> u32 { -        self.number_of_rva_and_sizes.get(LE) -    } -} diff --git a/vendor/object/src/read/pe/import.rs b/vendor/object/src/read/pe/import.rs deleted file mode 100644 index 8e9a9a9..0000000 --- a/vendor/object/src/read/pe/import.rs +++ /dev/null @@ -1,337 +0,0 @@ -use core::fmt::Debug; -use core::mem; - -use crate::read::{Bytes, ReadError, Result}; -use crate::{pe, LittleEndian as LE, Pod, U16Bytes}; - -use super::ImageNtHeaders; - -/// Information for parsing a PE import table. -/// -/// Returned by [`DataDirectories::import_table`](super::DataDirectories::import_table). -#[derive(Debug, Clone)] -pub struct ImportTable<'data> { -    section_data: Bytes<'data>, -    section_address: u32, -    import_address: u32, -} - -impl<'data> ImportTable<'data> { -    /// Create a new import table parser. -    /// -    /// The import descriptors start at `import_address`. -    /// The size declared in the `IMAGE_DIRECTORY_ENTRY_IMPORT` data directory is -    /// ignored by the Windows loader, and so descriptors will be parsed until a null entry. -    /// -    /// `section_data` should be from the section containing `import_address`, and -    /// `section_address` should be the address of that section. Pointers within the -    /// descriptors and thunks may point to anywhere within the section data. -    pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self { -        ImportTable { -            section_data: Bytes(section_data), -            section_address, -            import_address, -        } -    } - -    /// Return an iterator for the import descriptors. -    pub fn descriptors(&self) -> Result<ImportDescriptorIterator<'data>> { -        let offset = self.import_address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import descriptor address")?; -        Ok(ImportDescriptorIterator { data }) -    } - -    /// Return a library name given its address. -    /// -    /// This address may be from [`pe::ImageImportDescriptor::name`]. -    pub fn name(&self, address: u32) -> Result<&'data [u8]> { -        self.section_data -            .read_string_at(address.wrapping_sub(self.section_address) as usize) -            .read_error("Invalid PE import descriptor name") -    } - -    /// Return a list of thunks given its address. -    /// -    /// This address may be from [`pe::ImageImportDescriptor::original_first_thunk`] -    /// or [`pe::ImageImportDescriptor::first_thunk`]. -    pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import thunk table address")?; -        Ok(ImportThunkList { data }) -    } - -    /// Parse a thunk. -    pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> { -        if thunk.is_ordinal() { -            Ok(Import::Ordinal(thunk.ordinal())) -        } else { -            let (hint, name) = self.hint_name(thunk.address())?; -            Ok(Import::Name(hint, name)) -        } -    } - -    /// Return the hint and name at the given address. -    /// -    /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`]. -    /// -    /// The hint is an index into the export name pointer table in the target library. -    pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE import thunk address")?; -        let hint = data -            .read::<U16Bytes<LE>>() -            .read_error("Missing PE import thunk hint")? -            .get(LE); -        let name = data -            .read_string() -            .read_error("Missing PE import thunk name")?; -        Ok((hint, name)) -    } -} - -/// A fallible iterator for the descriptors in the import data directory. -#[derive(Debug, Clone)] -pub struct ImportDescriptorIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> ImportDescriptorIterator<'data> { -    /// Return the next descriptor. -    /// -    /// Returns `Ok(None)` when a null descriptor is found. -    pub fn next(&mut self) -> Result<Option<&'data pe::ImageImportDescriptor>> { -        let import_desc = self -            .data -            .read::<pe::ImageImportDescriptor>() -            .read_error("Missing PE null import descriptor")?; -        if import_desc.is_null() { -            Ok(None) -        } else { -            Ok(Some(import_desc)) -        } -    } -} - -/// A list of import thunks. -/// -/// These may be in the import lookup table, or the import address table. -#[derive(Debug, Clone)] -pub struct ImportThunkList<'data> { -    data: Bytes<'data>, -} - -impl<'data> ImportThunkList<'data> { -    /// Get the thunk at the given index. -    pub fn get<Pe: ImageNtHeaders>(&self, index: usize) -> Result<Pe::ImageThunkData> { -        let thunk = self -            .data -            .read_at(index * mem::size_of::<Pe::ImageThunkData>()) -            .read_error("Invalid PE import thunk index")?; -        Ok(*thunk) -    } - -    /// Return the first thunk in the list, and update `self` to point after it. -    /// -    /// Returns `Ok(None)` when a null thunk is found. -    pub fn next<Pe: ImageNtHeaders>(&mut self) -> Result<Option<Pe::ImageThunkData>> { -        let thunk = self -            .data -            .read::<Pe::ImageThunkData>() -            .read_error("Missing PE null import thunk")?; -        if thunk.address() == 0 { -            Ok(None) -        } else { -            Ok(Some(*thunk)) -        } -    } -} - -/// A parsed import thunk. -#[derive(Debug, Clone, Copy)] -pub enum Import<'data> { -    /// Import by ordinal. -    Ordinal(u16), -    /// Import by name. -    /// -    /// Includes a hint for the index into the export name pointer table in the target library. -    Name(u16, &'data [u8]), -} - -/// A trait for generic access to [`pe::ImageThunkData32`] and [`pe::ImageThunkData64`]. -#[allow(missing_docs)] -pub trait ImageThunkData: Debug + Pod { -    /// Return the raw thunk value. -    fn raw(self) -> u64; - -    /// Returns true if the ordinal flag is set. -    fn is_ordinal(self) -> bool; - -    /// Return the ordinal portion of the thunk. -    /// -    /// Does not check the ordinal flag. -    fn ordinal(self) -> u16; - -    /// Return the RVA portion of the thunk. -    /// -    /// Does not check the ordinal flag. -    fn address(self) -> u32; -} - -impl ImageThunkData for pe::ImageThunkData64 { -    fn raw(self) -> u64 { -        self.0.get(LE) -    } - -    fn is_ordinal(self) -> bool { -        self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG64 != 0 -    } - -    fn ordinal(self) -> u16 { -        self.0.get(LE) as u16 -    } - -    fn address(self) -> u32 { -        self.0.get(LE) as u32 & 0x7fff_ffff -    } -} - -impl ImageThunkData for pe::ImageThunkData32 { -    fn raw(self) -> u64 { -        self.0.get(LE).into() -    } - -    fn is_ordinal(self) -> bool { -        self.0.get(LE) & pe::IMAGE_ORDINAL_FLAG32 != 0 -    } - -    fn ordinal(self) -> u16 { -        self.0.get(LE) as u16 -    } - -    fn address(self) -> u32 { -        self.0.get(LE) & 0x7fff_ffff -    } -} - -/// Information for parsing a PE delay-load import table. -/// -/// Returned by -/// [`DataDirectories::delay_load_import_table`](super::DataDirectories::delay_load_import_table). -#[derive(Debug, Clone)] -pub struct DelayLoadImportTable<'data> { -    section_data: Bytes<'data>, -    section_address: u32, -    import_address: u32, -} - -impl<'data> DelayLoadImportTable<'data> { -    /// Create a new delay load import table parser. -    /// -    /// The import descriptors start at `import_address`. -    /// This table works in the same way the import table does: descriptors will be -    /// parsed until a null entry. -    /// -    /// `section_data` should be from the section containing `import_address`, and -    /// `section_address` should be the address of that section. Pointers within the -    /// descriptors and thunks may point to anywhere within the section data. -    pub fn new(section_data: &'data [u8], section_address: u32, import_address: u32) -> Self { -        DelayLoadImportTable { -            section_data: Bytes(section_data), -            section_address, -            import_address, -        } -    } - -    /// Return an iterator for the import descriptors. -    pub fn descriptors(&self) -> Result<DelayLoadDescriptorIterator<'data>> { -        let offset = self.import_address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay-load import descriptor address")?; -        Ok(DelayLoadDescriptorIterator { data }) -    } - -    /// Return a library name given its address. -    /// -    /// This address may be from [`pe::ImageDelayloadDescriptor::dll_name_rva`]. -    pub fn name(&self, address: u32) -> Result<&'data [u8]> { -        self.section_data -            .read_string_at(address.wrapping_sub(self.section_address) as usize) -            .read_error("Invalid PE import descriptor name") -    } - -    /// Return a list of thunks given its address. -    /// -    /// This address may be from the INT, i.e. from -    /// [`pe::ImageDelayloadDescriptor::import_name_table_rva`]. -    /// -    /// Please note that others RVA values from [`pe::ImageDelayloadDescriptor`] are used -    /// by the delay loader at runtime to store values, and thus do not point inside the same -    /// section as the INT. Calling this function on those addresses will fail. -    pub fn thunks(&self, address: u32) -> Result<ImportThunkList<'data>> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay load import thunk table address")?; -        Ok(ImportThunkList { data }) -    } - -    /// Parse a thunk. -    pub fn import<Pe: ImageNtHeaders>(&self, thunk: Pe::ImageThunkData) -> Result<Import<'data>> { -        if thunk.is_ordinal() { -            Ok(Import::Ordinal(thunk.ordinal())) -        } else { -            let (hint, name) = self.hint_name(thunk.address())?; -            Ok(Import::Name(hint, name)) -        } -    } - -    /// Return the hint and name at the given address. -    /// -    /// This address may be from [`pe::ImageThunkData32`] or [`pe::ImageThunkData64`]. -    /// -    /// The hint is an index into the export name pointer table in the target library. -    pub fn hint_name(&self, address: u32) -> Result<(u16, &'data [u8])> { -        let offset = address.wrapping_sub(self.section_address); -        let mut data = self.section_data; -        data.skip(offset as usize) -            .read_error("Invalid PE delay load import thunk address")?; -        let hint = data -            .read::<U16Bytes<LE>>() -            .read_error("Missing PE delay load import thunk hint")? -            .get(LE); -        let name = data -            .read_string() -            .read_error("Missing PE delay load import thunk name")?; -        Ok((hint, name)) -    } -} - -/// A fallible iterator for the descriptors in the delay-load data directory. -#[derive(Debug, Clone)] -pub struct DelayLoadDescriptorIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> DelayLoadDescriptorIterator<'data> { -    /// Return the next descriptor. -    /// -    /// Returns `Ok(None)` when a null descriptor is found. -    pub fn next(&mut self) -> Result<Option<&'data pe::ImageDelayloadDescriptor>> { -        let import_desc = self -            .data -            .read::<pe::ImageDelayloadDescriptor>() -            .read_error("Missing PE null delay-load import descriptor")?; -        if import_desc.is_null() { -            Ok(None) -        } else { -            Ok(Some(import_desc)) -        } -    } -} diff --git a/vendor/object/src/read/pe/mod.rs b/vendor/object/src/read/pe/mod.rs deleted file mode 100644 index ab6011c..0000000 --- a/vendor/object/src/read/pe/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Support for reading PE files. -//! -//! Traits are used to abstract over the difference between PE32 and PE32+. -//! The primary trait for this is [`ImageNtHeaders`]. -//! -//! ## High level API -//! -//! [`PeFile`] implements the [`Object`](crate::read::Object) trait for -//! PE files. [`PeFile`] is parameterised by [`ImageNtHeaders`] to allow -//! reading both PE32 and PE32+. There are type aliases for these parameters -//! ([`PeFile32`] and [`PeFile64`]). -//! -//! ## Low level API -//! -//! The [`ImageNtHeaders`] trait can be directly used to parse both -//! [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. -//! -//! ### Example for low level API -//!  ```no_run -//! use object::pe; -//! use object::read::pe::ImageNtHeaders; -//! use std::error::Error; -//! use std::fs; -//! -//! /// Reads a file and displays the name of each section. -//! fn main() -> Result<(), Box<dyn Error>> { -//! #   #[cfg(feature = "std")] { -//!     let data = fs::read("path/to/binary")?; -//!     let dos_header = pe::ImageDosHeader::parse(&*data)?; -//!     let mut offset = dos_header.nt_headers_offset().into(); -//!     let (nt_headers, data_directories) = pe::ImageNtHeaders64::parse(&*data, &mut offset)?; -//!     let sections = nt_headers.sections(&*data, offset)?; -//!     let symbols = nt_headers.symbols(&*data)?; -//!     for section in sections.iter() { -//!         println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?)); -//!     } -//! #   } -//!     Ok(()) -//! } -//! ``` -#[cfg(doc)] -use crate::pe; - -mod file; -pub use file::*; - -mod section; -pub use section::*; - -mod data_directory; -pub use data_directory::*; - -mod export; -pub use export::*; - -mod import; -pub use import::*; - -mod relocation; -pub use relocation::*; - -mod resource; -pub use resource::*; - -mod rich; -pub use rich::*; - -pub use super::coff::{SectionTable, SymbolTable}; diff --git a/vendor/object/src/read/pe/relocation.rs b/vendor/object/src/read/pe/relocation.rs deleted file mode 100644 index 77421b7..0000000 --- a/vendor/object/src/read/pe/relocation.rs +++ /dev/null @@ -1,92 +0,0 @@ -use core::slice; - -use crate::endian::{LittleEndian as LE, U16}; -use crate::pe; -use crate::read::{Bytes, Error, ReadError, Result}; - -/// An iterator over the relocation blocks in the `.reloc` section of a PE file. -/// -/// Returned by [`DataDirectories::relocation_blocks`](super::DataDirectories::relocation_blocks). -#[derive(Debug, Default, Clone, Copy)] -pub struct RelocationBlockIterator<'data> { -    data: Bytes<'data>, -} - -impl<'data> RelocationBlockIterator<'data> { -    /// Construct a new iterator from the data of the `.reloc` section. -    pub fn new(data: &'data [u8]) -> Self { -        RelocationBlockIterator { data: Bytes(data) } -    } - -    /// Read the next relocation page. -    pub fn next(&mut self) -> Result<Option<RelocationIterator<'data>>> { -        if self.data.is_empty() { -            return Ok(None); -        } -        let header = self -            .data -            .read::<pe::ImageBaseRelocation>() -            .read_error("Invalid PE reloc section size")?; -        let virtual_address = header.virtual_address.get(LE); -        let size = header.size_of_block.get(LE); -        if size <= 8 || size & 3 != 0 { -            return Err(Error("Invalid PE reloc block size")); -        } -        let count = (size - 8) / 2; -        let relocs = self -            .data -            .read_slice::<U16<LE>>(count as usize) -            .read_error("Invalid PE reloc block size")? -            .iter(); -        Ok(Some(RelocationIterator { -            virtual_address, -            size, -            relocs, -        })) -    } -} - -/// An iterator of the relocations in a block in the `.reloc` section of a PE file. -#[derive(Debug, Clone)] -pub struct RelocationIterator<'data> { -    virtual_address: u32, -    size: u32, -    relocs: slice::Iter<'data, U16<LE>>, -} - -impl<'data> RelocationIterator<'data> { -    /// Return the virtual address of the page that this block of relocations applies to. -    pub fn virtual_address(&self) -> u32 { -        self.virtual_address -    } - -    /// Return the size in bytes of this block of relocations. -    pub fn size(&self) -> u32 { -        self.size -    } -} - -impl<'data> Iterator for RelocationIterator<'data> { -    type Item = Relocation; - -    fn next(&mut self) -> Option<Relocation> { -        loop { -            let reloc = self.relocs.next()?.get(LE); -            if reloc != 0 { -                return Some(Relocation { -                    virtual_address: self.virtual_address.wrapping_add((reloc & 0xfff) as u32), -                    typ: reloc >> 12, -                }); -            } -        } -    } -} - -/// A relocation in the `.reloc` section of a PE file. -#[derive(Debug, Default, Clone, Copy)] -pub struct Relocation { -    /// The virtual address of the relocation. -    pub virtual_address: u32, -    /// One of the `pe::IMAGE_REL_BASED_*` constants. -    pub typ: u16, -} diff --git a/vendor/object/src/read/pe/resource.rs b/vendor/object/src/read/pe/resource.rs deleted file mode 100644 index 331da3f..0000000 --- a/vendor/object/src/read/pe/resource.rs +++ /dev/null @@ -1,209 +0,0 @@ -use alloc::string::String; -use core::char; - -use crate::read::{ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE, U16Bytes}; - -/// The `.rsrc` section of a PE file. -/// -/// Returned by [`DataDirectories::resource_directory`](super::DataDirectories::resource_directory). -#[derive(Debug, Clone, Copy)] -pub struct ResourceDirectory<'data> { -    data: &'data [u8], -} - -impl<'data> ResourceDirectory<'data> { -    /// Construct from the data of the `.rsrc` section. -    pub fn new(data: &'data [u8]) -> Self { -        ResourceDirectory { data } -    } - -    /// Parses the root resource directory. -    pub fn root(&self) -> Result<ResourceDirectoryTable<'data>> { -        ResourceDirectoryTable::parse(self.data, 0) -    } -} - -/// A table of resource entries. -#[derive(Debug, Clone)] -pub struct ResourceDirectoryTable<'data> { -    /// The table header. -    pub header: &'data pe::ImageResourceDirectory, -    /// The table entries. -    pub entries: &'data [pe::ImageResourceDirectoryEntry], -} - -impl<'data> ResourceDirectoryTable<'data> { -    fn parse(data: &'data [u8], offset: u32) -> Result<Self> { -        let mut offset = u64::from(offset); -        let header = data -            .read::<pe::ImageResourceDirectory>(&mut offset) -            .read_error("Invalid resource table header")?; -        let entries_count = header.number_of_id_entries.get(LE) as usize -            + header.number_of_named_entries.get(LE) as usize; -        let entries = data -            .read_slice::<pe::ImageResourceDirectoryEntry>(&mut offset, entries_count) -            .read_error("Invalid resource table entries")?; -        Ok(Self { header, entries }) -    } -} - -impl pe::ImageResourceDirectoryEntry { -    /// Returns true if the entry has a name, rather than an ID. -    pub fn has_name(&self) -> bool { -        self.name_or_id.get(LE) & pe::IMAGE_RESOURCE_NAME_IS_STRING != 0 -    } - -    /// Returns the section offset of the name. -    /// -    /// Valid if `has_name()` returns true. -    fn name(&self) -> ResourceName { -        let offset = self.name_or_id.get(LE) & !pe::IMAGE_RESOURCE_NAME_IS_STRING; -        ResourceName { offset } -    } - -    /// Returns the ID. -    /// -    /// Valid if `has_string_name()` returns false. -    fn id(&self) -> u16 { -        (self.name_or_id.get(LE) & 0x0000_FFFF) as u16 -    } - -    /// Returns the entry name -    pub fn name_or_id(&self) -> ResourceNameOrId { -        if self.has_name() { -            ResourceNameOrId::Name(self.name()) -        } else { -            ResourceNameOrId::Id(self.id()) -        } -    } - -    /// Returns true if the entry is a subtable. -    pub fn is_table(&self) -> bool { -        self.offset_to_data_or_directory.get(LE) & pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY != 0 -    } - -    /// Returns the section offset of the associated table or data. -    pub fn data_offset(&self) -> u32 { -        self.offset_to_data_or_directory.get(LE) & !pe::IMAGE_RESOURCE_DATA_IS_DIRECTORY -    } - -    /// Returns the data associated to this directory entry. -    pub fn data<'data>( -        &self, -        section: ResourceDirectory<'data>, -    ) -> Result<ResourceDirectoryEntryData<'data>> { -        if self.is_table() { -            ResourceDirectoryTable::parse(section.data, self.data_offset()) -                .map(ResourceDirectoryEntryData::Table) -        } else { -            section -                .data -                .read_at::<pe::ImageResourceDataEntry>(self.data_offset().into()) -                .read_error("Invalid resource entry") -                .map(ResourceDirectoryEntryData::Data) -        } -    } -} - -/// Data associated with a resource directory entry. -#[derive(Debug, Clone)] -pub enum ResourceDirectoryEntryData<'data> { -    /// A subtable entry. -    Table(ResourceDirectoryTable<'data>), -    /// A resource data entry. -    Data(&'data pe::ImageResourceDataEntry), -} - -impl<'data> ResourceDirectoryEntryData<'data> { -    /// Converts to an option of table. -    /// -    /// Helper for iterator filtering. -    pub fn table(self) -> Option<ResourceDirectoryTable<'data>> { -        match self { -            Self::Table(dir) => Some(dir), -            _ => None, -        } -    } - -    /// Converts to an option of data entry. -    /// -    /// Helper for iterator filtering. -    pub fn data(self) -> Option<&'data pe::ImageResourceDataEntry> { -        match self { -            Self::Data(rsc) => Some(rsc), -            _ => None, -        } -    } -} - -/// A resource name. -#[derive(Debug, Clone, Copy)] -pub struct ResourceName { -    offset: u32, -} - -impl ResourceName { -    /// Converts to a `String`. -    pub fn to_string_lossy(&self, directory: ResourceDirectory<'_>) -> Result<String> { -        let d = self.data(directory)?.iter().map(|c| c.get(LE)); - -        Ok(char::decode_utf16(d) -            .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER)) -            .collect::<String>()) -    } - -    /// Returns the string unicode buffer. -    pub fn data<'data>( -        &self, -        directory: ResourceDirectory<'data>, -    ) -> Result<&'data [U16Bytes<LE>]> { -        let mut offset = u64::from(self.offset); -        let len = directory -            .data -            .read::<U16Bytes<LE>>(&mut offset) -            .read_error("Invalid resource name offset")?; -        directory -            .data -            .read_slice::<U16Bytes<LE>>(&mut offset, len.get(LE).into()) -            .read_error("Invalid resource name length") -    } - -    /// Returns the string buffer as raw bytes. -    pub fn raw_data<'data>(&self, directory: ResourceDirectory<'data>) -> Result<&'data [u8]> { -        self.data(directory).map(crate::pod::bytes_of_slice) -    } -} - -/// A resource name or ID. -/// -/// Can be either a string or a numeric ID. -#[derive(Debug)] -pub enum ResourceNameOrId { -    /// A resource name. -    Name(ResourceName), -    /// A resource ID. -    Id(u16), -} - -impl ResourceNameOrId { -    /// Converts to an option of name. -    /// -    /// Helper for iterator filtering. -    pub fn name(self) -> Option<ResourceName> { -        match self { -            Self::Name(name) => Some(name), -            _ => None, -        } -    } - -    /// Converts to an option of ID. -    /// -    /// Helper for iterator filtering. -    pub fn id(self) -> Option<u16> { -        match self { -            Self::Id(id) => Some(id), -            _ => None, -        } -    } -} diff --git a/vendor/object/src/read/pe/rich.rs b/vendor/object/src/read/pe/rich.rs deleted file mode 100644 index 33dd039..0000000 --- a/vendor/object/src/read/pe/rich.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! PE rich header handling - -use core::mem; - -use crate::pod::bytes_of_slice; -use crate::read::Bytes; -use crate::{pe, LittleEndian as LE, ReadRef, U32}; - -/// Parsed information about a Rich Header. -#[derive(Debug, Clone, Copy)] -pub struct RichHeaderInfo<'data> { -    /// The offset at which the rich header starts. -    pub offset: usize, -    /// The length (in bytes) of the rich header. -    /// -    /// This includes the payload, but also the 16-byte start sequence and the -    /// 8-byte final "Rich" and XOR key. -    pub length: usize, -    /// The XOR key used to mask the rich header. -    /// -    /// Unless the file has been tampered with, it should be equal to a checksum -    /// of the file header. -    pub xor_key: u32, -    masked_entries: &'data [pe::MaskedRichHeaderEntry], -} - -/// A PE rich header entry after it has been unmasked. -/// -/// See [`pe::MaskedRichHeaderEntry`]. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct RichHeaderEntry { -    /// ID of the component. -    pub comp_id: u32, -    /// Number of times this component has been used when building this PE. -    pub count: u32, -} - -impl<'data> RichHeaderInfo<'data> { -    /// Try to locate a rich header and its entries in the current PE file. -    pub fn parse<R: ReadRef<'data>>(data: R, nt_header_offset: u64) -> Option<Self> { -        // Locate the rich header, if any. -        // It ends with the "Rich" string and an XOR key, before the NT header. -        let data = data.read_bytes_at(0, nt_header_offset).map(Bytes).ok()?; -        let end_marker_offset = memmem(data.0, b"Rich", 4)?; -        let xor_key = *data.read_at::<U32<LE>>(end_marker_offset + 4).ok()?; - -        // It starts at the masked "DanS" string and 3 masked zeroes. -        let masked_start_marker = U32::new(LE, 0x536e_6144 ^ xor_key.get(LE)); -        let start_header = [masked_start_marker, xor_key, xor_key, xor_key]; -        let start_sequence = bytes_of_slice(&start_header); -        let start_marker_offset = memmem(&data.0[..end_marker_offset], start_sequence, 4)?; - -        // Extract the items between the markers. -        let items_offset = start_marker_offset + start_sequence.len(); -        let items_len = end_marker_offset - items_offset; -        let item_count = items_len / mem::size_of::<pe::MaskedRichHeaderEntry>(); -        let items = data.read_slice_at(items_offset, item_count).ok()?; -        Some(RichHeaderInfo { -            offset: start_marker_offset, -            // Includes "Rich" marker and the XOR key. -            length: end_marker_offset - start_marker_offset + 8, -            xor_key: xor_key.get(LE), -            masked_entries: items, -        }) -    } - -    /// Returns an iterator over the unmasked entries. -    pub fn unmasked_entries(&self) -> impl Iterator<Item = RichHeaderEntry> + 'data { -        let xor_key = self.xor_key; -        self.masked_entries -            .iter() -            .map(move |entry| RichHeaderEntry { -                comp_id: entry.masked_comp_id.get(LE) ^ xor_key, -                count: entry.masked_count.get(LE) ^ xor_key, -            }) -    } -} - -/// Find the offset of the first occurrence of needle in the data. -/// -/// The offset must have the given alignment. -fn memmem(data: &[u8], needle: &[u8], align: usize) -> Option<usize> { -    let mut offset = 0; -    loop { -        if data.get(offset..)?.get(..needle.len())? == needle { -            return Some(offset); -        } -        offset += align; -    } -} diff --git a/vendor/object/src/read/pe/section.rs b/vendor/object/src/read/pe/section.rs deleted file mode 100644 index 74c9d7f..0000000 --- a/vendor/object/src/read/pe/section.rs +++ /dev/null @@ -1,440 +0,0 @@ -use core::marker::PhantomData; -use core::{cmp, iter, slice, str}; - -use crate::endian::LittleEndian as LE; -use crate::pe; -use crate::pe::ImageSectionHeader; -use crate::read::{ -    self, CompressedData, CompressedFileRange, ObjectSection, ObjectSegment, ReadError, ReadRef, -    Relocation, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, -}; - -use super::{ImageNtHeaders, PeFile, SectionTable}; - -/// An iterator for the loadable sections in a [`PeFile32`](super::PeFile32). -pub type PeSegmentIterator32<'data, 'file, R = &'data [u8]> = -    PeSegmentIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the loadable sections in a [`PeFile64`](super::PeFile64). -pub type PeSegmentIterator64<'data, 'file, R = &'data [u8]> = -    PeSegmentIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the loadable sections in a [`PeFile`]. -#[derive(Debug)] -pub struct PeSegmentIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) iter: slice::Iter<'data, pe::ImageSectionHeader>, -} - -impl<'data, 'file, Pe, R> Iterator for PeSegmentIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeSegment<'data, 'file, Pe, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|section| PeSegment { -            file: self.file, -            section, -        }) -    } -} - -/// A loadable section in a [`PeFile32`](super::PeFile32). -pub type PeSegment32<'data, 'file, R = &'data [u8]> = -    PeSegment<'data, 'file, pe::ImageNtHeaders32, R>; -/// A loadable section in a [`PeFile64`](super::PeFile64). -pub type PeSegment64<'data, 'file, R = &'data [u8]> = -    PeSegment<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A loadable section in a [`PeFile`]. -/// -/// Most functionality is provided by the [`ObjectSegment`] trait implementation. -#[derive(Debug)] -pub struct PeSegment<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    file: &'file PeFile<'data, Pe, R>, -    section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeSegment<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectSegment<'data> for PeSegment<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base) -    } - -    #[inline] -    fn size(&self) -> u64 { -        u64::from(self.section.virtual_size.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.file.section_alignment() -    } - -    #[inline] -    fn file_range(&self) -> (u64, u64) { -        let (offset, size) = self.section.pe_file_range(); -        (u64::from(offset), u64::from(size)) -    } - -    fn data(&self) -> Result<&'data [u8]> { -        self.section.pe_data(self.file.data) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.data()?, -            self.address(), -            address, -            size, -        )) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<Option<&[u8]>> { -        self.section -            .name(self.file.common.symbols.strings()) -            .map(Some) -    } - -    #[inline] -    fn name(&self) -> Result<Option<&str>> { -        let name = self.section.name(self.file.common.symbols.strings())?; -        Ok(Some( -            str::from_utf8(name) -                .ok() -                .read_error("Non UTF-8 PE section name")?, -        )) -    } - -    #[inline] -    fn flags(&self) -> SegmentFlags { -        let characteristics = self.section.characteristics.get(LE); -        SegmentFlags::Coff { characteristics } -    } -} - -/// An iterator for the sections in a [`PeFile32`](super::PeFile32). -pub type PeSectionIterator32<'data, 'file, R = &'data [u8]> = -    PeSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator for the sections in a [`PeFile64`](super::PeFile64). -pub type PeSectionIterator64<'data, 'file, R = &'data [u8]> = -    PeSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; - -/// An iterator for the sections in a [`PeFile`]. -#[derive(Debug)] -pub struct PeSectionIterator<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) iter: iter::Enumerate<slice::Iter<'data, pe::ImageSectionHeader>>, -} - -impl<'data, 'file, Pe, R> Iterator for PeSectionIterator<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type Item = PeSection<'data, 'file, Pe, R>; - -    fn next(&mut self) -> Option<Self::Item> { -        self.iter.next().map(|(index, section)| PeSection { -            file: self.file, -            index: SectionIndex(index + 1), -            section, -        }) -    } -} - -/// A section in a [`PeFile32`](super::PeFile32). -pub type PeSection32<'data, 'file, R = &'data [u8]> = -    PeSection<'data, 'file, pe::ImageNtHeaders32, R>; -/// A section in a [`PeFile64`](super::PeFile64). -pub type PeSection64<'data, 'file, R = &'data [u8]> = -    PeSection<'data, 'file, pe::ImageNtHeaders64, R>; - -/// A section in a [`PeFile`]. -/// -/// Most functionality is provided by the [`ObjectSection`] trait implementation. -#[derive(Debug)] -pub struct PeSection<'data, 'file, Pe, R = &'data [u8]> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    pub(super) file: &'file PeFile<'data, Pe, R>, -    pub(super) index: SectionIndex, -    pub(super) section: &'data pe::ImageSectionHeader, -} - -impl<'data, 'file, Pe, R> read::private::Sealed for PeSection<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -} - -impl<'data, 'file, Pe, R> ObjectSection<'data> for PeSection<'data, 'file, Pe, R> -where -    Pe: ImageNtHeaders, -    R: ReadRef<'data>, -{ -    type RelocationIterator = PeRelocationIterator<'data, 'file, R>; - -    #[inline] -    fn index(&self) -> SectionIndex { -        self.index -    } - -    #[inline] -    fn address(&self) -> u64 { -        u64::from(self.section.virtual_address.get(LE)).wrapping_add(self.file.common.image_base) -    } - -    #[inline] -    fn size(&self) -> u64 { -        u64::from(self.section.virtual_size.get(LE)) -    } - -    #[inline] -    fn align(&self) -> u64 { -        self.file.section_alignment() -    } - -    #[inline] -    fn file_range(&self) -> Option<(u64, u64)> { -        let (offset, size) = self.section.pe_file_range(); -        if size == 0 { -            None -        } else { -            Some((u64::from(offset), u64::from(size))) -        } -    } - -    fn data(&self) -> Result<&'data [u8]> { -        self.section.pe_data(self.file.data) -    } - -    fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> { -        Ok(read::util::data_range( -            self.data()?, -            self.address(), -            address, -            size, -        )) -    } - -    #[inline] -    fn compressed_file_range(&self) -> Result<CompressedFileRange> { -        Ok(CompressedFileRange::none(self.file_range())) -    } - -    #[inline] -    fn compressed_data(&self) -> Result<CompressedData<'data>> { -        self.data().map(CompressedData::none) -    } - -    #[inline] -    fn name_bytes(&self) -> Result<&[u8]> { -        self.section.name(self.file.common.symbols.strings()) -    } - -    #[inline] -    fn name(&self) -> Result<&str> { -        let name = self.name_bytes()?; -        str::from_utf8(name) -            .ok() -            .read_error("Non UTF-8 PE section name") -    } - -    #[inline] -    fn segment_name_bytes(&self) -> Result<Option<&[u8]>> { -        Ok(None) -    } - -    #[inline] -    fn segment_name(&self) -> Result<Option<&str>> { -        Ok(None) -    } - -    #[inline] -    fn kind(&self) -> SectionKind { -        self.section.kind() -    } - -    fn relocations(&self) -> PeRelocationIterator<'data, 'file, R> { -        PeRelocationIterator(PhantomData) -    } - -    fn flags(&self) -> SectionFlags { -        SectionFlags::Coff { -            characteristics: self.section.characteristics.get(LE), -        } -    } -} - -impl<'data> SectionTable<'data> { -    /// Return the file offset of the given virtual address, and the size up -    /// to the end of the section containing it. -    /// -    /// Returns `None` if no section contains the address. -    pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> { -        self.iter().find_map(|section| section.pe_file_range_at(va)) -    } - -    /// Return the data starting at the given virtual address, up to the end of the -    /// section containing it. -    /// -    /// Ignores sections with invalid data. -    /// -    /// Returns `None` if no section contains the address. -    pub fn pe_data_at<R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> { -        self.iter().find_map(|section| section.pe_data_at(data, va)) -    } - -    /// Return the data of the section that contains the given virtual address in a PE file. -    /// -    /// Also returns the virtual address of that section. -    /// -    /// Ignores sections with invalid data. -    pub fn pe_data_containing<R: ReadRef<'data>>( -        &self, -        data: R, -        va: u32, -    ) -> Option<(&'data [u8], u32)> { -        self.iter() -            .find_map(|section| section.pe_data_containing(data, va)) -    } - -    /// Return the section that contains a given virtual address. -    pub fn section_containing(&self, va: u32) -> Option<&'data ImageSectionHeader> { -        self.iter().find(|section| section.contains_rva(va)) -    } -} - -impl pe::ImageSectionHeader { -    /// Return the offset and size of the section in a PE file. -    /// -    /// The size of the range will be the minimum of the file size and virtual size. -    pub fn pe_file_range(&self) -> (u32, u32) { -        // Pointer and size will be zero for uninitialized data; we don't need to validate this. -        let offset = self.pointer_to_raw_data.get(LE); -        let size = cmp::min(self.virtual_size.get(LE), self.size_of_raw_data.get(LE)); -        (offset, size) -    } - -    /// Return the file offset of the given virtual address, and the remaining size up -    /// to the end of the section. -    /// -    /// Returns `None` if the section does not contain the address. -    pub fn pe_file_range_at(&self, va: u32) -> Option<(u32, u32)> { -        let section_va = self.virtual_address.get(LE); -        let offset = va.checked_sub(section_va)?; -        let (section_offset, section_size) = self.pe_file_range(); -        // Address must be within section (and not at its end). -        if offset < section_size { -            Some((section_offset.checked_add(offset)?, section_size - offset)) -        } else { -            None -        } -    } - -    /// Return the virtual address and size of the section. -    pub fn pe_address_range(&self) -> (u32, u32) { -        (self.virtual_address.get(LE), self.virtual_size.get(LE)) -    } - -    /// Return the section data in a PE file. -    /// -    /// The length of the data will be the minimum of the file size and virtual size. -    pub fn pe_data<'data, R: ReadRef<'data>>(&self, data: R) -> Result<&'data [u8]> { -        let (offset, size) = self.pe_file_range(); -        data.read_bytes_at(offset.into(), size.into()) -            .read_error("Invalid PE section offset or size") -    } - -    /// Return the data starting at the given virtual address, up to the end of the -    /// section. -    /// -    /// Ignores sections with invalid data. -    /// -    /// Returns `None` if the section does not contain the address. -    pub fn pe_data_at<'data, R: ReadRef<'data>>(&self, data: R, va: u32) -> Option<&'data [u8]> { -        let (offset, size) = self.pe_file_range_at(va)?; -        data.read_bytes_at(offset.into(), size.into()).ok() -    } - -    /// Tests whether a given RVA is part of this section -    pub fn contains_rva(&self, va: u32) -> bool { -        let section_va = self.virtual_address.get(LE); -        match va.checked_sub(section_va) { -            None => false, -            Some(offset) => { -                // Address must be within section (and not at its end). -                offset < self.virtual_size.get(LE) -            } -        } -    } - -    /// Return the section data if it contains the given virtual address. -    /// -    /// Also returns the virtual address of that section. -    /// -    /// Ignores sections with invalid data. -    pub fn pe_data_containing<'data, R: ReadRef<'data>>( -        &self, -        data: R, -        va: u32, -    ) -> Option<(&'data [u8], u32)> { -        let section_va = self.virtual_address.get(LE); -        let offset = va.checked_sub(section_va)?; -        let (section_offset, section_size) = self.pe_file_range(); -        // Address must be within section (and not at its end). -        if offset < section_size { -            let section_data = data -                .read_bytes_at(section_offset.into(), section_size.into()) -                .ok()?; -            Some((section_data, section_va)) -        } else { -            None -        } -    } -} - -/// An iterator for the relocations in an [`PeSection`]. -/// -/// This is a stub that doesn't implement any functionality. -#[derive(Debug)] -pub struct PeRelocationIterator<'data, 'file, R = &'data [u8]>( -    PhantomData<(&'data (), &'file (), R)>, -); - -impl<'data, 'file, R> Iterator for PeRelocationIterator<'data, 'file, R> { -    type Item = (u64, Relocation); - -    fn next(&mut self) -> Option<Self::Item> { -        None -    } -}  | 
