aboutsummaryrefslogtreecommitdiff
path: root/vendor/object/src/read/pe/data_directory.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/read/pe/data_directory.rs')
-rw-r--r--vendor/object/src/read/pe/data_directory.rs213
1 files changed, 0 insertions, 213 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")
- }
-}