/// An iterator for the loadable sections in a [`PeFile32`](super::PeFile32). pubtype PeSegmentIterator32<'data, 'file, R = &'data [u8]> =
PeSegmentIterator<'data, 'file, pe::ImageNtHeaders32, R>; /// An iterator for the loadable sections in a [`PeFile64`](super::PeFile64). pubtype PeSegmentIterator64<'data, 'file, R = &'data [u8]> =
PeSegmentIterator<'data, 'file, pe::ImageNtHeaders64, R>;
/// An iterator for the loadable sections in a [`PeFile`]. #[derive(Debug)] pubstruct 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>;
/// A loadable section in a [`PeFile32`](super::PeFile32). pubtype PeSegment32<'data, 'file, R = &'data [u8]> =
PeSegment<'data, 'file, pe::ImageNtHeaders32, R>; /// A loadable section in a [`PeFile64`](super::PeFile64). pubtype 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)] pubstruct 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> PeSegment<'data, 'file, Pe, R> where
Pe: ImageNtHeaders,
R: ReadRef<'data>,
{ /// Get the PE file containing this segment. pubfn pe_file(&self) -> &'file PeFile<'data, Pe, R> { self.file
}
/// Get the raw PE section header. pubfn pe_section(&self) -> &'data pe::ImageSectionHeader { self.section
}
}
impl<'data, 'file, Pe, R> read::private::Sealed for PeSegment<'data, 'file, Pe, R> where
Pe: ImageNtHeaders,
R: ReadRef<'data>,
{
}
/// An iterator for the sections in a [`PeFile32`](super::PeFile32). pubtype PeSectionIterator32<'data, 'file, R = &'data [u8]> =
PeSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; /// An iterator for the sections in a [`PeFile64`](super::PeFile64). pubtype PeSectionIterator64<'data, 'file, R = &'data [u8]> =
PeSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>;
/// An iterator for the sections in a [`PeFile`]. #[derive(Debug)] pubstruct 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>;
/// A section in a [`PeFile32`](super::PeFile32). pubtype PeSection32<'data, 'file, R = &'data [u8]> =
PeSection<'data, 'file, pe::ImageNtHeaders32, R>; /// A section in a [`PeFile64`](super::PeFile64). pubtype 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)] pubstruct 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> PeSection<'data, 'file, Pe, R> where
Pe: ImageNtHeaders,
R: ReadRef<'data>,
{ /// Get the PE file containing this segment. pubfn pe_file(&self) -> &'file PeFile<'data, Pe, R> { self.file
}
/// Get the raw PE section header. pubfn pe_section(&self) -> &'data pe::ImageSectionHeader { self.section
}
}
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>;
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. pubfn 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. pubfn 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. pubfn 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. pubfn 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. pubfn 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. pubfn 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. pubfn 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. pubfn pe_data<'data, R: ReadRef<'data>>(&self, data: R) -> Result<&style='color:blue'>'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. pubfn 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 pubfn 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. pubfn 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)] pubstruct PeRelocationIterator<'data, 'file, R = &'data [u8]>(
PhantomData<(&'data (), &'file (), R)>,
);
impl<'data, 'file, R> Iterator for PeRelocationIterator<'data, 'file, R> { type Item = (u64, Relocation);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.